WinDbg 崩溃转储 (.dmp) 分析实战指南
在工业控制或上位机开发中,当部署在现场机器上的程序发生崩溃时,抓取 .dmp 文件并在本地还原案发现场是我们排查问题的必经之路。
📍 假设本案的路径场景如下:
- 现场机器(上位机)运行目录:
C:\SuperApp - 本地源码目录:
D:\DevSuper - 本地 EXE/PDB 生成目录:
D:\DevSuper\Build\RelWithDebInfo - 本地软件执行目录:
D:\SuperApp - 本地符号缓存目录:
D:\DebugSymbols
第一阶段:布置现场(配置环境与路径)
打开 WinDbg 并拖入 .dmp 文件后,第一件事就是告诉它“你的代码在哪,符号在哪”。建议依次单条输入,避免语法粘连报错:
// 1. 设置符号路径 (优先找本地 PDB,找不到再去微软服务器下载并缓存)
.sympath D:\DevSuper\Build\RelWithDebInfo;SRV*D:\DebugSymbols*https://msdl.microsoft.com/download/symbols
// 2. 设置可执行文件路径 (解决各种 Unable to load image, Win32 error 0n2 报错)
// 包含现场机器的路径以及本地的运行/生成路径
.exepath C:\SuperApp;D:\SuperApp;D:\DevSuper\Build\RelWithDebInfo
// 3. 设置源码目录 (为了后面能直接定位到 C++ 具体的行号)
.srcpath D:\DevSuper
// 4. 应用并刷新符号
// 注意:如果不想它疯狂联网下载全部模块,直接用 .reload 即可。
// 只有在明确需要强行重载时才加 /f 强制参数。
.reload
第二阶段:破案三板斧(核心定位流程)
当路径出现 OK 或 Deferred(延迟加载,正常现象)后,直接开始查异常:
// 1. 穿越回崩溃瞬间 (最关键的一步,把上下文切到抛出异常的那一秒)
.ecxr
// 2. 查看带行号的调用堆栈 (从下往上看调用链)
kn
// 3. 自动诊断报告 (让引擎帮你出结论)
!analyze -v
🕵️ 分析重点:
- 在
kn输出中寻找你自己项目的模块名(如SuperApp!...),看右侧[...]里的源码行号。 - 在
!analyze -v输出中重点看Primary Problem Class(比如Access violation)和FAULTING_IP(具体挂在哪条指令)。
第三阶段:深挖细节(查看局部变量)
如果你通过 kn 定位到了嫌疑函数,想看看里面的变量长什么样:
Bash
// 1. 切换到指定的堆栈帧 (比如 kn 输出里的 01 号帧)
.frame 1
// 2. 打印当前帧的所有局部变量及内存地址
dv /t /v
// 3. 查看特定对象的内部结构 (假设变量名叫 pData)
dt pData
⚠️ 避坑提醒: 如果你编译的是 Release 或者
RelWithDebInfo版本,执行dv极大概率会遇到提示Private symbols (symbols.pri) are required for locals。这是因为局部变量被编译器优化掉了(未保留私有符号),属于正常现象,此时直接回 VS 源码里对着行号脑补逻辑即可。
💡 终极快捷键 & 救场指令
- 强行打断: 当底部疯狂刷屏
copying...或者显示*BUSY*卡死时,果断按下Ctrl + Break强行中断。 - 查看下载明细: 如果你想知道 WinDbg 到底在后台连哪个网址下载什么文件,输入
!sym noisy开启啰嗦模式。 - 查看所有线程: 排查死锁或线程争用时,输入
~\* kn可以一口气看全家福。

5万+

被折叠的 条评论
为什么被折叠?



