Unwinding Exception Handlers

In addition to handling exceptions, exception handlers are used to clean up resources during the execution of a nonlocal GOTO instruction or during thread termination. (A nonlocal GOTO instruction jumps to a label outside the current procedure. The label is a procedure address or an address within a procedure that is on the stack, higher in the call frame chain.)

DosUnwindException calls and removes exception handlers from a thread's chain of registered exception handlers up to, but not including, a specified exception handler. This is known as an unwind operation. DosUnwindException can also be used to unwind all exception handlers from the thread's exception handler chain and to terminate the thread.

For example, with the C language setjmp() and longjmp() routines, the setjmp() would save the address of the current exception handler structure, along with any other information that is necessary to perform the longjmp() routine. (The address of the current exception handler structure is obtained from the head of the exception handler chain. A pointer to the head of the chain is located in the Thread Information Block.)

The longjmp() routine would initiate the unwind of procedure call frames by calling DosUnwindException and passing to it the saved address of the EXCEPTIONREGISTRATIONRECORD data structure. If the address of the EXCEPTIONREGISTRATIONRECORD data structure is not found in the chain, then the XCPT_INVALID_UNWIND_TARGET exception is raised, and the chain is not unwound.

The machine state at the time of the call to DosUnwindException is captured in ContextRecord. The EH_UNWINDING flag is set in the exception flags field of the EXCEPTIONREPORTRECORD data structure. The EH_EXIT_UNWIND flag is also set if the EXCEPTIONREGISTRATIONRECORD parameter is set to 0 (if the application does not provide its own EXCEPTIONREPORTRECORD parameter OS/2 will construct one). A backward walk through the procedure call frames is then performed to find the target of the unwind operation.

Note: Even though a ContextRecord is used to capture the state of the machine, unwinding is not considered an exception. It is simply delivered through the exception mechanism.