f:id:clayfish:20080127145911p:image:right
前回の続き。

次は ACCESS VIOLATION をつかまえてみようかと思います。google で検索したり, msdn を検索したりした結果、ソースコードはこんなかんじになりました。

#include <windows.h>
#include <tchar.h>
int
main(int argc, char *argv[])
{
  int *p = 0;

  OutputDebugString(_T("1\n"));
  __try {
    OutputDebugString(_T("try 1\n"));
    *p = 1;
    OutputDebugString(_T("try 2\n"));
  }
  __except(EXCEPTION_EXECUTE_HANDLER) {
    OutputDebugString(_T("do your handler\n"));
  }
  OutputDebugString(_T("2\n"));

  return 0;
}

実行するとデバッガの出力ウィンドウに以下のように表示されるはずです。

1
try 1
null_access.exe の 0x00411421 で初回の例外が発生しました: 0xC0000005: 場所 0x00000000 に書き込み中にアクセス違反が発生しました。
do your handler
2

上記のソースコードと実行結果からわかることは、

  • ACCESS VIOLATION のダイアログが表示されなくなった
  • ACCESS VIOLATION したことをつかまえるには、ACCESS VIOLATION する可能性のあるソースを「__try」ブロックでかこむと良さそうだ
  • 実際に ACCESS VIOLATION すると「__except」ブロックが実行されるぽい

上記のソースコードの場合、__except の括弧内で EXCEPTION_EXECUTE_HANDLER を指定することにより __except につづくブロックが実行されるように指定しています。
なお、他にも __except の括弧内に指定できる値があるので以下にまとめます。

EXCEPTION_CONTINUE_EXECUTION
例外が発生した箇所から再実行。上記ソースコードの EXCEPTION_EXECUTE_HANDLER を EXCEPTION_CONTINUE_EXECUTION に置き換えると無限ループします。(ACCESS VIOLATION 発生→補足→再実行→...を繰り返します)
EXCEPTION_CONTINUE_SEARCH
外側の __try ブロックに処理委譲。上記ソースコードの EXCEPTION_EXECUTE_HANDLER を EXCEPTION_CONTINUE_SEARCH に置き換えるとやっぱり ACCESS VIOLATION のダイアログが表示されます。(同じ例外が再度発生するイメージです。)
EXCEPTION_EXECUTE_HANDLER
発生した例外を自分で処理する

ここまでで目的の「ACCESS VIOLATION をつかまえてごにょごにょ」するための準備がととのったので、次は実際にごにょごにょしてみたいと思います。