フレームベースの例外処理

フレームベースの例外ハンドラーを使用すると、特定のコード シーケンスで例外が発生する可能性を処理できます。 フレーム ベースの例外ハンドラーは、次の要素で構成されます。

  • コードの保護された本文
  • フィルター式
  • 例外ハンドラー ブロック

フレーム ベースの例外ハンドラーは、言語固有の構文で宣言されます。 たとえば、Microsoft C/C++ 最適化コンパイラでは、__try__except を使用して実装されます。 詳細については、「ハンドラー構文」を参照してください。

コードの保護された本文は、フィルター式と例外ハンドラー ブロックが例外処理保護を提供する 1 つ以上のステートメントのセットです。 保護された本文には、コードのブロック、入れ子になったブロックのセット、またはプロシージャまたは関数全体を指定できます。 Microsoft C/C++ 最適化コンパイラを使用すると、保護された本文は、__try キーワードの後に中かっこ ({}) で囲まれます。

フレーム ベースの例外ハンドラーのフィルター式は、保護された本文内で例外が発生したときにシステムによって評価される式です。 この評価により、システムによって次のいずれかのアクションが実行されます。

  • システムは例外ハンドラーの検索を停止し、マシンの状態を復元し、例外が発生した時点からスレッドの実行を継続します。
  • システムは、例外ハンドラーの検索を続行します。
  • システムは制御を例外ハンドラーに移し、スレッドの実行は例外ハンドラーが見つかったスタック フレーム内で順次続行されます。 例外が発生したスタック フレームにハンドラが存在しない場合、システムはスタックを巻き戻し、例外ハンドラのスタック フレームに戻るまで現在のスタック フレームと他のスタック フレームを残します。 例外ハンドラーが実行される前に、例外ハンドラーへの制御の移行の結果として終了した、保護されたコード本体に対して終了ハンドラーが実行されます。 終了ハンドラーの詳細については、「終了処理」を参照してください。

フィルター式は単純な式にすることも、例外の処理を試みるフィルター関数を呼び出すこともできます。 フィルター式内から GetExceptionCode 関数と GetExceptionInformation 関数を呼び出して、フィルター処理されている例外に関する情報を取得できます。 GetExceptionCode は例外の種類を識別するコードを返し、GetExceptionInformationCONTEXT 構造体と EXCEPTION_RECORD 構造体へのポインターを含む EXCEPTION_POINTERS 構造体へのポインターを返します。

これらの関数はフィルター関数内から呼び出すことはできませんが、戻り値はパラメーターとしてフィルター関数に渡すことができます。 GetExceptionCode は例外ハンドラー ブロック内で使用できますが、GetExceptionInformation が指す情報は通常スタック上にあり、コントロールが例外ハンドラーに転送されると破棄されるため、使用できません。 ただし、アプリケーションは、情報を安全なストレージにコピーして、例外ハンドラーで使用できるようにすることができます。

フィルター関数の利点は、例外を処理し、例外が発生した時点からシステムに実行を継続させる値を返すことができることです。 対照的に、例外ハンドラー ブロックでは、実行は例外の時点からではなく、例外ハンドラーから順次続行されます。

例外の処理は、エラーに注目して後で検査されるフラグを設定する、警告またはエラー メッセージを出力する、またはその他の限定されたアクションを実行するなど、簡単な場合があります。 実行を継続できる場合は、コンテキスト レコードを変更してマシンの状態を変更する必要がある場合もあります。 ページ フォールト例外を処理するフィルター関数の例については、「仮想メモリ関数の使用」を参照してください。

UnhandledExceptionFilter 関数は、フィルター式のフィルター関数として使用できます。 プロセスがデバッグされていない場合は EXCEPTION_EXECUTE_HANDLER を返し、デバッグ中の場合は EXCEPTION_CONTINUE_SEARCH を返します。