Home / Win32例外のおさらい

Win32例外のおさらい

書きかけ...と言うより書き残し orz


←Advanced Windows 等で詳しく述べられているが、自分が勘違いしていたのでおさらい。

__finally ブロック中の return

Advanced Windows ではこれをグローバルアンワインドの中止と称し、グローバルアンワインドを途中で終了させることが出来る、とある。

void f1()
{
    __try 
    {
        ::OutputDebugString("call f2().\n");
        f2();                                     // 1.
    }
    __except (EXCEPTION_EXECUTE_HANDLER)          // 4.
    {
        ::OutputDebugString("f1() except handler.\n");
    }

    ::OutputDebugString("f1() Leave.\n");         // 8.
}

void f2()
{
    __try
    {
        ::OutputDebugString("f2() __try.\n");
        f3();                                     // 2.
    }
    __finally
    {
        ::OutputDebugString("f2() __finally.\n"); // 7.
    }

    ::OutputDebugString("f2() Leave.\n");         // 
}

void f3()
{
    __try
    {
        ::OutputDebugString("f3() __try.\n");
        strcpy(0,0);                              // 3.
    }
    __finally
    {
        ::OutputDebugString("f3() __finally.\n"); // 5.
        return;                                   // 6.
    }

    ::OutputDebugString("f3() Leave.\n");         // 
}

となり、例外ハンドラが実行される前に f2() の finally ブロックが実行される。
これがグローバル アンワインドと呼ばれるもので、finally ブロックを処理してから例外ハンドラを実行する(finally ブロックが有れば)。

f1() の例外ブロックが実行されなくなった!

call f2().      ... #1
f2() __try.     ... #5
f3() __try.     ... #8
f3() __finally. ... #9
f2() __finally. ... #6
f2() Leave.     ... #7
f1() Leave.     ... #4
例外処理 (初回) は xxx.exe にあります: 0xC0000005: Access Violation。

もし、f3 の __finally 中の return が無ければ、

call f2().      ... #1
f2() __try.     ... #5
f3() __try.     ... #8
f3() __finally. ... #9
f2() __finally. ... #6
f1() exec handler.
f1() Leave.     ... #4
例外処理 (初回) は xxx.exe にあります: 0xC0000005: Access Violation。

望み通り、例外が起きた後は __finally ブロックを呼び出して例外ハンドラへ進む。


Home / Win32例外のおさらい
http://usskim.web.fc2.com/
inserted by FC2 system