6

我依靠Windows 错误报告为大型多线程应用程序创建完整的用户模式转储。我知道当我开始使用它时(2012 年初),这些转储包含所有应用程序内存,以及在应用程序崩溃时准确的所有线程的完整堆栈(引发未处理的异常等)。但在去年的某个未知时刻,WER 创建的故障转储发生了变化。它们仍然包含所有内存,但只显示一个线程,并且堆栈似乎来自进程已经关闭之后

    ntdll.dll!_LdrpCallInitRoutine@16()  + 0x14 bytes   
    ntdll.dll!_LdrShutdownProcess@0()  + 0x141 bytes    
    ntdll.dll!_RtlExitUserProcess@4()  + 0x74 bytes 
    kernel32.dll!_UnhandledExceptionFilter@4()  + 0x18928 bytes 

这是一个使用 VS2010 SP1 编译的非托管(无法管理?)32 位 C++ 应用程序,在 64 位 Win7 SP1 上运行(并保持更新)。有谁知道去年改变了 WER 行为的任何 Windows 更新?除了“HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\AppName.exe”之外,还有什么可配置的吗?

此外,通过调用“RaiseFailFastException”来终止应用程序仍然会导致良好的转储,并为所有线程提供有效的堆栈。

4

2 回答 2

5

啊哈!第三方库正在调用 SetUnhandledExceptionFilter,这会阻止 Windows 错误报告获取原始异常。他们的处理程序进行了一些内部清理,然后调用了中止,此时 WER 终于能够创建转储。

对于遇到此类问题的任何人,我建议检查已安装的处理程序(SetUnhandledExceptionFilter、set_terminate 等的返回值)是否符合您的预期(如果您依赖 WER,则为 null,或者您自己的处理程序或 CrashRpt)。

于 2013-05-03T19:06:33.880 回答
-1

最好让您的应用程序在崩溃时自行转储。你只需要调用SetUnhandledExceptionFilter函数,指定回调。在回调中,使用转储类型的MiniDumpWriteDump函数。MiniDumpWithFullMemory

每当发生未处理的(由您的代码)异常时,都会调用您的异常过滤器。在回调中,最好枚举并挂起进程的所有其他线程。

您可能还需要为SetUnhandledExceptionFilter自己安装一个挂钩!为什么?好吧,CRT 总是会禁用任何已安装的异常过滤器,并且通过挂钩功能,您可以避免这种情况。

于 2013-04-03T17:08:46.383 回答