Microsoft Windowsファミリーのオペレーティングシステムは、いくつかの特定の例外処理メカニズムを採用しています。
Microsoft Structured Exception Handling は、Windows のネイティブ例外処理メカニズムであり、Vectored Exception Handling (VEH) の先駆けとなる技術です。[ 1 ]標準 C++ 例外には存在しないメカニズム (ただし、後に導入されたほとんどの命令型finally言語には存在する)を備えています。SEH は、実行スレッドごとに個別に設定および処理されます。
Microsoft は、SEH をコンパイラ レベルでのみプログラミング テクニックとしてサポートしています。MS Visual C++ コンパイラには、この目的のために 、、および という 3 つの非標準キーワードがあります__try。__exceptその他の例外処理の側面は、たとえばSEH 例外を手動で発生させるためのWin32 API関数[ 2 ]__finallyによってサポートされています。RaiseException
int filterExpression ( EXCEPTION_POINTERS * ep ) { ep -> ContextRecord -> Eip += 8 ; // 除算命令は 2 バイトから 8 バイトでエンコードされる可能性がありますreturn EXCEPTION_CONTINUE_EXECUTION ; }int main ( void ) { static int zero = 0 ; __try { zero = 1 / zero ; asm { nop nop nop nop nop nop nop } printf ( "例外処理が完了しました。\n " ); } __except ( filterExpression ( GetExceptionInformation ())) { printf ( "ハンドラが呼び出されました。\n " ) ; } return 0 ; }Windows IA-32エディションの各実行スレッド、またはx86-64バージョンのWoW64エミュレーション レイヤーには、スレッド情報ブロックの先頭に、ドキュメント化されていない_EXCEPTION_REGISTRATION_RECORDリストへのリンクがあります。このステートメントは基本的にコンパイラ定義関数を呼び出します。この関数は、スタック上に[ a ]関数を指す_EXCEPTION_REGISTRATION_RECORDを割り当て、[ b ]レコードをリストの先頭に追加します。ブロックの最後に、逆の操作を行うコンパイラ定義関数が呼び出されます。これらのコンパイラ定義ルーチンはどちらもインライン化できます。プログラマ定義のブロックとブロックはすべて、内部から呼び出されます。プログラマ定義ブロックが存在する場合、によって作成された_EXCEPTION_REGISTRATION_RECORDは、によって使用されるいくつかの追加フィールドで拡張されます。[ 3 ]__tryEH_prolog__except_handler3msvcrt.dll__tryEH_epilog__except__finally__except_handler3EH_prolog__except_handler3
ユーザーモードコードで例外が発生した場合、オペレーティングシステム[ c ]はスレッドの_EXCEPTION_REGISTRATION_RECORDリストを解析し、例外ハンドラが例外を処理したことを通知するか (戻り値によって)、リストが尽きるまで、各例外ハンドラを順番に呼び出します。リストの最後のハンドラは常に、一般保護違反エラー メッセージを表示します。[ d ]その後、リストがもう一度走査され、ハンドラが使用済みのリソースをクリーンアップする機会が与えられます。最後に、実行はカーネル モードに戻り[ e ]、そこでプロセスが再開されるか終了します。kernel32!UnhandledExceptionFilter
このSEH方式に関する特許(US5628016)は2014年に失効した。
64 ビット Windows の SEH では、実行時例外ハンドラ リストは使用されません。代わりに、例外が発生したときにシステムによって解釈されるスタック アンワインディングテーブル ( ) を使用します。 [ 4 ] [ 5 ] これは、コンパイラがスタック アンワインディングを手動で実行し、例外ハンドラを適切に呼び出すための追加コードを生成する必要がないことを意味します。スタック フレーム レイアウトと指定された例外ハンドラに関する情報をアンワインディング テーブル形式で出力するだけで済みます。UNWIND_INFO
Mingw-w64の GCC 4.8+ は、C++ 例外に 64 ビット SEH を使用することをサポートしています。LLVM clang は x86 と x64 の両方でサポートしています__try。[ 6 ]
ベクタ例外処理はWindows XPで導入されました。[ 7 ]ベクタ例外処理は、 C++やVisual Basicなどの言語を使用する Windows プログラマーが利用できます。VEH は構造化例外処理 (SEH) を置き換えるものではなく、VEH と SEH は共存し、VEH ハンドラが SEH ハンドラよりも優先されます。[ 1 ] [ 7 ] SEH と比較すると、VEH はカーネルによって配信されるUnix シグナルに似ています。[ 8 ]
ntdll.dllおよびkernel32.dll、ならびに VC ランタイムと静的にリンクされた他のプログラムでは、代わりにこの関数がコンパイルされます。ntdll!RtlDispatchExceptionれるシステムルーチン。(ケン・ジョンソン(2007年11月16日)「NTDLLカーネルモードからユーザーモードへのコールバックのカタログ、パート2:KiUserExceptionDispatcher」を参照) 。ntdll!KiUserExceptionDispatchernt!KiDispatchException詳細はntdll!KiUserExceptionDispatcherどちらかを呼び出すnt!ZwContinueかnt!ZwRaiseException/link /safeseh:no。