Win32API 例外ハンドラ SetUnhandledExceptionFilter

SetUnhandledExceptionFilter関数で例外ハンドラを登録しておくと、プログラムでAccessViolationなどの例外が発生したときに、登録した例外ハンドラが呼び出される。




使用例
main関数の最初に、SetUnhandledExceptionFilterで例外ハンドラを登録する。その直後に、strcpyでAccessViolationを発生させる。ここで、登録された例外ハンドラが呼び出される。例外ハンドラであるTopLevelExceptionFilter関数は、引数で渡されてくる例外に関する情報をメッセージボックスで表示する。

#include <windows.h>
#include <stdio.h>
#include <strsafe.h>
#include <string.h>

LONG WINAPI TopLevelExceptionFilter(struct _EXCEPTION_POINTERS *ExceptionInfo)
{
    TCHAR szText[1024] =  {TEXT('\0')};

    StringCchPrintf(szText,
        sizeof(szText)/sizeof(szText[0]),
        TEXT("ExceptionAddress=%X, ExceptionCode=%X, ExceptionFlags=%X, ExceptionInformation=%X, NumberParameters=%X"),
        ExceptionInfo->ExceptionRecord->ExceptionAddress,
        ExceptionInfo->ExceptionRecord->ExceptionCode,
        ExceptionInfo->ExceptionRecord->ExceptionFlags,
        ExceptionInfo->ExceptionRecord->ExceptionInformation,
        ExceptionInfo->ExceptionRecord->NumberParameters);

    MessageBox(NULL, szText, TEXT("ExceptionFilter"), MB_OK);
    
    return 0;
}

int main()
{
    SetUnhandledExceptionFilter(TopLevelExceptionFilter);
    
    strcpy(NULL, NULL);

    return 0;
}



実際には、デバッグ中にクラッシュさせても例外ハンドラは呼び出されない。このソースコードをビルドして生成された実行ファイルを実行すると例外ハンドラが呼び出されて、メッセージボックスが起動して例外に関する情報が表示される。

メッセージボックスを閉じると、「xxxxx.exeの動作は停止しました」というメッセージボックスが起動し、プログラムが終了する。



参考
http://msdn.microsoft.com/ja-jp/library/cc428992.aspx