WinDbg 调试实战:核心命令与内存分析技巧
WinDbg 是诊断 .NET 应用程序疑难杂症的核心工具,涵盖内存泄漏、CPU 飙高、线程死锁等场景。本文聚焦日常调试中最常用的命令及其典型用法,帮助开发者快速定位问题。
环境准备与 Dump 捕获
调试前需准备 64 位进程的内存转储文件。以 IIS 工作进程为例,打开任务管理器,定位到 w3wp.exe,右键选择"创建转储文件"即可生成。
安装 WinDbg 需通过 Windows SDK 获取,安装时勾选 Debugging Tools for Windows。启动后按 Ctrl+D 加载 Dump 文件。
基础环境配置
加载 SOS 扩展
.loadby sos clr
配置调试符号
.symfix+ C:\symbols
.reload
查看当前符号搜索路径:
0:000> .sympath
线程与 CPU 分析
线程池状态
!threadpool 展示 CLR 线程池的整体健康度:
0:000> !threadpool
CPU utilization: 2%
Worker Thread: Total: 19 Running: 2 Idle: 17 MaxLimit: 32767 MinLimit: 4
Work Request in Queue: 0
--------------------------------------
Number of Timers: 2
--------------------------------------
Completion Port Thread:Total: 4 Free: 4 MaxFree: 8 CurrentLimit: 4 MaxLimit: 1000 MinLimit: 4
线程全景视图
!threads
CPU 消耗排行
!runaway 按累计 CPU 时间排序,快速识别热点线程:
0:000> !runaway
输出第一列为线程 TID,第二列为该线程消耗的 CPU 时间(单位毫秒)。
堆栈与对象探查
切换线程并查看托管堆栈
~34s // 切换到 34 号线程
!clrstack // 显示托管调用栈
栈上对象扫描
!dso(Dump Stack Objects)列出当前线程栈帧引用的所有托管对象:
!dso
对象详情与数组解析
!do 00007ff812345678 // 查看指定地址的对象结构
!da 00007ff812345680 // 解析数组对象
带参数的完整堆栈
!clrstack -a
该命令会显示每个栈帧的局部变量和参数值,对分析业务逻辑至关重要。
内存与 GC 诊断
托管堆概览
!eeheap -gc
展示三代堆的段分布、已提交与已使用大小,辅助判断内存压力来源。
对象统计与筛选
!dumpheap -stat // 按类型汇总对象数量与占用
!dumpheap -stat -mt -min 85000 // 筛选大对象(≥85KB)
!dumpheap -type System.Net.Sockets.Socket -stat // 特定类型统计
终结队列与 GC Root
!finalizequeue // 等待终结的对象队列
!gcroot 0000023456789ABC // 追踪对象的引用根链
模块加载情况
!eeheap -loader
异常与同步问题
CLR 异常断点调试
附加到活进程时,可启用 CLR 异常捕获:
sxe clr // 启用 CLR 异常中断
g // 继续执行
!pe // 打印当前异常详情
!clrstack // 查看异常发生时的堆栈
sxd clr // 禁用 CLR 异常中断
qd // 分离并退出调试器
线程阻塞与锁分析
!syncblk
该命令输出同步块表,揭示哪些线程持有锁、哪些线程在等待,是诊断死锁和性能瓶颈的关键。
扩展工具建议
除内置命令外,MEX 扩展 提供了更友好的输出格式和额外诊断能力,建议配合安装以提升调试效率。