Visual C++程序崩溃,但未生成转储文件。为什么?

3
我有一个非常奇怪的情况。 我正在运行Visual Studio 2010中用C++编写的IOCP服务器程序。
它使用'minidump',因此当出现逻辑错误(如指针误用)时,程序会崩溃并生成转储文件,以便我可以找出代码中的崩溃点。
有时(很少),程序会崩溃,但没有转储文件。
是什么情况导致 'SetUnhandledExceptionFilter()' 不起作用? 有人知道这个问题吗?我搞不清楚。

http://msdn.microsoft.com/en-us/library/windows/desktop/ee416349%28v=vs.85%29.aspx - DumbCoder
1个回答

3

当然你不知道是因为你没有 minidump 查看。在 SetUnhandledExceptionFilter 回调触发时,应该最少限度的操作,进程处于危险状态,已经崩溃。锁可能被持有,堆锁尤其棘手。你不能期望 MiniDumpWriteDump() 能成功。

你需要一个小的守护进程来等待命名事件。在 main() 函数中尽早启动它,并将进程 ID 传递给它。守护进程同时等待该事件和进程句柄。在异常回调函数中,只需发出信号并立即休眠很长时间。这会唤醒守护进程,它将调用 MiniDumpWriteDump() 加上其他必要的内容来让您了解崩溃情况。然后杀死您的主程序。


我不明白为什么从另一个进程运行MiniDumpWriteDump有更大的成功机会。如果锁被占用,则这些锁将被占用。哪个进程试图访问已锁定的资源并不重要。此外,由于MiniDumpWriteDump不是线程安全的,无论如何都会失败。除非您可以同步所有线程(因为您的程序处于不确定状态,所以不能),否则无法保证成功。你说的听起来很有道理,但并没有提供为什么守卫进程将具有更高成功率的理由。 - IInspectable
1
线程安全并不是一个问题,因为只有一个线程调用MiniDumpWriteDump()。但如果进程被破坏,如MDWD所需的CreateFile()和HeapAlloc()等基本调用可能会失败,这无疑是个问题。这相当于一种过滤器,如果在进程内执行,则永远无法看到那些无法调试的真正严重的崩溃。这也许是件好事。 - Hans Passant
1
感谢回复。我还不太确定:如果一个进程被破坏到CreateFile失败(请纠正我,除非内核内存被破坏,否则它会失败?),那么你也可以说SetEvent也会失败。基本上,对于HeapAlloc来说也是一样的,除非它因OOM而失败。我认为MDWD在“预分配”的静态数据上工作,这也解释了为什么它不是线程安全的。在技术层面之外,您是否曾经生成过一个超出上下文的minidump,而进程内的解决方案可能不会有这个问题? - IInspectable
我并不确定我需要说服你做任何事情,这听起来很费力。请点击“提问”按钮。 - Hans Passant
4
当然,你不必说服我。但既然我对你提出的答案的准确性提出了质疑,如果你能的话,不这样做是愚蠢的。我真的很感兴趣。 - IInspectable

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接