Windows異常処理_try __except

3393 ワード

__try __Exceptはwindowsシステム独自の異常処理モデルであり、windowsの異常処理モードはSEH(structured exception handling)と呼ばれ、SEHの異常処理モデルは主にtry-except文で完成し、標準的なtry catchと似ている.C++例外処理モデルはcatchキーを使用して例外処理モジュールを定義し、SEHは_Exceptキーワードで定義します.また、catchキーワードの後ろには、関数パラメータを受け入れるように、さまざまなタイプの異常データオブジェクトであってもよい.でも_Exceptキーワードは異なり、後に続くのは式です.関数呼び出しも式であることを知っています.SEHには、実際には2つの主要な機能があります.終了処理(termination handling)と例外処理(exception handling)は、tryブロックを作成するたびにfinallyブロックまたはexceptブロックに従う必要があります.1つのtryブロックの後にfinallyブロックとexceptブロックがあることはできません.ただし、try-exceptブロックにtry-finallyブロックをネストしてもよいし、逆にしてもよい.Exceptパラメータの値は、EXCEPTION_の3つです.CONTINUE_EXECUTION(-1)異常は無視され、制御フローは異常が発生した点以降、運転を再開します.EXCEPTION_CONTINUE_SEARCH(0)異常は認識されない、すなわち現在のこの_Exceptモジュールは、この異常エラーに対応する正しい異常処理モジュールではありません.システムは、前の階層のtry-exceptドメインで適切な_を検索し続けます.Exceptモジュール.EXCEPTION_EXECUTE_HANDLER(1)異常が認識されている、すなわち現在のこの異常エラーは、システムが見つけて確認できる、この_Exceptモジュールは正しい異常処理モジュールです.制御フローが__に入るExceptモジュールにあります.try-exceptのポイントは_Exceptモジュールで異常エラーに関する情報を取得し、Windowsでは2つのAPI関数を提供して異常情報を取得します:LPEXCEPTION_POINTERS GetExceptionInformation(VOID);//異常関連情報の取得
DWORD GetExceptionCode(VOID);//異常番号を取得
EXCEPTION_POINTERS構造は以下の通りである.
typedef struct _EXCEPTION_POINTERS { // exp 
PEXCEPTION_RECORD ExceptionRecord; 
PCONTEXT ContextRecord; 
} EXCEPTION_POINTERS;
EXCEPTION_異常に関連する情報を記録したRECORDタイプ.一方,CONTEXTデータ構造体には異常発生時のスレッド当時のコンテキスト環境が記録されており,主にレジスタの値を含む.これらの情報があって、_Exceptモジュールは異常エラーをよく分類して復元することができ、通常はフィルタ関数が必要です.一般にfilterfunctionと呼ばれ、フィルタ関数は処理する必要がある異常だけをフィルタします.
int exception_access_violation_filter(LPEXCEPTION_POINTERS p_exinfo)
{
    if(p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_ACCESS_VIOLATION)
    {
        messagebox("access vialation exceptionn");
       return EXCEPTION_EXECUTE_HANDLER ; //  except      
    }
    else return EXCEPTION_CONTINUE_SEARCH; //   except      
}

int exception_int_divide_by_zero_filter(LPEXCEPTION_POINTERS p_exinfo)
{
    if(p_exinfo->ExceptionRecord->ExceptionCode == EXCEPTION_INT_DIVIDE_BY_ZERO)
    {
        return  EXCEPTION_EXECUTE_HANDLER; //  except      
    }
   else return EXCEPTION_CONTINUE_SEARCH; //   except      
}
で、この例外処理コードを書くことができます.
__try
{
  // guarded code
}

__except(exception_access_violation_filter(GetExceptionInformation()))
{
//
}

__try
{
  // guarded code
}
__exceptexception_int_divide_by_zero_filter(GetExceptionInformation()))
{
//exception handling
}
SEH異常処理モデルでは、1つの異常を放出してもよい.対応するWindowsAPI関数はRaiseException、
VOID RaiseException(
DWORD dwExceptionCode,//異常の番号
DWORD dwExceptionFlags,//異常フラグ
DWORD nNumberOfArguments,//パラメータ個数
CONST DWORD*lpArguments//パラメータ配列ヘッダアドレス
);
通常、後の3つのパラメータは基本的に使用されません.
SEH異常処理にはtry-finallyもありますが、SEHのtryはexceptとfinallyの2つの組み合わせしかなく、try-except-finalyはありません.
C++異常モデルはtry-catch構文で定義され、SEH異常モデルはtry-except構文でC++異常モデルと類似しており、try-exceptも多層try-exceptネストをサポートしている.
try-exceptモデルでは、1つのtryブロックは1つのexceptブロックしかありません.一方,C++異常モデルでは,1つのtryブロックに複数のcatchブロックを持つことができる.
C++異常モデルは、異常オブジェクトのタイプに応じてマッチング検索を行う.一方try-exceptモデルは異なり、1つの式の値で判断されます.
__Exceptキーワードの後に続く式は、関数呼び出しや条件式、カンマ式、いっそ整数定数など、さまざまなタイプの式であってもよい.
最も一般的な関数式であり、GetExceptionCode()またはGetExceptionInformation()関数を使用して現在の異常エラー情報を取得することで、プログラマが異常エラーの分類処理を効率的に制御できます.
SEH異常処理モデルでは,異常はRaiseException()関数により投げ出される.RaiseException()関数の役割は、C++例外モデルのthrowに似ています.