【问题标题】:Exception Handler not called in C未在 C 中调用异常处理程序
【发布时间】:2013-11-01 07:08:53
【问题描述】:

我正在阅读 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),但它没有被调用。我在异常处理程序(第一条指令)处设置了一个断点,但它从未到达那段代码。

这可能是什么原因?

【问题讨论】:

  • 看起来这是一个编译器警告,而不是运行时错误检查。我没有窗户,所以无法检查..
  • 您是否尝试过使用/ZI /MTd 编译器选项编译您的代码?这样,我得到了预期的结果。

标签: c exception seh


【解决方案1】:

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

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

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

【讨论】:

  • 你绝对需要那个 MASM 文件吗?你不能只使用内联汇编添加那个汇编代码吗?
  • @Calmarius 我怀疑内联是否有效。有一个-safeseh 参数传递给ml.exe,cl.exe 不支持该参数。仅供参考,我使用以下方法编译了 asm:ml.exe -Fo my.obj -c -safeseh my.asm
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 2014-09-10
相关资源
最近更新 更多