Thursday, May 20, 2010

Win32 Exceptions – OS Level Point of View

One of the widely used and not well documented feature of 32-bit Windows operating system is structured exceptions handling. This common exception service provided by operating system is used by C++ compilers.

This article describes the win32 exception layering and discusses structured exceptions handling (SEH) on OS level and on C++ compiler level.

Describing exceptions from OS level point of view helps to understand functionality and the performance cost of exceptions. Then, it will be not difficult to reveal how it is possible to mix SEH and C++ exceptions and how it is possible to catch SEH in C++ exceptions which could be the main motivation why to read this article.

The best way how to understand the topic is to play with attached examples.

Win32 Exception Layering

The following diagram shows how the common exception service provided by OS (OS Level SEH) is used by C++ compilers for structured exceptions handling (C++ Compiler Level SEH) and for well-known C++ exceptions (C++ Exception Handling).

It is important to understand that both C++ Compiler Level SEH and C++ Exception Handling use the same OS Level SEH.

OS Level SEH

The common exception service provided by OS handles:

Software (Synchronous) Exceptions - explicitly passes control to the operating system through software interrupt
Hardware (Asynchronous) Exceptions - e.g. access violation, integer division by 0, illegal instruction, etc...
Exception Callback Function

Whenever some exception occurs, OS calls the Exception Callback Function within the current thread context.

This function can be defined by the user and the prototype is as follows (defined in excpt.h header):

EXCEPTION_DISPOSITION __cdecl _except_handler
(

struct _EXCEPTION_RECORD* _ExceptionRecord,
void*                     _EstablisherFrame,
struct _CONTEXT*          _ContextRecord,
void*                     _DispatcherContext
);

According to the returned value, OS will perform a certain action (defined in excpt.h):


typedef enum _EXCEPTION_DISPOSITION
{

ExceptionContinueExecution, // tells OS to restart faulting instruction
ExceptionContinueSearch,    // tells OS to continue Exception
                             // Callback Function searching
ExceptionNestedException,
ExceptionCollidedUnwind
} EXCEPTION_DISPOSITION;

The first parameter _ExceptionRecord describes the exception (defined in WinNT.h):

typedef struct _EXCEPTION_RECORD
{

DWORD     ExceptionCode;    // which exception occurred
DWORD     ExceptionFlags;   // additional exception info
struct _EXCEPTION_RECORD *ExceptionRecord;
PVOID     ExceptionAddress; // where the exception occurred
DWORD     NumberParameters;
ULONG_PTR ExceptionInformation[EXCEPTION_MAXIMUM_PARAMETERS];
} EXCEPTION_RECORD;

The third parameter _ContextRecord is a pointer to the CONTEXT structure which represents the register values of a particular thread at the time of the exception. This structure is defined in WinNT.h and it is the same structure which is used for the Get/SetThreadContext API methods.


Read more: Codeproject

Posted via email from jasper22's posterous