Windows System Programming : Exception Handling - Termination Handlers

4/29/2013 7:36:16 PM

A termination handler serves much the same purpose as an exception handler, but it is executed when a thread leaves a block as a result of normal program flow as well as when an exception occurs. On the other hand, a termination handler cannot diagnose an exception.

Construct a termination handler using the __finally keyword in a try-finally statement. The structure is the same as for a try-except statement, but there is no filter expression. Termination handlers, like exception handlers, are a convenient way to close handles, release resources, restore masks, and otherwise restore the process to a known state when leaving a block. For example, a program may execute return statements in the middle of a block, and the termination handler can perform the cleanup work. In this way, there is no need to include the cleanup code in the code block itself, nor is there a need for goto or other control flow statements to reach the cleanup code.

__try {
   /* Code block. */
__finally {
   /* Termination handler (finally block). */

Leaving the Try Block

The termination handler is executed whenever the control flow leaves the try block for any of the following reasons:

  • Reaching the end of the try block and “falling through” to the termination handler

  • Execution of one of the following statements in such a way as to leave the block:




    [1] It may be a matter of taste, either individual or organizational, but many programmers never use the goto statement and try to avoid break, except with the switch statement and sometimes in loops, and with continue. Reasonable people continue to differ on this subject. The termination and exception handlers can perform many of the tasks that you might want to perform with a goto to a labeled statement.




    [2] This statement is specific to the Microsoft C compiler and is an efficient way to leave a try-finally block without an abnormal termination.

  • An exception

Abnormal Termination

Termination for any reason other than reaching the end of the try block and falling through or performing a __leave statement is considered an abnormal termination. The effect of __leave is to transfer to the end of the __try block and fall through. Within the termination handler, use this function to determine how the try block terminated.

BOOL AbnormalTermination (VOID)

The return value will be TRUE for an abnormal termination or FALSE for a normal termination.


The termination would be abnormal even if, for example, a return statement were the last statement in the try block.

Executing and Leaving the Termination Handler

The termination handler, or __finally block, is executed in the context of the block or function that it monitors. Control can pass from the end of the termination handler to the next statement. Alternatively, the termination handler can execute a flow control statement (return, break, continue, goto, longjmp, or __leave). Leaving the handler because of an exception is another possibility.

Combining Finally and Except Blocks

A single try block must have a single finally or except block; it cannot have both, even though it might be convenient. Therefore, the following code would cause a compile error.

__try {
   /* Block of monitored code. */
__except (filter_expression) {
   /* Except block. */
__finally {
   /* Do not do this! It will not compile. */

It is possible, however, to embed one block within another, a technique that is frequently useful. The following code is valid and ensures that the temporary file is deleted if the loop exits under program control or because of an exception. This technique is also useful to ensure that file locks are released. There is also an inner try-except block with some floating-point processing.

__try { /* Outer try-except block. */
   while (...) __try { /* Inner try-finally block. */
      hFile = CreateFile(tempFile, ...);
      if (...) __try { /* Inner try-except block. */
         /* Enable FP exceptions. Perform computations. */
      __except (fp-filter-expression) {
         ... /* Process FP exception. */ _clearfp();
      ... /* Non-FP processing. /*
   __finally { /* End of while loop. */
   /* Executed on EVERY loop iteration. */
      CloseHandle(hFile); DeleteFile(tempFile);
__except (filter-expression) {
   /* Exception handler. */

Global and Local Unwinds

Exceptions and abnormal terminations will cause a global stack unwind to search for a handler. For example, suppose an exception occurs in the monitored block of the example at the end of the preceding section before the floating-point exceptions are enabled. The termination handler will be executed first, followed by the exception handler at the end. There might be numerous termination handlers on the stack before the exception handler is located.

Recall that the stack structure is dynamic, and that it contains, among other things, the exception and termination handlers. The contents at any time depend on:

  • The static structure of the program’s blocks

  • The dynamic structure of the program as reflected in the sequence of open function calls

Termination Handlers: Process and Thread Termination

Termination handlers do not execute if a process or thread terminates, whether the process or thread terminates itself by using ExitProcess or ExitThread, or whether the termination is external, caused by a call to TerminateProcess or TerminateThread from elsewhere. Therefore, a process or thread should not execute one of these functions inside a try-except or try-finally block.

Notice also that the C library exit function or a return from a main function will exit the process.

SEH and C++ Exception Handling

C++ exception handling uses the keywords catch and throw and is implemented using SEH. Nonetheless, C++ exception handling and SEH are distinct. They should be mixed with care, or not at all, because the user-written and C++-generated exception handlers may interfere with expected operation. For example, an __except handler may be on the stack and catch a C++ exception so that the C++ handler will never receive the exception. The converse is also possible, with a C++ handler catching, for example, an SEH exception generated with RaiseException. The Microsoft documentation recommends that Windows exception handlers not be used in C++ programs at all but instead that C++ exception handling be used exclusively.

Normally, a Windows exception or termination handler will not call destructors to destroy C++ object instances. However, the /EHa compiler flag (setable from Visual Studio) allows C++ exception handling to include asynchronous exceptions and “unwind” (destroy) C++ objects.

Top 10
Review : Sigma 24mm f/1.4 DG HSM Art
Review : Canon EF11-24mm f/4L USM
Review : Creative Sound Blaster Roar 2
Review : Philips Fidelio M2L
Review : Alienware 17 - Dell's Alienware laptops
Review Smartwatch : Wellograph
Review : Xiaomi Redmi 2
Extending LINQ to Objects : Writing a Single Element Operator (part 2) - Building the RandomElement Operator
Extending LINQ to Objects : Writing a Single Element Operator (part 1) - Building Our Own Last Operator
3 Tips for Maintaining Your Cell Phone Battery (part 2) - Discharge Smart, Use Smart
- First look: Apple Watch

- 3 Tips for Maintaining Your Cell Phone Battery (part 1)

- 3 Tips for Maintaining Your Cell Phone Battery (part 2)
- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 1)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 2)

- How to create your first Swimlane Diagram or Cross-Functional Flowchart Diagram by using Microsoft Visio 2010 (Part 3)
Popular Tags
Video Tutorail Microsoft Access Microsoft Excel Microsoft OneNote Microsoft PowerPoint Microsoft Project Microsoft Visio Microsoft Word Active Directory Exchange Server Sharepoint Sql Server Windows Server 2008 Windows Server 2012 Windows 7 Windows 8 Adobe Flash Professional Dreamweaver Adobe Illustrator Adobe Photoshop CorelDRAW X5 CorelDraw 10 windows Phone 7 windows Phone 8 Iphone