Windows应用的crash dump收集入门 - 先搞清楚 WER / ProcDump / WinDbg怎么分工
· 小村 豪 · Windows开发, 故障排查, crash dump, WER, ProcDump, WinDbg
在 Windows 应用上,只要出现「偶尔才会崩溃」这种症状,光靠日志往往追查不下去。
特别是下列情境:
- 只在客户环境会发生
- 有捕获到异常信息,但调用端的上下文不够
- 不只是 C# / .NET 的 managed 层,还牵涉 COM、P/Invoke、原生 DLL、厂商 SDK
- 只有在长时间运行后才崩溃
这时候 crash dump 就派得上用场。只要在 crash 当下把进程状态存成文件,之后就能读到异常代码、挂掉那条 thread 的堆栈、当时加载的模块、以及部分或整块的内存。
在 Windows 上,思路顺序是:先用 WER 的 LocalDumps,有需要再搭配 Sysinternals 的 ProcDump;真的想自己掌控了,再用 MiniDumpWriteDump。本文就以 Windows 桌面应用、常驻应用、Windows 服务、设备集成工具等为前提,整理 crash dump 收集的第一步。
1. 先下结论
先把最要掌握的重点列出来:
- 先 按应用单独配置 WER LocalDumps 是最稳妥的做法,不用额外部署工具,也能在 crash 后把 dump 留在本地。
- 复现率低的现场调查、或要看 first chance exception / hang,就用 ProcDump。
- 自研收集放到最后再想 大概刚好。真的需要再评估
MiniDumpWriteDump就行。 - 和 dump 同等重要的是 PDB 与发布 binary 的保存。只有 dump 没有符号,能读到的信息会大幅减少。
- full dump 威力大,但文件大小与敏感信息泄露风险也大。保存位置、保留份数、访问权限、分享流程要先定好。
入门阶段建议的配置大概是这样:
| 环境 | 起手式 |
|---|---|
| 开发机/验证机 | 按应用单独配置 WER LocalDumps,先用 DumpType=2 取 full dump |
| 客户环境/现场机 | 依容量与敏感度要求选 DumpType=1 或 2;只在必要时补上 ProcDump |
| 长时间运行或 hang 调查 | WER 之外再评估 ProcDump 的 -h 或 -e 1 |
| 想自带 UI、附带日志 | 以独立进程为前提,用 MiniDumpWriteDump 做自研收集 |
简单说就是:先 WER,再 ProcDump,最后自研。反过来的顺序做,设计通常会变重。
2. crash dump 能告诉我们什么
crash dump 是「那一刻的快照」,比起监控录像,它更像事故现场的静止画面。
所以下列信息通常很容易拿到:
- 是哪个异常代码
- 是哪条 thread 挂掉
- 当下的调用堆栈
- 当时加载的模块
- 依你包进多少内存,还能看到 heap 的状态、对象内容
但下列信息光靠 dump 就比较不够:
- 走到这一步的时序
- 几小时前就在上升的趋势
- 和通信或设备之间的外部状态
- 崩溃前的输入或业务情境
所以实务上 不要只靠 dump 单打独斗,要搭配日志与 heartbeat。
3. 收集方法全景
入门阶段要掌握的 Windows 应用 dump 收集方式,有下列 4 种:
| 方法 | 适合情境 | 优势 | 注意事项 |
|---|---|---|---|
| WER LocalDumps | 想先常态化的 crash 收集 | Windows 内置,易按应用单独配置 | 主要针对 crash;hang 与细部条件分流较弱 |
| ProcDump | 复现率低的调查、hang、first chance exception | 触发条件多,容易在现场部署 | 变成外部工具的运维 |
| 任务管理器的创建 dump | 手动抓当下状态 | GUI 现场抓 | 不是自动收集 |
MiniDumpWriteDump |
想做自研诊断功能 | 容易把附带日志或自定义 metadata 绑一起 | 写不好反而会把自己搞坏 |
对入门者来说,比起「用什么抓」,更要先决定「在什么条件」「抓到哪」「抓多大」。
4. 起手式推荐 WER LocalDumps
4.1 先看的注册表值
Windows Error Reporting (WER) 内置了 LocalDumps,可以在 crash 后把 user-mode dump 存到本地。不用额外分发工具,起手式相当好用。
基本 key 是:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps
你可以在这里放全局设置,但实务上更建议把设置放在 按应用单独的子 key 下。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe
最先看的值有 3 个:
| 值 | 含义 | 起手式建议 |
|---|---|---|
DumpFolder |
dump 的输出位置 | 划一个专用文件夹 |
DumpCount |
保留份数 | 从 5〜10 起 |
DumpType |
0=自定义、1=mini、2=full | 先用 2;容量吃紧再改 1 |
4.2 按应用单独的配置示例
举例来说,想把 MyApp.exe 的 full dump 存到 C:\CrashDumps\MyApp,最多保留 10 份,可以这样设置:
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpFolder /t REG_EXPAND_SZ /d "C:\CrashDumps\MyApp" /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpCount /t REG_DWORD /d 10 /f
reg add "HKLM\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\MyApp.exe" /v DumpType /t REG_DWORD /d 2 /f
这段的重点:
- 范围限定到
MyApp.exe,不是全局 - 输出位置划到专用文件夹
- 起手式先用 full dump
- 保留份数限制为 10
4.3 确认真的有抓到
设置好之后,不要直接等正式环境自然发生,一定要先在验证环境亲自抓一次 比较安全。
确认重点:
.dmp会不会出现在预期文件夹- 文件大小是否符合运维设想
- 用 WinDbg 能不能打开
- 事件查看器的 Application 日志有没有对应 crash 事件
5. 何时用 ProcDump
WER 就够用的情境不少,但下列情境 ProcDump 更方便:
- 不想常设注册表项
- 只想监视某个已在跑的进程
- 只想监视下一次启动的进程
- 要看 first chance exception
- 要抓 hang
- 想用性能计数器或其他条件触发
5.1 常用选项
入门阶段只要记下列这些,就能打相当多仗:
| 选项 | 含义 |
|---|---|
-ma |
full dump |
-mp |
MiniPlus dump |
-e |
未处理异常时抓 dump |
-e 1 |
first chance / second chance 异常都抓 |
-h |
窗口 hang 时抓 |
-w |
等待目标进程启动 |
-x |
由 ProcDump 启动并监视目标 |
-n |
最多抓几份 dump |
-accepteula |
首次 EULA 自动同意 |
5.2 代表性命令
对已启动的进程,未处理异常时抓 full dump
procdump -accepteula -ma -e 1234 C:\CrashDumps\MyApp
等下次启动,未处理异常时抓 full dump
procdump -accepteula -ma -e -w MyApp.exe C:\CrashDumps\MyApp
由 ProcDump 启动并继续监视
procdump -accepteula -ma -e -x C:\CrashDumps\MyApp MyApp.exe
连 first chance exception 也要抓
procdump -accepteula -ma -n 3 -e 1 MyApp.exe C:\CrashDumps\MyApp
要抓 hang
procdump -accepteula -h MyApp.exe C:\CrashDumps\MyApp
5.3 为什么不要把 -i 当起手式
ProcDump 有 -i 可以注册成 postmortem debugger,功能很强,但 会影响整台机器的 crash 时行为,入门阶段拿它来起手式太重。
起手式建议从 WER 的按应用单独配置 或 ProcDump 的 -w / -x / 指定 PID 开始,比较好掌握。
6. 自研收集用 MiniDumpWriteDump 的思路
自研收集适合下列情境:
- 想在 UI 放一个「保存诊断信息」按钮
- 想把 dump、日志、配置、trace ID 绑在一起
- 想连同关联的子进程或辅助进程一起打包
- 上传前想做自研的数据遮罩或压缩
这里主角 API 是 MiniDumpWriteDump。
不过它有一些特性,入门阶段最不要偏掉的有 2 点:
- 如果可以,从另一个进程去 dump 目标进程
- DbgHelp 系列以 single-threaded 的前提使用
7. mini / full / 中型 dump 怎么选
这里相当多人犹豫。实务上照下表思考会比较顺:
| 种类 | 适合情境 | 优势 | 注意事项 |
|---|---|---|---|
| mini dump | 想先广泛分发、方便分享 | 小、好传 | 能还原的状态深度有限 |
| full dump | 以查原因为优先,牵涉原生边界或 heap | 信息最多 | 文件大、敏感信息泄露风险高 |
| MiniPlus / Custom | mini 不够、full 又太重 | 取平衡 | 需要调参的知识 |
给入门者的建议其实很单纯:
- 开发机/验证机直接 full dump
- 客户环境依运维条件选 mini 或 full
- 怀疑是内存损坏、原生 DLL、COM、P/Invoke、或长时间运行后的状态异常,偏 full
8. 运维上要先决定的事
dump 收集常常是运维层面先出事,而不是实现层面。请先把下列事项梳理清楚。
8.1 PDB 与 binary 要怎么保存
这件事最重要。
- 实际发布的 EXE / DLL 版本
- 该版本对应的 PDB
- 是从哪个 commit / 哪条 build pipeline 产出的
- 安装包与发布物的版本信息
8.2 要输出到哪里、保留几份
full dump 会相当大,一开始就先定:
- 不要放在系统盘根目录
- 划到专用文件夹
- 用
DumpCount或-n设上限 - 长期保存与临时保存分开
8.3 谁可以看这些 dump
full dump 有可能混入敏感或个人信息:
- 明文配置
- 连接字符串
- token 或凭证
- 崩溃前正在处理的业务数据
- 文件路径或用户名
所以 「抓什么」的设计,要与「谁可以接触」一起定。
9. 拿到 dump 后的最短分析路线
拿到 dump 之后要做的事其实很朴实:
9.1 安装 WinDbg
现在可从 Microsoft Store 或 winget 安装。
winget install Microsoft.WinDbg
9.2 打开 dump
windbg -z C:\CrashDumps\MyApp\MyApp_YYMMDD_HHMMSS.dmp
9.3 设置符号
先接通 Microsoft 公开符号,再把自己的 PDB 路径加进去。
.symfix C:\Symbols\Microsoft
.sympath+ C:\Symbols\MyApp
.reload
9.4 先看自动分析
!analyze -v
之后依序看:
- 是哪个异常代码
- faulting module 是什么
- 自己的代码在堆栈上露到哪
- 除了异常 thread,其他 thread 有没有奇怪的等待或卡住
10. 常见踩坑
10.1 dump 有了,但 PDB 没了
这种情况不少。dump 有抓到,但没有符号就读得很片段。
配置 dump 的同一时间,就把 PDB 的保存设计一起做。
10.2 没检查 DumpFolder 的 ACL
在服务或已做权限隔离的进程上,这里很容易空转。
先确认「那个进程真的能写进去吗」。
10.3 持续把 full dump 往正式环境的系统盘写
这是容量事故的常客。
保留份数限制与输出位置分离,一开始就要配置好。
10.4 想用 WER 一手包 hang 的情境
WER LocalDumps 主要对 crash 有效。
hang 或 first chance exception,ProcDump 有些情境更合适。
10.5 永远开着 -e 1,被异常洪流淹没
first chance exception 很好用,但数量就是多。
设份数上限、短时间才开、限缩目标 才实务。
11. 总结
在复现率低的故障场景里,crash dump 是相当有力的观测点。特别是 Windows 应用牵涉 COM、P/Invoke、原生 DLL、或长时间运行时,一开始就先把「崩溃后要留下什么」定清楚,非常值得。
推荐的顺序很单纯:
- 先把 WER LocalDumps 按应用单独配置好
- 必要时再加 ProcDump
- 想进一步控制,再以独立进程为前提使用
MiniDumpWriteDump
按这个顺序走,比较不会走偏。
12. 参考资料
- Microsoft Learn: Collecting user-mode dumps - Win32 apps
- Microsoft Learn: ProcDump v11.1 - Sysinternals
- Microsoft Learn: MiniDumpWriteDump function (minidumpapiset.h) - Win32
- Microsoft Learn: User-mode dump files - Windows drivers
- Microsoft Learn: Analyzing a user-mode dump file - Windows drivers
- Microsoft Learn: Install the Windows debugger - Windows drivers
- Microsoft Learn: Symbol path for Windows debuggers - Windows drivers
- Microsoft Learn: !analyze (WinDbg) - Windows drivers
- Microsoft Learn: Troubleshoot processes by using Task Manager - Windows Server
- Microsoft Learn: Enabling Postmortem Debugging - Windows drivers
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
工业相机控制应用运行一个月后突然崩溃时(下篇) - 什么是 Application Verifier 与异常路径测试基础设施的做法
下篇整理 Application Verifier 是什么以及怎么把它编入 Windows 异常路径测试基础设施。用 Handles 抓 invalid handle、Low Resource Simulation 不用把机器榨干就触发资源不足,搭配 harness EXE...
伪随机数与真随机数的区别 - 如何区分的整理
本文整理伪随机数与真随机数的区别,重点不在输出外观而在生成器结构:普通 PRNG 重视可重现性、CSPRNG / DRBG 主打不可预测性、NRBG 则以物理熵源为基础。文中说明种子(seed)与重新播种(reseed)、健康检测(health test)的作用,并给出信息...
Windows的效率模式是什么 - Windows 11绿色叶子图标代表什么,以及如何关闭
整理 Windows 11 任务管理器中绿色叶子图标与效率模式的真正含义,以及它如何通过降低优先级与 EcoQoS 平衡前台响应、电池与散热。同时说明逐一进程的关闭步骤、灰色选项的处理,以及和 Microsoft Edge 节能功能的差异,以及性能比较时必须对齐的条件。
Windows 什么时候需要管理员权限 - UAC、保护区域与设计上的辨别方式
从边界与存储位置的角度,整理 Windows 什么时候真正需要管理员权限:UAC、保护区域、HKLM、服务、驱动、防火墙。同时说明 per-user 与 per-machine 的差异,以及把管理员处理拆成独立 EXE、服务或任务的设计取舍,帮读者判断该不该提升权限。
在 Windows 环境下减少 Codex 乱码事故的最佳实践 - 先把『指示方式』钉住,再谈环境整备
本文整理在 Windows 上让 Codex 安全处理日文文件的指示原则:读文件前先确认 encoding 与 BOM,疑似乱码禁止臆测保存,现有文件维持原状,仅新建采用 UTF-8,并在写入后重新读取代表性日文行验证,把规则沉淀进 AGENTS.md 以减少事故。
常见问题
汇总了咨询这一主题时常见的问题。
- Crash dump 是什么?能看到哪些信息?
- Crash dump 是在应用崩溃当下,把进程状态存成文件的快照,比起监控录像更像事故现场的静止画面。从 dump 通常能读到异常代码、挂掉那条 thread 的调用堆栈、当时加载的模块,依包含的内存多寡还能看到 heap 的状态与对象内容。但走到崩溃前的时序、和通信或设备之间的外部状态,光靠 dump 就比较不够,实务上要搭配日志与 heartbeat 一起使用。
- WER LocalDumps 要怎么配置?
- 在注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps 下,建议按应用单独创建子键(例如 MyApp.exe),设置三个值:DumpFolder 指定 dump 的输出位置(划一个专用文件夹)、DumpCount 设保留份数(从 5〜10 起)、DumpType 选 dump 种类(1 为 mini、2 为 full,起手式先用 2)。设置完成后,一定要先在验证环境亲自触发一次 crash,确认 .dmp 有出现在预期文件夹且能用 WinDbg 打开。
- WER 和 ProcDump 该怎么分工?
- 先按应用单独配置 WER LocalDumps 是最稳妥的起手式,不用额外部署工具就能在 crash 后把 dump 留在本地。ProcDump 则适合 WER 不好处理的情境:不想常设注册表项、要看 first chance exception、要抓 hang、或想用其他条件触发。自研收集用 MiniDumpWriteDump 放到最后再想就好。顺序是先 WER、再 ProcDump、最后自研,反过来做设计通常会变重。
- 该选 mini dump 还是 full dump?
- 开发机或验证机直接用 full dump;客户环境依容量与敏感度要求选 mini 或 full。怀疑是内存损坏、原生 DLL、COM、P/Invoke、或长时间运行后的状态异常时偏向 full。要注意 full dump 文件大,而且可能混入明文配置、连接字符串、token 等敏感信息,所以保存位置、保留份数、访问权限、分享流程要先定好。另外与 dump 同等重要的是 PDB 与发布 binary 的保存,没有符号能读到的信息会大幅减少。
作者简介
本文作者的个人简介页面。
Go Komura
小村软件有限公司 代表
以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。