programming4us
programming4us
ENTERPRISE

Windows System Programming : Exception Handling - Exceptions and Their Handlers

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019

Without some form of exception handling, an unintended program exception, such as dereferencing a NULL pointer or division by zero, will terminate a program immediately without performing normal termination processing, such as deleting temporary files. SEH allows specification of a code block, or exception handler, which can delete the temporary files, perform other termination operations, and analyze and log the exception. In general, exception handlers can perform any required cleanup operations before leaving the code block.

Normally, an exception indicates a fatal error with no recovery, and the thread , or even the entire process, should terminate after the handler reports the exception. Do not expect to be able to resume execution from the point where the exception occurs. Nonetheless, we will show an example where a program can continue execution.

SEH is supported through a combination of Windows functions, compiler-supported language extensions, and run-time support. The exact language support may vary; the examples here were all developed for Microsoft C.

Try and Except Blocks

The first step in using SEH is to determine which code blocks to monitor and provide them with exception handlers, as described next. It is possible to monitor an entire function or to have separate exception handlers for different code blocks and functions.

A code block is a good candidate for an exception handler in situations that include the following, and catching these exceptions allows you to detect bugs and avoid potentially serious problems.

  • Detectable errors, including system call errors, might occur, and you need to recover from the error rather than terminate the program.

  • There is a possibility of dereferencing pointers that have not been properly initialized or computed.

  • There is array manipulation, and it is possible for array indices to go out of bounds.

  • The code performs floating-point arithmetic, and there is concern with zero divides, imprecise results, and overflows.

  • The code calls a function that might generate an exception intentionally, because the function arguments are not correct, or for some other occurrence.

SEH uses “try” and “except” blocks. Once you have decided to monitor a block, create the try and except blocks as follows:

 __try {
      /* Block of monitored code */
}
 __except (filter_expression) {
   /* Exception handling block */
}

Note that __try and __except are keywords that the C compiler recognizes; however, they are not part of standard C.

The try block is part of normal application code. If an exception occurs in the block, the OS transfers control to the exception handler, which is the code in the block associated with the __except clause. The value of the filter_expression determines the actions that follow.

The exception could occur within a block embedded in the try block, in which case the run-time support “unwinds” the stack to find the exception handler and then gives control to the handler. The same thing happens when an exception occurs within a function called within a try block if the function does not have an appropriate exception handler.

For the x86 architecture, Figure 1 shows how an exception handler is located on the stack when an exception occurs. Once the exception handler block completes, control passes to the next statement after the exception block unless there is some other control flow statement in the handler. Note that SEH on some other architectures uses a more efficient static registration process (out of scope for this discussion) to achieve a similar result.

Figure 1. SEH, Blocks, and Functions

Filter Expressions and Their Values

The filter_expression in the __except clause is evaluated immediately after the exception occurs. The expression is usually a literal constant, a call to a filter function, or a conditional expression. In all cases, the expression should return one of three values.

  1. EXCEPTION_EXECUTE_HANDLER— Windows executes the except block as shown in Figure 1 /

  2. EXCEPTION_CONTINUE_SEARCH— Windows ignores the exception handler and searches for an exception handler in the enclosing block, continuing until it finds a handler.

  3. EXCEPTION_CONTINUE_EXECUTION— Windows immediately returns control to the point at which the exception occurred. It is not possible to continue after some exceptions, and inadvisable in most other cases, and another exception is generated immediately if the program attempts to do so.

Here is a simple example using an exception handler to delete a temporary file if an exception occurs in the loop body. Notice you can apply the __try clause to any block, including the block associated with a while, if, or other flow control statement. In this example, if there is any exception, the exception handler closes the file handle and deletes the temporary file. The loop iteration continues.

The exception handler executes unconditionally. In many realistic situations, the exception code is tested first to determine if the exception handler should execute; the next sections show how to test the exception code.

hFile = INVALID_HANDLE_VALUE;
while (...) __try {
   GetTempFileName(tempFile, ...);
   hFile = CreateFile(tempFile, ..., OPEN_ALWAYS, ...);
   SetFilePointerEx(hFile, 0, NULL, FILE_END);
   ...
   WriteFile(hFile, ...);
   i = *p; /* An addressing exception could occur. */
   ...
   CloseHandle(hFile);
   hFile = INVALID_HANDLE_VALUE;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
   /* Print error information; this is probably a bug */
   if (INVALID_HANDLE_VALUE != hFile) CloseHandle(hFile);
   hFile = INVALID_HANDLE_VALUE;
   DeleteFile(tempFile);
   /* The loop will now execute the next iteration .*/
}
/* Control passes here after normal loop termination.
   The file handle is always closed and the temp file
   will not exist if there was an exception. */

					  

The logic of this code fragment is as follows.

  • Each loop iteration writes data to a temporary file associated with the iteration. An enhancement would append an identifier to the temporary file name.

  • If an exception occurs in any loop iteration, all data accumulated in the temporary file is deleted, and the next iteration, if any, starts to accumulate data in a new temporary file with a new name. You need to create a new name so that another process does not get the temporary name after the deletion.

  • The example shows just one location where an exception could occur, although the exception could occur anywhere within the loop body.

  • The file handle is assured of being closed when exiting the loop or starting a new loop iteration.

  • If an exception occurs, there is almost certainly a program bug. Program 4 shows how to analyze an address exception. Nonetheless, this code fragment allows the loop to continue, although it might be better to consider this a fatal error and terminate the program.

Exception Codes

The __except block or the filter expression can determine the exact exception using this function:

DWORD GetExceptionCode (VOID)


You must get the exception code immediately after an exception. Therefore, the filter function itself cannot call GetExceptionCode (the compiler enforces this restriction). A common usage is to invoke it in the filter expression, as in the following example, where the exception code is the argument to a user-supplied filter function.

__except (MyFilter(GetExceptionCode())) {
}

In this situation, the filter function determines and returns the filter expression value, which must be one of the three values enumerated earlier. The function can use the exception code to determine the function value; for example, the filter may decide to pass floating-point exceptions to an outer handler (by returning EXCEPTION_CONTINUE_SEARCH) and to handle a memory access violation in the current handler (by returning EXCEPTION_EXECUTE_HANDLER).

GetExceptionCode can return a large number of possible exception code values, and the codes are in several categories.

  • Program violations such as the following:

    - EXCEPTION_ACCESS_VIOLATION— An attempt to read, write, or execute a virtual address for which the process does not have access.

    - EXCEPTION_DATATYPE_MISALIGNMENT— Many processors insist, for example, that DWORDs be aligned on 4-byte boundaries.

    - EXCEPTION_NONCONTINUABLE_EXECUTION— The filter expression was EXCEPTION_CONTINUE_EXECUTION, but it is not possible to continue after the exception that occurred.

  • Exceptions raised by the memory allocation functions—HeapAlloc and HeapCreate—if they use the HEAP_GENERATE_EXCEPTIONS flag . The value will be either STATUS_NO_MEMORY or EXCEPTION_ACCESS_VIOLATION.

  • A user-defined exception code generated by the RaiseException function; see the User-Generated Exceptions subsection.

  • A large variety of arithmetic (especially floating-point) codes such as EXCEPTION_INT_DIVIDE_BY_ZERO and EXCEPTION_FLT_OVERFLOW.

  • Exceptions used by debuggers, such as EXCEPTION_BREAKPOINT and EXCEPTION_SINGLE_STEP.

GetExceptionInformation is an alternative function, callable only from within the filter expression, which returns additional information, some of which is processor-specific. Program 3 uses GetExceptionInformation.

LPEXCEPTION_POINTERS GetExceptionInformation (VOID)


The EXCEPTION_POINTERS structure contains both processor-specific and processor-independent information organized into two other structures, an exception record and a context record.

typedef struct _EXCEPTION_POINTERS {
   PEXCEPTION_RECORD ExceptionRecord;
   PCONTEXT ContextRecord;
} EXCEPTION_POINTERS;


EXCEPTION_RECORD contains a member for the ExceptionCode with the same set of values as returned by GetExceptionCode. The ExceptionFlags member of the EXCEPTION_RECORD is either 0 or EXCEPTION_NONCONTINUABLE, which allows the filter function to determine that it should not attempt to continue execution. Other data members include a virtual memory address, ExceptionAddress, and a parameter array, ExceptionInformation.

In the case of EXCEPTION_ACCESS_VIOLATION or EXCEPTION_IN_PAGE_VIOLATION, the first element indicates whether the violation was a memory write (1), read (0), or execute (8). The second element is the virtual memory address. The third array element specifies the NSTATUS code that caused the exception.

The execute error (code 8) is a Data Execution Prevention (DEP) error, which indicates an attempt to execute data that is not intended to be code, such as data on the heap. This feature is supported as of XP SP2; see MSDN for more information.

ContextRecord, the second EXCEPTION_POINTERS member, contains processor-specific information, including the address where the exception occurred. There are different structures for each type of processor, and the structure can be found in <winnt.h>.

Summary: Exception Handling Sequence

Figure 2 shows the sequence of events that takes place when an exception occurs. The code is on the left side, and the circled numbers on the right show the steps carried out by the language run-time support. The steps are as follows.

Figure 2. Exception Handling Sequence

  1. The exception occurs, in this case a division by zero.

  2. Control transfers to the exception handler, where the filter expression is evaluated. GetExceptionCode is called first, and its return value is the argument to the function Filter.

  3. The filter function bases its actions on the exception code value.

  4. The exception code is EXCEPTION_INT_DIVIDE_BY_ZERO in this case.

  5. The filter function determines that the exception handler should be executed, so the return value is EXCEPTION_EXECUTE_HANDLER.

  6. The exception handler, which is the code associated with the __except clause, executes.

  7. Control passes out of the try-except block.

Other  
  •  Building Applications with Visual Studio 2010 : Getting Smart about Smart Clients - Using the Properties Window
  •  Building Applications with Visual Studio 2010 : Getting Smart about Smart Clients - Manipulating Controls
  •  .NET Debugging : Introduction to the Tools - Reflector for .NET, PowerDbg, Managed Debugging Assistants
  •  .NET Debugging : Introduction to the Tools - CLR Profiler, Performance Counters
  •  Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 2)
  •  Microsoft .NET : Design Principles and Patterns - From Principles to Patterns (part 1)
  •  All We Need To Know About Green Computing (Part 4)
  •  All We Need To Know About Green Computing (Part 3)
  •  All We Need To Know About Green Computing (Part 2)
  •  All We Need To Know About Green Computing (Part 1)
  •  
    Top 10
    Free Mobile And Desktop Apps For Accessing Restricted Websites
    MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
    TOYOTA CAMRY 2; 2.5 : Camry now more comely
    KIA SORENTO 2.2CRDi : Fuel-sipping slugger
    How To Setup, Password Protect & Encrypt Wireless Internet Connection
    Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
    Backup & Restore Game Progress From Any Game With SaveGameProgress
    Generate A Facebook Timeline Cover Using A Free App
    New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
    SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
    - Messages forwarded by Outlook rule go nowhere
    - Create and Deploy Windows 7 Image
    - How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
    - Creating and using an unencrypted cookie in ASP.NET
    - Directories
    - Poor Performance on Sharepoint 2010 Server
    - SBS 2008 ~ The e-mail alias already exists...
    - Public to Private IP - DNS Changes
    - Send Email from Winform application
    - How to create a .mdb file from ms sql server database.......
    programming4us programming4us
    programming4us
     
     
    programming4us