Exception Information Provided by OS/2

When an exception occurs, OS/2 provides data in structures that are arguments to the exception handler.

_EXCEPTIONREPORTRECORD
This structure is defined in IBMCXXO\os2\bsexcpt.h as follows:

struct _EXCEPTIONREPORTRECORD
{
   ULONG ExceptionNum;
   ULONG fHandlerFlags;
   struct _EXCEPTIONREPORTRECORD *NestedERR;
   PVOID ExceptionAddress;
   ULONG cParameters;
   ULONG ExceptionInfo[EXCEPTION_MAXIMUM_PARAMETERS];
};

The fields in _EXCEPTIONREPORTRECORD provide the following information:

ExceptionNum
The exception number. You can encounter the exceptions in the table below only by using an OS/2 exception handler. This is because the IBM C and C++ Compilers default handler passes them to the operating system to handle.

Exception Description
XCPT_PROCESS_TERMINATE Indicates that the current thread has called DosExit, and the process is about to end. Until your exception handler ends, the thread continues as though DosExit had not been called.
XCPT_ASYNC_PROCESS_TERMINATE Indicates that some other thread in the process has called DosExit and that your current thread is about to end also. You can decide to continue running the current thread and return the exception as handled.
XCPT_ACCESS_VIOLATION Indicates an invalid attempt was made to access memory (similar to the SIGSEGV signal). When this exception occurs, the ExceptionInfo field provides the address that generated the exception and the type of access that was attempted (read or write).
XCPT_GUARD_PAGE_VIOLATION Indicates that the current thread tried to access a memory page marked as a guard page. Usually it means that your application has accessed a guard page on the stack.
In most cases, you will probably pass the exception to the operating system, which will allocate another 4K of committed memory for your thread and a new guard page.
The operating system requires about 1.5K to place the information about the exception on the stack and then call the exception handler. If you know you are running out of stack space, you may want to end your process.
XCPT_UNABLE_TO_GROW_STACK Indicates that the operating system tried to move your guard page, but no memory remained on the stack.
If you suppressed stack probe generation by building with /Gs-, there may not be enough stack for you to even receive the exception, in which case your process terminates with an operating system trap.
A user-defined exception You can also use the OS/2 API DosRaiseException to create and raise your own exceptions that you can then handle with your own exception handler.

fHandlerFlags
How the exception occurred and what you can do to handle it. It includes the following bits:

Bit Description
EH_NONCONTINUABLE You cannot continue running the thread once you leave the exception handler. If you try to return XCPT_CONTINUE_EXECUTION, an error is generated. You cannot reset the bit. However, you can intentionally set the bit to make an exception noncontinuable.
EH_UNWINDING A longjmp has been done over this exception handler and the handler is to be deregistered. If your function uses a mutex semaphore, you should release it when you receive this exception.
EH_EXIT_UNWIND A DosExit call has been made and the exception has been passed back to the operating system. This exception gives you an opportunity to take action before your exception handler is deregistered.
EH_NESTED_CALL An exception occurred while another exception was being handled. This situation should be handled carefully: each exception requires about 1.5K of stack, so if you nest exceptions too deep you could run out of stack .

_EXCEPTIONREPORTRECORD *NestedERR
If a nested exception occurs, the information about the exception is found in this structure.

ExceptionAddress
This field contains the instruction address where the exception occurred. Typically, you cannot determine at run time which function caused the problem.

cParameters
This field contains the number of bytes of information.

ExceptionInfo
For some exceptions, this field may contain additional information. For example, if XCPT_ACCESS_VIOLATION occurs, it contains the address at which the memory access failed.

CONTEXTRECORD
This structure contains information about the machine state of the thread. It is generally of limited use to a high-level programmer because to continue a process after a synchronous exception, you must modify the CONTEXTRECORD, and it is extremely difficult to ensure the exception handler code is correct for all possible conditions. You should modify the CONTEXTRECORD only if you have no other alternative to correct your program.

You can use the CONTEXTRECORD to trace the stack and produce useful debugging information. However there are limitations:

Here is how the 32-bit stack usually looks:



Signals and Exceptions
Signal and Exception Handling
How OS/2 Chains Exception Handlers


Prototype of an OS/2 Exception Handler
Example of an OS/2 Exception Handler