Content deleted Content added
m →{{Anchor|SEH}}Structured Exception Handling: WP:CHECKWIKI error fixes using AWB (12057) |
Citation bot (talk | contribs) Added date. | Use this bot. Report bugs. | Suggested by Whoop whoop pull up | Category:Microsoft application programming interfaces | #UCB_Category 120/133 |
||
(36 intermediate revisions by 24 users not shown) | |||
Line 1:
The [[Microsoft Windows]]
== {{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|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) |
=== 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=
=== Implementation ===
Each [[Thread (computing)|thread of execution]] in Windows has a link to an undocumented _EXCEPTION_REGISTRATION_RECORD [[List (computing)|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 _EXCEPTION_REGISTRATION_RECORD [[Stack-based memory allocation|on the stack]] pointing to <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 (programming)|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 expansion|inline]]. All the programmer-defined <code>__except</code> and <code>__finally</code> blocks are called from within <code>__except_handler3</code>. If such blocks are present, _EXCEPTION_REGISTRATION_RECORD being created 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|date=February 2009|accessdate=2009-11-21}}, ''Compiler based Structured Exception Handling'' section</ref>▼
==== IA-32 ====
In a case of an exception in a [[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 _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 [http://msdn.microsoft.com/en-us/library/ms680548%28VS.85%29.aspx error mode]; the default last handler can be replaced with [http://msdn.microsoft.com/en-us/library/ms680634(VS.85).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.▼
▲Each [[Thread (computing)|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 (computing)|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}} [[Stack-based memory allocation|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 (programming)|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 expansion|inline]]. All the programmer-defined <code>__except</code> and <code>__finally</code> blocks are called from within <code>__except_handler3</code>. If
▲In
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 [[Call stack#Unwinding|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=
Compared with SEH, VEH works more like
== Notes ==
Line 26 ⟶ 35:
==External links==
* {{cite web |url=
* {{cite journal |author=
* {{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=
* {{cite web |url=
* {{cite web|url=
* {{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=
[[Category:Control flow]]
|