The Microsoft Windows family of operating systems employ some specific exception handling mechanisms.
Microsoft Structured Exception Handling is the native exception handling mechanism for Windows and a forerunner technology to
Vectored Exception Handling (VEH).
[1] It features the finally
mechanism not present in standard C++ exceptions (but present in most
imperative languages introduced later). SEH is set up and handled separately for each
thread of execution.
Microsoft supports SEH as a programming technique at the compiler level only. MS Visual C++ compiler features three non-standard keywords: __try
, __except
and __finally
— for this purpose. Other exception handling aspects are backed by a number of
Win32 API functions,
[2] for example, RaiseException
to raise SEH exceptions manually.
Each
thread of execution in Windows
IA-32 edition or the
WoW64 emulation layer for the
x86-64 version has a link to an undocumented _EXCEPTION_REGISTRATION_RECORD
list at the start of its
Thread Information Block. The __try
statement essentially calls a compiler-defined EH_prolog
function. That function allocates an _EXCEPTION_REGISTRATION_RECORD
on the stack pointing to the __except_handler3
[a] function in msvcrt.dll
,
[b] then adds the record to the list's head. At the end of the __try
block a compiler-defined EH_epilog
function is called that does the reverse operation. Either of these compiler-defined routines can be
inline. All the programmer-defined __except
and __finally
blocks are called from within __except_handler3
. If the programmer-defined blocks are present, the _EXCEPTION_REGISTRATION_RECORD created by EH_prolog
is extended with a few additional fields used by __except_handler3
.
[3]
In the case of an exception in
user mode code, the operating system
[c] parses the thread's _EXCEPTION_REGISTRATION_RECORD list and calls each exception handler in sequence until a handler signals it has handled the exception (by
return value) or the list is exhausted. The last one in the list is always the kernel32!UnhandledExceptionFilter
which displays the
General protection fault error message.
[d] Then the list is traversed once more giving handlers a chance to clean up any resources used. Finally, the execution returns to
kernel mode
[e] where the process is either resumed or terminated.
The patent on this mode of SEH, US5628016, expired in 2014.
SEH on 64-bit Windows does not involve a runtime exception handler list; instead, it uses a
stack unwinding table (UNWIND_INFO
) interpreted by the system when an exception occurs.
[4]
[5]
This means that the compiler does not have to generate extra code to manually perform stack unwinding and to call exception handlers appropriately. It merely has to emit information in the form of unwinding tables about the stack frame layout and specified exception handlers.
GCC 4.8+ from
Mingw-w64 supports using 64-bit SEH for C++ exceptions.
LLVM clang supports __try
on both x86 and x64.
[6]
Vectored Exception Handling was introduced in Windows XP. [7] Vectored Exception Handling is made available to Windows programmers using languages such as C++ and Visual Basic. VEH does not replace Structured Exception Handling (SEH); rather, VEH and SEH coexist, with VEH handlers having priority over SEH handlers. [1] [7] Compared with SEH, VEH works more like kernel-delivered Unix signals. [8]
ntdll.dll
and kernel32.dll
, as well as other programs linked statically with VC runtime, have this function compiled-in instead
ntdll!RtlDispatchException
system routine called from ntdll!KiUserExceptionDispatcher
which is in turn called from the nt!KiDispatchException
kernel function. (See Ken Johnson (November 16, 2007).
"A catalog of NTDLL kernel mode to user mode callbacks, part 2: KiUserExceptionDispatcher". for details)
ntdll!KiUserExceptionDispatcher
calls either nt!ZwContinue
or nt!ZwRaiseException
/link /safeseh:no
.The Microsoft Windows family of operating systems employ some specific exception handling mechanisms.
Microsoft Structured Exception Handling is the native exception handling mechanism for Windows and a forerunner technology to
Vectored Exception Handling (VEH).
[1] It features the finally
mechanism not present in standard C++ exceptions (but present in most
imperative languages introduced later). SEH is set up and handled separately for each
thread of execution.
Microsoft supports SEH as a programming technique at the compiler level only. MS Visual C++ compiler features three non-standard keywords: __try
, __except
and __finally
— for this purpose. Other exception handling aspects are backed by a number of
Win32 API functions,
[2] for example, RaiseException
to raise SEH exceptions manually.
Each
thread of execution in Windows
IA-32 edition or the
WoW64 emulation layer for the
x86-64 version has a link to an undocumented _EXCEPTION_REGISTRATION_RECORD
list at the start of its
Thread Information Block. The __try
statement essentially calls a compiler-defined EH_prolog
function. That function allocates an _EXCEPTION_REGISTRATION_RECORD
on the stack pointing to the __except_handler3
[a] function in msvcrt.dll
,
[b] then adds the record to the list's head. At the end of the __try
block a compiler-defined EH_epilog
function is called that does the reverse operation. Either of these compiler-defined routines can be
inline. All the programmer-defined __except
and __finally
blocks are called from within __except_handler3
. If the programmer-defined blocks are present, the _EXCEPTION_REGISTRATION_RECORD created by EH_prolog
is extended with a few additional fields used by __except_handler3
.
[3]
In the case of an exception in
user mode code, the operating system
[c] parses the thread's _EXCEPTION_REGISTRATION_RECORD list and calls each exception handler in sequence until a handler signals it has handled the exception (by
return value) or the list is exhausted. The last one in the list is always the kernel32!UnhandledExceptionFilter
which displays the
General protection fault error message.
[d] Then the list is traversed once more giving handlers a chance to clean up any resources used. Finally, the execution returns to
kernel mode
[e] where the process is either resumed or terminated.
The patent on this mode of SEH, US5628016, expired in 2014.
SEH on 64-bit Windows does not involve a runtime exception handler list; instead, it uses a
stack unwinding table (UNWIND_INFO
) interpreted by the system when an exception occurs.
[4]
[5]
This means that the compiler does not have to generate extra code to manually perform stack unwinding and to call exception handlers appropriately. It merely has to emit information in the form of unwinding tables about the stack frame layout and specified exception handlers.
GCC 4.8+ from
Mingw-w64 supports using 64-bit SEH for C++ exceptions.
LLVM clang supports __try
on both x86 and x64.
[6]
Vectored Exception Handling was introduced in Windows XP. [7] Vectored Exception Handling is made available to Windows programmers using languages such as C++ and Visual Basic. VEH does not replace Structured Exception Handling (SEH); rather, VEH and SEH coexist, with VEH handlers having priority over SEH handlers. [1] [7] Compared with SEH, VEH works more like kernel-delivered Unix signals. [8]
ntdll.dll
and kernel32.dll
, as well as other programs linked statically with VC runtime, have this function compiled-in instead
ntdll!RtlDispatchException
system routine called from ntdll!KiUserExceptionDispatcher
which is in turn called from the nt!KiDispatchException
kernel function. (See Ken Johnson (November 16, 2007).
"A catalog of NTDLL kernel mode to user mode callbacks, part 2: KiUserExceptionDispatcher". for details)
ntdll!KiUserExceptionDispatcher
calls either nt!ZwContinue
or nt!ZwRaiseException
/link /safeseh:no
.