必须用 WinDbg Preview 或 WinDbg 10 分析 C# dump;.NET Framework 可用 WinDbg Legacy 配匹配版本 SOS.dll,.NET Core/5+ 必须用 WinDbg Preview 并通过 dotnet-sos 安装扩展,且位数需与 dump 一致。

WinDbg 装什么版本才能分析 C# dump
必须用 WinDbg Preview(Microsoft Store 版)或 WinDbg 10(Windows SDK 自带),旧版 WinDbg Legacy 对 .NET Core/.NET 5+ 支持极差,连 clrstack 都可能报 Failed to load data access DLL。
关键点:
- .NET Framework 程序可用
WinDbg Legacy+SOS.dll(路径需匹配运行时版本,如C:\Windows\Microsoft.NET\Framework64\v4.0.30319\SOS.dll) - .NET Core 3.1+ / .NET 5+ 必须用
WinDbg Preview,它内置dotnet-sos和自动扩展加载能力 - 32 位 dump 必须用 32 位 WinDbg,64 位 dump 必须用 64 位 WinDbg——混用直接卡在
.loadby sos coreclr失败
怎么让 WinDbg 正确加载 SOS / DAC 扩展
不是所有 dump 都能直接敲 !clrstack。常见失败原因是 DAC(Data Access Component)没找到,尤其 .NET Core 程序的 dump 缺少运行时符号或未部署 dotnet-sos。
实操步骤:
- 先执行
.symfix; .reload确保符号路径正确(默认走 Microsoft 服务器) - 对 .NET Core/.NET 5+:运行
dotnet-sos install(需已装 .NET SDK),然后在 WinDbg 中执行.load C:\Users\XXX\.dotnet\sos\sos.dll - 对 .NET Framework:用
.loadby sos clr(托管进程)或.loadby sos mscorwks(.NET 2.0) - 验证是否成功:
!eeversion应输出运行时版本;!dumpheap -stat不报错即 OK
快速定位 C# 崩溃/高 CPU/内存泄漏的命令组合
别一上来就 !dumpheap -stat——容易卡死或返回无意义数据。按问题类型选命令链:
-
崩溃(AccessViolation / AV):
!analyze -v→ 看FAULTING_IP和STACK_TEXT→ 再用!u反汇编托管方法(需 PDB 在符号路径中)地址 -
高 CPU:
~*e !clrstack查所有线程托管栈 → 找重复出现的调用栈(比如都在System.Threading.WaitHandle.WaitOne或死循环里) -
内存泄漏:
!dumpheap -stat看大头类型 → 记下类型名(如MyApp.CacheItem)→!dumpheap -type MyApp.CacheItem→ 拿几个对象地址 →!gcroot查谁在引用它地址
注意:!gcroot 输出里如果出现 Finalizer Queue 或 HandleTable,大概率是未释放的 IDisposable 或事件订阅泄漏。
为什么 !dumpobj 显示字段全是 0x0 或乱码
这不是 WinDbg 问题,是 dump 缺少调试信息或对象已被 GC 回收但内存未覆写。常见于:
- Release 编译且未生成 PDB,或 PDB 路径不对 →
.sympath+ C:\path\to\pdbs+.reload /f - 对象在 Gen 0,而 dump 是
MiniDumpWithHeap类型(不包含完整堆)→ 必须用Full Dump(任务管理器右键 → “创建转储文件”,或procdump -ma) - 字段是
string或引用类型,但!dumpobj只显示引用地址 → 需再对地址执行一次!dumpobj,或用!do(简写)
真正难的是跨 AppDomain 或跨上下文的对象引用链,这时候 !gcroot 可能只显示 DOMAIN(000001234567890),得结合源码确认生命周期管理逻辑。








