最近,我们遇到了一个 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 在评论中提供帮助。