Retro video games delivered to your door every month!
Click above to get retro games delivered to your door ever month!
X-Hacker.org- Watcom C/C++ User's Guide - the decision to handle an exception must be weighed carefully. it is not http://www.X-Hacker.org [<<Previous Entry] [^^Up^^] [Next Entry>>] [Menu] [About The Guide]
The decision to handle an exception must be weighed carefully.  It is not
necessarily a desirable thing for an exception handler to handle all
exceptions.  In the previous example, the expression in the exception filter
in func_level0 always evaluates to EXCEPTION_EXECUTE_HANDLER which means it
will snag every exception that comes its way.  There may be other exception
handlers further on down the chain that are better equipped to handle
certain types of exceptions.  There is a way to determine the exact type of
exception using the built-in GetExceptionCode() function.  It may be called
only from within the exception handler filter expression or within the
exception handler block.  Here is a description of the possible return
values from the GetExceptionCode() function.

Value
    Meaning

EXCEPTION_ACCESS_VIOLATION
    The thread tried to read from or write to a virtual address for which it
    does not have the appropriate access.

EXCEPTION_BREAKPOINT
    A breakpoint was encountered.

EXCEPTION_DATATYPE_MISALIGNMENT
    The thread tried to read or write data that is misaligned on hardware
    that does not provide alignment.  For example, 16-bit values must be
    aligned on 2-byte boundaries; 32-bit values on 4-byte boundaries, and so
    on.

EXCEPTION_SINGLE_STEP
    A trace trap or other single-instruction mechanism signaled that one
    instruction has been executed.

EXCEPTION_ARRAY_BOUNDS_EXCEEDED
    The thread tried to access an array element that is out of bounds and
    the underlying hardware supports bounds checking.

EXCEPTION_FLT_DENORMAL_OPERAND
    One of the operands in a floating-point operation is denormal.  A
    denormal value is one that is too small to represent as a standard
    floating-point value.

EXCEPTION_FLT_DIVIDE_BY_ZERO
    The thread tried to divide a floating-point value by a floating-point
    divisor of zero.

EXCEPTION_FLT_INEXACT_RESULT
    The result of a floating-point operation cannot be represented exactly
    as a decimal fraction.

EXCEPTION_FLT_INVALID_OPERATION
    This exception represents any floating-point exception not included in
    this list.

EXCEPTION_FLT_OVERFLOW
    The exponent of a floating-point operation is greater than the magnitude
    allowed by the corresponding type.

EXCEPTION_FLT_STACK_CHECK
    The stack overflowed or underflowed as the result of a floating-point
    operation.

EXCEPTION_FLT_UNDERFLOW
    The exponent of a floating-point operation is less than the magnitude
    allowed by the corresponding type.

EXCEPTION_INT_DIVIDE_BY_ZERO
    The thread tried to divide an integer value by an integer divisor of
    zero.

EXCEPTION_INT_OVERFLOW
    The result of an integer operation caused a carry out of the most
    significant bit of the result.

EXCEPTION_PRIV_INSTRUCTION
    The thread tried to execute an instruction whose operation is not
    allowed in the current machine mode.

EXCEPTION_NONCONTINUABLE_EXCEPTION
    The thread tried to continue execution after a non-continuable exception
    occurred.

These constants are defined by including WINDOWS.H in the source code.

The following example is a refinement of the func_level1 function in our
previous example.

Example:

     #include <windows.h>

     func_level0()
     {
       _try {
         _try {
           func_level1();
         }
         _except (
             (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION)
             ? EXCEPTION_EXECUTE_HANDLER
             : EXCEPTION_CONTINUE_SEARCH
             ) {
           printf( "Exception handled in func_level0\n" );
         }
       }
       _finally {
         if( AbnormalTermination() )
           printf( "Unwind in func_level0\n" );
       }
       printf( "Normal return from func_level0\n" );
     }

In this version, only an "access violation" will be handled by the exception
handler in the func_level0 function.  All other types of exceptions will be
passed on to main (which can also be modified to be somewhat more selective
about the types of exceptions it should handle).

More information on the exception that has occurred can be obtained by the
use of the GetExceptionInformation() function.  The use of this function is
also restricted.  It can be called only from within the filter expression of
an exception handler.  However, the return value of
GetExceptionInformation() can be passed as a parameter to a filter function.
 This is illustrated in the following example.

Example:

     int GetCode( LPEXCEPTION_POINTERS exceptptrs )
     {
         return (exceptptrs->ExceptionRecord->ExceptionCode );
     }

     func_level0()
     {
       _try {
         _try {
           func_level1();
         }
         _except (
             (GetCode( GetExceptionInformation() )
                 == EXCEPTION_ACCESS_VIOLATION)
             ? EXCEPTION_EXECUTE_HANDLER
             : EXCEPTION_CONTINUE_SEARCH
             ) {
           printf( "Exception handled in func_level0\n" );
         }
       }
       _finally {
         if( AbnormalTermination() )
           printf( "Unwind in func_level0\n" );
       }
       printf( "Normal return from func_level0\n" );
     }

The return value of GetExceptionInformation() is a pointer to an
 EXCEPTION_POINTERS structure that contains pointers to two other
structures:  an  EXCEPTION_RECORD structure containing a description of the
exception, and a  CONTEXT structure containing the machine-state
information.  The filter function can make a copy of the structures if a
more permanent copy is desired.  Check your Win32 SDK documentation for more
information on these structures.

Online resources provided by: http://www.X-Hacker.org --- NG 2 HTML conversion by Dave Pearson