5

I am reading about Structured Exception Handling in C. Here is an example code which does not work as expected:

This code is taken from here:

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;
}

This code should print the message, "Hello from my_handler" when the exception is triggered by trying to write to an invalid memory address. However, it appears that the exception handler is not called at all.

I compiled this code and tried debugging it with Olly Debugger. When the exception occurs, I try passing the exception to the application defined exception handler (by pressing, Shift + F9) but it does not get called. I set a breakpoint at the exception handler (first instruction), but it never reaches that section of code.

What might be the reason for this?

4

1 回答 1

2

我面临着同样的问题。它不起作用的原因是 my_handler 在链接时被编译器阻塞。我们需要告诉编译器 my_handler 是安全的,或者完全禁用安全检查。因此,有两种方法可以使其工作。(在 MSVC 2008 和 2010 上都试过)

  • 通过在链接时添加 /safeseh:no 来禁用 safeseh 表。

    cl /c C4733.cpp
    link /safeseh:no C4733.obj 
    
  • 创建一个 masm 文件以将 my_handler 添加到 SEH 表中。但是MSN 上的 SAFESEH 示例在我的笔记本电脑上不起作用。我在 stackoverflow 上找到了这个解决方案来代替: Custom SEH handler with /SAFESEH。但是我们必须创建一个额外的 MASM 过程来跳转到外部 C 函数。

于 2013-12-03T06:19:50.557 回答