Windowsの例外処理メカニズムの概要

Windowsシステム、強力かつ安定したユーザプログラムが例外に対処するため、プログラマやシステム担当者を支援するための例外処理メカニズムを提供し確保するために、強力かつ安定したシステムのコアを確保するためです。CPUは、コード例外が発生した実行時に、例外がオペレーティングシステムに通知します簡単に言えば、オペレーティングシステムの最初のプログラム自体が例外を処理する、プログラム自体が能力(プログラムに登録を例外ハンドラをしている)が、プログラムは継続します実行します。プログラム自体が(例外ハンドラがプログラムに登録されていない)、この例外がまだ処理されていない扱うことができないが、オペレーティングシステムは、ユーザーがデバッグにデバッガを呼び出すか、プログラムを終了するように指示さに対処する必要があります。あなたが参加して、デバッガを使用している場合は、プログラムが異常である、オペレーティングシステムは、プログラム自体の権利が、デバッガに例外を処理しません、デバッガは右のプログラムへのハンドルを回すために続けることができ、あなたはまた、独自に対処することができます。フロントで話すのプロセスを完了するためには、Windwos情報は、機構SEHとVEH 2トリートメントを提供しています。以下は簡単です。
、SEHの例外処理メカニズム

SEHは、最終的な実装にキーワード__、__除いて、プログラムのソースコードに__try使用し、構造化例外処理と呼ばれるシステムの例外処理メカニズムを、Windowsオペレーティングあります。

Windowsオペレーティングシステム(以降Windows95のから)、各ユーザスレッドは、異常なイベントを処理するための例外処理フレームのリンクリストを設定しています。二つの部材、即ち、リスト上のアドレス、例外ハンドラの現在のアドレス、構造_EXCEPTION_REGISTRATION_RECORDの組成物による例外ハンドラリストの各フレーム。例外ハンドラは、処理の例外コールバック関数(コールバック関数)を意味します。初めにスレッド情報ブロック(スレッド情報ブロック)(すなわち、FS:[0]メモリで、FSは、CPUのセグメントレジスタである)ヘッド・テーブル・エントリ例外処理フレームリストのアドレスを含みます。[0]リンクリストの先頭にポイントが一つの例外ハンドラのコールバック関数が0を返すまで、各ノードは、例外ハンドラのコールバック関数が含まれて呼び出します:異常なイベントは、FSからのオペレーティングシステムのRtlDispatchException機能中断され、プログラムの実行中に遭遇しましたこれは、スレッドが実行を再開することができ、それが例外を処理していたと述べました。最後のものは、常にユーザーに「アプリケーションエラー」ダイアログを示しスレッド!UnhandledExceptionFilter関数をロードするときに、オペレーティングシステムの設定をKERNEL32するために、リストのポイントです。そして、異常プロセッサプログラムリストは、ユーザプログラム自体がインストールされています。プログラムのコールスタック(コールスタック)に保存されている各ノードリスト。Windowsの例外処理メカニズムはそれは例外が例外処理コールバック関数の実装で再び発生している、ネストされた例外処理をサポートしています。この場合は、まだ一般的な例外処理メカニズムに準拠し、オペレーティングシステムRtlDispatchException機能の再突入プロセスネストされた例外は、新興。ネストされた例外ハンドラは、例外が実行時に発生した新しい例外フレームをDispatcherContext得られたパラメータ値のアドレスです。
Windowsの例外処理メカニズムに基づいて、様々なプログラミング言語は、自分の例外処理文の制御構造を設計しました。マイクロソフトは、C言語の構文を拡張し、トライを除くのtry-finally文で構造化例外処理を設計しました。で機能してみてください-以外のtry-最後に林(データ構造)上に形成さ備える(囲む)関係を持つすべての機能。入口で、最後に機能__try文は、存在する場合、すべての包ま保護された関数内のコードのtryブロックでは、コンパイラとEH_epilog EH_prologコードに挿入されています。EH_prologは、Visual C ++の機能__except_handler4ランタイムライブラリMSVCRT.DLLのアドレスを含む新しいヘッダの例外処理リストとして、コールスタック上の_EXCEPTION_REGISTRATION_RECORDを作成します。機能ブロックの最後で、EH_epilog _EXCEPTION_REGISTRATION_RECORDは元のヘッダを復元し、リストの先頭から除去されます。例外処理コールバックMSVCR100Dのリストに掛かっによって__except声明フィルタ式!__実行を呼び出すためのexcept_handler4、戻り値は、フィルタ式がと評価されています。実際には、各リンクリストのデータ構造は、2つの拡張部材5人のメンバーで構成されている場合、コンパイラ実装構造例外、すなわち、ポインタを上位アドレスにおける構造のscopetable_entries型配列を付加され、整数実行用語表しますこれEBPの格納されたエントリレジスタ整数、関数の現在位置のブロックを試みます。その後(下位アドレス)(即ち、真性GetExceptionInformation関数はポインタ値を返す)ポインタEXCEPTION_POINTERS構造が続いています。
例外が発生した場合、FSからオペレーティングシステムRtlDispatchException機能のNTDLL例外処理機構:! [0]次に、リスト・ヘッダを指し、このコールバックによれば、except_handler4 __ MSVCR100Dに含まれる各ノード例外フレームにリンクされたリストの例外ハンドラコールバック関数を呼び出します!異常が処理されたかどうかを決定するために、戻り値、スレッドは実行コンテキスト異常(例外コンテキスト)を再開することができます。__except_handler4コールバック関数は、実際にはMSVCR100Dを呼んでいる!__ except_handler4_common機能。__except_handler4_common機能は、実際の主力である例外を処理することができ、現在の例外フレーム(すなわち、フィルタ式が1に評価される)の機能にexcept文のtry-見つけるための責任があります。このようのtry-除くブロックが存在しない場合は、__ except_handler4_common機能はExceptionContinueExecutionを返す(0)、リスト内の例外フレームRtlDispatchExceptionに次のノードにアクセスし続けます。現在のtry-除くブロックの異常、__ except_handler4_common機能を処理することが判明した場合最初にあなたがスタックを行うには、次の層の機能機能の現在の例外に対処できるようになるまで、関数は、リストのフレームヘッダから異常である_EH4_GlobalUnwind、グローバル展開の関数を呼び出します(巻き戻し)を展開し、次に、関数はこの例外にtry-除くブロックの例外を処理するまで実行ポイント__try文を含むほとんどのメモリを扱うことができ、関数呼び出しが部分的に_EH4_LocalUnwindを展開し、例外を処理するために行わもう一度お試しください-except例外処理のコードブロックは、最後に、コードは他のトライを除いた後、続けています。グローバル展開、_EH4_GlobalUnwindによってNTDLL呼び出します!RtlUnwind、RtlUnwindリストトラバーサル訪問フレームから対象フレームヘッダ(なし)例外コードを持つすべての例外ハンドラコールバック(STATUS_UNWINDすなわち0C0000027H)、異常フラグ(EXCEPTION_UNWINDINGすなわち値2)呼び出しに例外フレーム、。実行ポイントから例外ハンドラ・コールバック・コードと電流異常異常フラグ、現在のフレームの異常な機能は、tryブロック内の最も外側の機能まで、順次コールが試して、最も内側の__try文が始まる異常を発生させることを含みます - 最後のクリーンアップ目的コード。このステップは、実際に完了するために、機能を_EH4_LocalUnwindと呼ばれています。
部分的に展開、実行ポイント__try文生成開始異常を含むまで押すの関係を備えた最内層から、_EH4_LocalUnwind機能によって実装のtry-除く特定のステートメント、呼び出し元のコードは、連続してのtry-ようやくのクリーニング外側にまでコードを使用します。

第二に、量子化例外がWin32での取り扱い

(VEH)を取り扱うベクタ例外は、64ビットのWindowsがこの機能をサポートしていないので、それは、Win32であることを強調するためにWindows XP、なぜベクトル化例外で導入された構造化例外処理の拡張です。特性を理解するか、オペレーティング・システムは、上記の配列異常がデバッガに最初に処理し、その後、ユーザプログラムで処理する前に言って戻り、例外が処理されている値は、フィルタ式がに従い返すか否かを判断し、このベクタ例外処理、例外処理は、この前にコードを追加することで、そのコードは、フィルタ式の前に最初に実行されるであろう。私たちは、それが外側の層に、内側から層によって異常層を見て知っている、プロセスが完了した場合には、内側層は、その後、外側の層はチャンスプロセスを持っていることはありません、この場合には、我々はアプリケーションを開発するサードパーティ製のライブラリを使用しており、このないソースコードライブラリを提供し、例外が発生した場合、ライブラリは、単純にスレッドを終了し、我々はこの異常に対処したいのですが、内部処理のために、外側のtryは、単にあなたがベクトル化例外を使用することができ、この時間をキャッチしていませんそれは扱っ。私たちは、例外処理コード最初の処理を記述し、ライブラリは、この異常に対処する機会を持っていないので、継続して戻ります。

あなたが使用することができますAddVectoredExceptionHandlerを()関数は、欠点は、それが唯一のVEHことなので、WinXPの以降のバージョンでは、実行時に確認することができるということです、ベクトル化例外ハンドラを追加しますAddVectoredExceptionHandler()関数が存在します。

以前に使用することができますインストールされている例外ハンドラ削除するにはRemoveVectoredExceptionHandler()関数を。

VEHは、すべての例外に表示または処理アプリケーションを可能にします。それは便利なSEHプロセッサを見つけるまで、プログラムの一部が順番に場所SEH例外システムを取るとき、下位互換性を維持するために、VEHプロセッサがインストールされて呼び出します。

一つの利点は、VEH例外ハンドラ(チェーン例外ハンドラ)をリンクするための機能ですので、誰かが例外プロセッサをベクトル化されている場合は、インストールする前に、あなたはまだこれらの異常をキャプチャすることができます。

あなたはすべての例外のスーパーバイザーとして、デバッガのようなものが必要な場合は、VEHが適切である使用。問題は、例外、スキップする必要のある例外を処理する必要があるかを決定する必要があるということです。プログラムのコードでは、いくつかの例外が意図的に__try {} __除く(){}建設に守られ、フレームベースのSEHハンドラに渡すVEHで、このような例外を処理していないことも、アプリケーション・ロジックにバグを導入することができます。

VEHは、現在CrashRptで使用されていません。SetUnhandledExceptionFilterは、それが最上位レベルのSEHプロセッサであるため()、より適用可能です。例外処理が存在しない場合は、トップレベルのSEHハンドラが呼び出され、あなたは例外を処理するかどうかを決定する必要はありません。

おすすめ

転載: www.cnblogs.com/yilang/p/11226218.html