我正在编写使用第三方库执行一项简单任务(光栅化)的小实用程序(VC 2010,无clr)。以后的实用程序将被更大的应用程序使用有时,实用程序因第三方库中的某些堆损坏而崩溃。没关系,但Windows(Vista / 2008)显示了众所周知的对话框“程序已停止工作...关闭/调试程序。”这在我的情况下是不合适的(服务器端)。实用程序应该静默崩溃/终止没有任何可见效果。
为此,我为未处理的异常(SetUnhandledExceptionFilter)安装了SEH。对于像AV(*(PDWORD)0 = 0)这样的异常,可以完美地调用处理程序,但由于某些原因,在堆损坏的情况下不会调用它。在卸载时,第三方库dll之一的dllmain中发生了损坏。
几个问题。任何人都可以解释为什么不调用处理程序?还有其他方法可以阻止该对话吗?
答案 0 :(得分:1)
显然,用户定义的异常处理程序无法捕获堆损坏,即使它们是作为异常发出的,也有自己的异常代码(0xC0000374“STATUS_HEAP_CORRUPTION”)。这是一个Visual C ++错误报告,它基本上被关闭为“无法修复”:
正如您所发现的,这不是编译器或操作系统中的错误。您的函数导致的堆损坏被视为严重错误,并且作为处理该错误的一部分,操作系统终止该进程。这就是导致不能调用异常处理程序的原因。
我猜测Windows错误报告或其他创建崩溃转储的方法仍然可以捕获它。
至于阻止对话框,在注册表中你可以完全禁用WER,或者只是禁用对话框以便进程不会阻塞:
https://msdn.microsoft.com/de-de/library/windows/desktop/aa366711(v=vs.85).aspx(参见“DontShowUI”)
答案 1 :(得分:0)
但由于某种原因,在堆损坏的情况下不会调用它。在卸载时,第三方库dll之一的dllmain中发生了损坏。
堆损坏是未定义的行为。它可能会抛出异常,否则可能会发生异常。如果一个有缺陷的第三方库弄乱了你的堆,那么问题是“为什么你首先要让他们弄乱你的堆?”
只要进程异常终止,就会显示“程序已停止工作”对话框。并非所有异常进程终止都是由异常引起的。许多错误(例如堆栈溢出,堆栈错位等)导致进程立即终止,这可能会显示该消息但不会给您机会处理错误。
(另外,请参阅Hans上面的精彩评论)