结构化异常处理程序(SEH)不会捕获堆损坏

时间:2011-12-07 06:23:35

标签: c++ exception-handling heap-corruption seh structured-exception

我正在编写使用第三方库执行一项简单任务(光栅化)的小实用程序(VC 2010,无clr)。以后的实用程序将被更大的应用程序使用有时,实用程序因第三方库中的某些堆损坏而崩溃。没关系,但Windows(Vista / 2008)显示了众所周知的对话框“程序已停止工作...关闭/调试程序。”这在我的情况下是不合适的(服务器端)。实用程序应该静默崩溃/终止没有任何可见效果。

为此,我为未处理的异常(SetUnhandledExceptionFilter)安装了SEH。对于像AV(*(PDWORD)0 = 0)这样的异常,可以完美地调用处理程序,但由于某些原因,在堆损坏的情况下不会调用它。在卸载时,第三方库dll之一的dllmain中发生了损坏。

几个问题。任何人都可以解释为什么不调用处理程序?还有其他方法可以阻止该对话吗?

2 个答案:

答案 0 :(得分:1)

显然,用户定义的异常处理程序无法捕获堆损坏,即使它们是作为异常发出的,也有自己的异常代码(0xC0000374“STATUS_HEAP_CORRUPTION”)。这是一个Visual C ++错误报告,它基本上被关闭为“无法修复”:

https://connect.microsoft.com/VisualStudio/feedback/details/664497/cant-catch-0xc0000374-exception-status-heap-corruption

  

正如您所发现的,这不是编译器或操作系统中的错误。您的函数导致的堆损坏被视为严重错误,并且作为处理该错误的一部分,操作系统终止该进程。这就是导致不能调用异常处理程序的原因。

我猜测Windows错误报告或其他创建崩溃转储的方法仍然可以捕获它。

至于阻止对话框,在注册表中你可以完全禁用WER,或者只是禁用对话框以便进程不会阻塞:

https://msdn.microsoft.com/de-de/library/windows/desktop/aa366711(v=vs.85).aspx(参见“DontShowUI”)

答案 1 :(得分:0)

  

但由于某种原因,在堆损坏的情况下不会调用它。在卸载时,第三方库dll之一的dllmain中发生了损坏。

堆损坏是未定义的行为。它可能会抛出异常,否则可能会发生异常。如果一个有缺陷的第三方库弄乱了你的堆,那么问题是“为什么你首先要让他们弄乱你的堆?”

只要进程异常终止,就会显示“程序已停止工作”对话框。并非所有异常进程终止都是由异常引起的。许多错误(例如堆栈溢出,堆栈错位等)导致进程立即终止,这可能会显示该消息但不会给您机会处理错误。

(另外,请参阅Hans上面的精彩评论)