The Microsoft Windows family of operating systems employ some specific exception handling mechanisms.
== {{Anchor|SEH}}Structured Exception Handling == Microsoft Structured Exception Handling is the native exception handling mechanism for Windows and a forerunner technology to Vectored Exception Handling (VEH).<ref name=devx>{{cite web|url=http://www.devx.com/microsoftISV/Article/15992 |title=Vectored Exception Handling in Windows Server 2003 (Through Internet Archive) |archive-url = https://web.archive.org/web/20080118162324/http://www.devx.com/microsoftISV/Article/15992 |archive-date = 2008-01-18}}</ref> It features the <code>finally</code> 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.
=== Usage === {{see also|Exception handling syntax#Microsoft-specific}} Microsoft supports SEH as a programming technique at the compiler level only. MS Visual C++ compiler features three non-standard keywords: <code>__try</code>, <code>__except</code> and <code>__finally</code> — for this purpose. Other exception handling aspects are backed by a number of Win32 API functions,<ref>{{cite web |url=https://msdn.microsoft.com/en-us/library/ms680659.aspx |title=Structured Exception Handling Functions |date=2009-11-12 |work=MSDN Library |author=Microsoft Corp. |access-date=2022-07-23 }}</ref> for example, <code>RaiseException</code> to raise SEH exceptions manually.
<syntaxhighlight lang="c"> int filterExpression(EXCEPTION_POINTERS* ep) { ep->ContextRecord->Eip += 8; // divide instruction may be encoded from 2 to 8 bytes return EXCEPTION_CONTINUE_EXECUTION; }
int main(void) { static int zero = 0; __try { zero = 1 / zero; asm { nop nop nop nop nop nop nop } printf("Past the exception.\n"); } __except (filterExpression(GetExceptionInformation())) { printf("Handler called.\n"); } return 0; } </syntaxhighlight>
=== Implementation ===
==== IA-32 ==== 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 {{mono|_EXCEPTION_REGISTRATION_RECORD}} list at the start of its Thread Information Block. The <code>__try</code> statement essentially calls a compiler-defined <code>EH_prolog</code> function. That function allocates an {{mono|_EXCEPTION_REGISTRATION_RECORD}} on the stack pointing to the <code>__except_handler3</code>{{Efn|The name varies in different versions of VC runtime}} function in <code>msvcrt.dll</code>,{{Efn|<code>ntdll.dll</code> and <code>kernel32.dll</code>, as well as other programs linked statically with VC runtime, have this function compiled-in instead}} then adds the record to the list's head. At the end of the <code>__try</code> block a compiler-defined <code>EH_epilog</code> function is called that does the reverse operation. Either of these compiler-defined routines can be inline. All the programmer-defined <code>__except</code> and <code>__finally</code> blocks are called from within <code>__except_handler3</code>. If the programmer-defined blocks are present, the {{mono|_EXCEPTION_REGISTRATION_RECORD}} created by <code>EH_prolog</code> is extended with a few additional fields used by <code>__except_handler3</code>.<ref>{{cite web|url=http://stoned-vienna.com/html/index.php?page=windows-exception-handling|author=Peter Kleissner|title=Windows Exception Handling - Peter Kleissner|date=February 14, 2009|access-date=2009-11-21 |archive-url=https://web.archive.org/web/20131014204335/http://stoned-vienna.com/html/index.php?page=windows-exception-handling |archive-date=October 14, 2013 |url-status=dead}}, ''Compiler based Structured Exception Handling'' section</ref>
In the case of an exception in user mode code, the operating system{{Efn|More specifically, <code>ntdll!RtlDispatchException</code> system routine called from <code>ntdll!KiUserExceptionDispatcher</code> which is in turn called from the <code>nt!KiDispatchException</code> kernel function. (See {{cite web|url=http://www.nynaeve.net/?p=201|title=A catalog of NTDLL kernel mode to user mode callbacks, part 2: KiUserExceptionDispatcher|author=Ken Johnson|date=November 16, 2007 <!-- , 7:00 am --> }} for details)}} parses the thread's {{mono|_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 <code>kernel32!UnhandledExceptionFilter</code> which displays the General protection fault error message.{{Efn|The message can be silenced by altering the process's [https://msdn.microsoft.com/en-us/library/ms680548.aspx error mode]; the default last handler can be replaced with [https://msdn.microsoft.com/en-us/library/ms680634.aspx SetUnhandledExceptionFilter] API}} Then the list is traversed once more giving handlers a chance to clean up any resources used. Finally, the execution returns to kernel mode{{Efn|<code>ntdll!KiUserExceptionDispatcher</code> calls either <code>nt!ZwContinue</code> or <code>nt!ZwRaiseException</code>}} where the process is either resumed or terminated.
The patent on this mode of SEH, US5628016, expired in 2014.
==== x86-64 ==== SEH on 64-bit Windows does not involve a runtime exception handler list; instead, it uses a stack unwinding table (<code>UNWIND_INFO</code>) interpreted by the system when an exception occurs.<ref>{{cite web |title=Exceptional Behavior - x64 Structured Exception Handling |url=https://www.osronline.com/article.cfm%5earticle=469.htm |publisher=The NT Insider}}</ref><ref>{{cite web |title=x64 exception handling |url=https://docs.microsoft.com/en-us/cpp/build/exception-handling-x64?view=vs-2019 |website=VC++ 2019 documentation | date=8 February 2022 |language=en-us}}</ref> 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.
=== Support === GCC 4.8+ from Mingw-w64 supports using 64-bit SEH for C++ exceptions. LLVM clang supports <code>__try</code> on both x86 and x64.<ref>{{cite web |title=MSVC compatibility |url=http://clang.llvm.org/docs/MSVCCompatibility.html |website=Clang 11 documentation}}</ref>
== {{Anchor|VEH}}Vectored Exception Handling == Vectored Exception Handling was introduced in Windows XP.<ref name="VEH">{{cite web|url=https://msdn.microsoft.com/en-us/magazine/cc301714.aspx|title=Under the Hood: New Vectored Exception Handling in Windows XP |archive-url = https://web.archive.org/web/20080915135659/https://msdn.microsoft.com/en-us/magazine/cc301714.aspx |archive-date = 2008-09-15 |url-status=dead}}</ref> 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.<ref name="devx" /><ref name="VEH" /> Compared with SEH, VEH works more like kernel-delivered Unix signals.<ref>{{cite web|url=https://msdn.microsoft.com/en-us/magazine/cc300448.aspx|title=Windows Server 2003 Discover Improved System Info, New Kernel, Debugging, Security, and UI APIs |archive-url = https://web.archive.org/web/20080505055123/https://msdn.microsoft.com/en-us/magazine/cc300448.aspx |archive-date = 2008-05-05 |url-status=dead}}</ref>
== Notes == {{Notelist|30em}}
== References == {{Reflist|30em}}
==External links== * {{cite web |url=https://msdn.microsoft.com/en-us/library/ms680657.aspx |title=Structured Exception Handling |date=2009-11-12 |work=MSDN Library |author=Microsoft Corp. |access-date=2022-07-23 }} * {{cite journal |author=Matt Pietrek |author-link=Matt Pietrek |date=Jan 1997 |title=A Crash Course on the Depths of Win32 Structured Exception Handling |journal=MSJ |volume=12 |issue=1 |url=https://www.microsoft.com/msj/0197/Exception/Exception.aspx|url-status=dead|archive-url=https://web.archive.org/web/20030810214010/https://www.microsoft.com/msj/0197/Exception/Exception.aspx|archive-date=2003-08-10 }} Note that the examples given there do not work as-is on modern Windows systems (post XP SP2) due to the changes Microsoft made to address the security issues present in the early SEH design. The examples still work on later versions of Windows if compiled with <code>/link /safeseh:no</code>. * {{cite web|url=https://www.tortall.net/projects/yasm/manual/html/objfmt-win32-safeseh.html|title=win32: Safe Structured Exception Handling|publisher=Yasm manual}} * {{US patent|7,480,919|US patent 7,480,919 - Safe exceptions}} * {{cite web|url=https://jpassing.com/2008/05/20/fun-with-low-level-seh/|title=Fun with low level SEH|author=Johannes Passing|date=May 20, 2008}} Covers the obscure details needed to get low-level SEH (and particularly SafeSEH) code to work on more modern Windows. * {{cite web |url=https://www.openrce.org/articles/full_view/21 |title=Reversing Microsoft Visual C++ Part I: Exception Handling |author=Igor Skochinsky |date= March 6, 2006 |publisher=OpenRCE |access-date=2009-11-17 }} * {{cite web|url=https://blogs.technet.com/b/srd/archive/2009/02/02/preventing-the-exploitation-of-seh-overwrites-with-sehop.aspx|title=Preventing the Exploitation of Structured Exception Handler (SEH) Overwrites with SEHOP|author=Matt Miller|publisher=Technet|date=2 Feb 2009}} * {{cite web|title=Bypassing SEHOP|url=http://www.sysdream.com/sites/default/files/sehop_en.pdf|author=Stéfan Le Berre, Damien Cauquil|publisher=Sysdream|date=22 Dec 2009|url-status=dead|archive-url=https://web.archive.org/web/20120907022250/http://www.sysdream.com/sites/default/files/sehop_en.pdf|archive-date=2012-09-07}} * {{cite web|url=https://www.optiv.com/blog/old-meets-new-microsoft-windows-safeseh-incompatibility/|title=Old Meets New: Microsoft Windows SafeSEH Incompatibility|author=Joshua J. Drake|date=10 Jan 2012|access-date=9 January 2017|archive-date=9 January 2017|archive-url=https://web.archive.org/web/20170109184752/https://www.optiv.com/blog/old-meets-new-microsoft-windows-safeseh-incompatibility|url-status=dead}} An article explaining why Windows 7 SP1 ignores SafeSEH for some older binaries, while Windows XP SP3 honors it.
Category:Control flow Category:Microsoft application programming interfaces