2

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

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

几个问题。谁能解释为什么不调用处理程序?还有其他方法可以防止该对话吗?

4

2 回答 2

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”)

于 2017-04-04T18:09:11.623 回答
0

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

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

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

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

于 2011-12-07T06:46:26.153 回答