5

C の構造化例外処理について読んでいます。期待どおりに動作しないサンプル コードを次に示します。

このコードは次の場所から取得されます。

http://msdn.microsoft.com/en-us/library/ha52ak6a.aspx

// C4733.cpp
// compile with: /W1 /c
// processor: x86
#include "stdlib.h"
#include "stdio.h"
void my_handler()
{
   printf("Hello from my_handler\n");
   exit(1);
}

int main()
{
   _asm {
      push    my_handler
      mov     eax, DWORD PTR fs:0
      push    eax
      mov     DWORD PTR fs:0, esp   // C4733
   }

   *(int*)0 = 0;
}

このコードは、無効なメモリ アドレスに書き込もうとして例外がトリガーされたときに、「Hello from my_handler」というメッセージを出力する必要があります。ただし、例外ハンドラはまったく呼び出されていないようです。

このコードをコンパイルし、Olly Debugger でデバッグしてみました。例外が発生すると、アプリケーションで定義された例外ハンドラーに例外を渡そうとしますが (Shift + F9 キーを押して)、呼び出されません。例外ハンドラ (最初の命令) にブレークポイントを設定しましたが、コードのそのセクションに到達しません。

この理由は何でしょうか?

4

1 に答える 1

2

私は同じ問題に直面していました。これが機能しない理由は、リンク時に my_handler がコンパイラによってブロックされるためです。my_handler が安全であることをコンパイラに伝えるか、安全性チェックを完全に無効にする必要があります。したがって、それを機能させるには2つの方法があります。(MSVC 2008 と 2010 の両方で試しました)

  • リンク時に /safeseh:no を追加して、safeseh テーブルを無効にします。

    cl /c C4733.cpp
    link /safeseh:no C4733.obj 
    
  • my_handler を SEH テーブルに追加するための masm ファイルを作成します。しかし、MSN の SAFESEH の例は、私のラップトップでは機能しませんでした。代わりに、stackoverflow でこのソリューションが機能することがわかりました: Custom SEH handler with /SAFESEH。ただし、外部 C 関数にジャンプするには、追加の MASM プロシージャを作成する必要があります。

于 2013-12-03T06:19:50.557 に答える