Platform SDK: Debugging and Error Handling

Termination-Handler Syntax

The __try and __finally keywords are used to construct a termination handler. The following example shows the structure of a termination handler.

__try 
{ 
    // guarded body of code 
 
} 
__finally 
{ 
    // __finally block 
 
} 

As with the exception handler, both the __try block and the __finally block require braces ({}), and using a goto statement to jump into either block is not permitted.

The __try block contains the guarded body of code that is protected by the termination handler. A function can have any number of termination handlers, and these termination-handling blocks can be nested within the same function or in different functions.

The __finally block is executed whenever the flow of control leaves the __try block. However, the __finally block is not executed if you call any of the following functions within the __try block: ExitProcess, ExitThread, or abort.

The __finally block is executed in the context of the function in which the termination handler is located. This means that the __finally block can access that function's local variables. Execution of the __finally block can terminate by any of the following means.

If execution of the __try block terminates because of an exception that invokes the exception-handling block of a frame-based exception handler, the __finally block is executed before the exception-handling block is executed. Similarly, a call to the longjmp C run-time library function from the __try block causes execution of the __finally block before execution resumes at the target of the longjmp operation. If __try block execution terminates due to a control statement (return, break, continue, or goto), the __finally block is executed.

The AbnormalTermination function can be used within the __finally block to determine whether the __try block terminated sequentially — that is, whether it reached the closing brace (}). Leaving the __try block because of a call to longjmp, a jump to an exception handler, or a return, break, continue, or goto statement, is considered an abnormal termination. Note that failure to terminate sequentially causes the system to search through all stack frames in reverse order to determine whether any termination handlers must be called. This can result in performance degradation due to the execution of hundreds of instructions.

To avoid abnormal termination of the termination handler, execution should continue to the end of the block. You can also execute the __leave statement. The __leave statement allows for immediate termination of the __try block without causing abnormal termination and its performance penalty. Check your compiler documentation to determine if the __leave statement is supported.

If execution of the __finally block terminates because of the return control statement, it is equivalent to a goto to the closing brace in the enclosing function. Therefore, the enclosing function will return.