1

最近,我们遇到了一个 64 位 .NET 4.0 进程,其中一些非托管代码通过简单地消失而崩溃。没有事件查看器条目,没有 Windows 错误对话框,而且我们当前的日志记录和跟踪语句没有任何明显的迹象。代码库非常庞大,所以添加额外的跟踪语句肯定会很耗时。

我们有几个第三方 DLL 在使用中,但是我们可以访问我们需要的所有 PDB 文件。崩溃在一天中经常发生,但不是定期发生。我们的小组怀疑某些处理不当的多播流量可能是原因,但我们不能 100% 确定。

我们使用 ADPlus 在崩溃模式下调试进程:

adplus -crash -p <pid> -o c:\temp

我们得到了一些非常奇怪的行为......崩溃发生时的最后一个小型转储是第一次机会“CONTRL_C_OR_Debug_Break异常”;我们肯定没有按“ctrl+C”。每次我们附加调试器时,我们都会在启动后 10 分钟到 2 小时内得到这个小型转储。没有第二次机会例外,也没有失控的内存或 CPU。

诚然,在 CDB/ADPlus/WinDbg 方面,我是个新手,但我至少知道一些 windbg/SOS 命令可以绕过一些故障转储;在这个小型转储上,我很难过。

我要以正确的方式诊断这个问题吗?我们还能做什么?

更新

在获得正确的 Windows Server 2008 符号文件后,这似乎是堆栈。寻找可能的堆损坏的最佳方法是什么?

0:039> k
  *** Stack trace for last set context - .thread/.cxr resets it
Child-SP          RetAddr           Call Site
00000000`2d06f4f0 00000000`77834736 ntdll!RtlReportCriticalFailure+0x2f
00000000`2d06f5c0 00000000`77835942 ntdll!RtlpReportHeapFailure+0x26
00000000`2d06f5f0 00000000`778375f4 ntdll!RtlpHeapHandleError+0x12
00000000`2d06f620 00000000`777ddc8f ntdll!RtlpLogHeapFailure+0xa4
00000000`2d06f650 00000000`7767307a ntdll! ?? ::FNODOBFM::`string'+0x10c54
00000000`2d06f6d0 00000000`72a88cc4 kernel32!HeapFree+0xa
00000000`2d06f700 00000000`6ea37ffb msvcr100!free+0x1c
00000000`2d06f730 00000000`eb692d6c jvm+0x187ffb
00000000`2d06f738 00000000`2d06f7a8 0xeb692d6c
00000000`2d06f740 00000000`00000000 0x2d06f7a8

更新 2

事实证明,我们的应用程序 + 较新版本的 jdk 的组合确实破坏了堆。通过设置 gflags 捕获故障转储:

gflags -p /enable MyProcess.exe /full

仍然不确定究竟是什么原因,但降级我们的 jvm 实际上暂时解决了这个问题。非常感谢 @MarcSherman 和 @SevaTitov 在评论中提供帮助。

4

1 回答 1

1

这是我为找到堆损坏的根源所做的工作:

  1. 将 Windows 调试工具安装为“独立”组件。
  2. 使用 gflags启用全堆验证:

    gflags -p /enable MyProcess.exe /full
    
  3. 使用 ADPlus 捕获生成的故障转储:

    adplus.exe -crash -o <outputdirectory> -p <PID>
    
  4. 在 WinDbg 中打开生成的故障转储并运行:

    !analyze -v
    

感谢@MarcSherman 和@SevaTitov 的评论。

于 2013-04-23T13:47:00.920 回答