个人主页杨利杰YJlio❄️个人专栏《Sysinternals实战教程》 《Windows PowerShell 实战》 《WINDOWS教程》 《IOS教程》《微信助手》 《锤子助手》 《Python》 《Kali Linux》《那些年未解决的Windows疑难杂症》让复杂的事情更简单让重复的工作自动化ProcDump 学习笔记6.7监视异常未处理/首机会/消息过滤/进程终止1. 为什么要用异常触发抓 Dump2. 先搞清楚首机会异常和未处理异常3. 抓未处理异常稳定、低噪声、适合第一轮定位4. 抓首机会异常必须配合过滤和次数限制5. 用 -f 做异常过滤从异常风暴里筛出关键现场6. .NET 程序异常抓取建议7. 原生 SEH 异常重点看异常代码8. 等待进程启动与进程终止兜底9. 输出策略目录、Dump 类型和数量控制10. 实战推荐异常抓取优先级11. 即拿即用命令清单11.1 未处理异常稳定首选11.2 首机会异常 过滤11.3 原生访问违规11.4 进程终止兜底11.5 等待服务进程出现11.6 .NET OOM 专项12. 常见问题和踩坑提醒12.1 为什么未处理异常抓不到12.2 为什么首机会异常抓太多12.3 为什么 Dump 很大12.4 为什么进程名方式不准12.5 为什么服务进程权限不足13. 小结1. 为什么要用异常触发抓 Dump在 Windows 桌面运维和应用排障里有一类问题很难靠任务管理器或普通日志抓住程序不是一直慢也不是一直占 CPU而是在某个瞬间抛出异常然后崩溃、退出或者被业务代码捕获后继续运行。这个瞬间如果没有留证后续只能靠猜。ProcDump 的异常触发能力就是为这类问题准备的。它可以在进程发生异常时自动生成 Dump把当时的线程栈、异常代码、模块信息和内存状态保存下来。相比 CPU、内存、窗口挂起这些“状态型触发”异常触发更像是直接盯住问题爆发点。上图表达的是异常触发的核心链路目标进程运行过程中出现异常ProcDump 监视到异常事件后按设定条件生成 Dump 文件。这个思路非常适合处理偶发崩溃、.NET 异常、原生访问违规、服务进程异常退出等场景。我的判断是如果问题表现为“突然崩溃、闪退、异常退出”优先考虑异常触发如果问题表现为“慢、卡、占用高”再考虑 CPU、内存或挂起触发。注意异常触发不是万能方案。程序卡死但没有抛异常、线程死锁但窗口未崩溃、业务逻辑错误但没有真正触发异常时异常触发未必能抓到关键现场。2. 先搞清楚首机会异常和未处理异常异常触发最容易写错的地方就是没有分清“首机会异常”和“未处理异常”。这两个概念如果混在一起命令看起来没问题但抓出来的 Dump 价值会差很多。首机会异常指的是异常刚抛出来还没被应用程序自己的 try...catch、异常处理器或运行时机制处理之前调试器先收到一次通知。很多首机会异常最终会被程序正常处理不一定导致崩溃。所以首机会异常数量通常很大噪声也很重。未处理异常则更接近我们平时说的“程序崩了”。异常没有被捕获继续向外冒泡最终导致进程进入崩溃流程。这类异常噪声低定位价值高通常更适合作为第一轮抓取策略。上图可以理解为两条路径首机会异常更早通知调试器但不一定代表最终故障未处理异常更靠近崩溃结果噪声更低也更适合一线排障先使用。推荐顺序先抓未处理异常如果怀疑异常被程序吞掉再短时间开启首机会异常并配合过滤和数量限制。不要一上来就长时间开 -e 1。首机会异常可能非常多尤其是 .NET、浏览器、Office、企业 IM、插件型程序容易生成大量 Dump把磁盘打满。3. 抓未处理异常稳定、低噪声、适合第一轮定位如果一个程序已经明确存在闪退、崩溃、异常退出第一轮建议先抓未处理异常。它的噪声比首机会小也更接近真实崩溃现场。常用命令如下procdump -ma -e -n 1 MyApp.exe D:\Dumps\Unhandled这条命令的含义是监视 MyApp.exe当进程遇到未处理异常时生成一份完整 Dump并保存到 D:\Dumps\Unhandled 目录。参数拆开看-ma 生成完整 Dump -e 未处理异常触发 -n 1 最多抓 1 份这是最适合一线排障起步的命令。它不会像首机会异常那样大量刷屏也能在程序真正崩溃时保留关键现场。如果目标进程是 PID也可以写成procdump -ma -e -n 1 1234 D:\Dumps\UnhandledPID 方式适合进程名重复的场景例如多个 w3wp.exe、多个 chrome.exe、多个同名业务进程同时存在时。进程名方式更方便但前提是你能明确目标进程只有一个或者知道 ProcDump 会附加到哪个对象。4. 抓首机会异常必须配合过滤和次数限制首机会异常比未处理异常更早出现所以它适合处理一种特殊情况程序确实发生了异常但异常被上层框架、业务代码或运行时吞掉了最后没有直接崩溃日志里也只留下模糊记录。首机会异常的命令写法如下procdump -ma -e 1 -n 2 MyApp.exe D:\Dumps\FirstChance这里的 -e 1 表示首机会异常触发。它会在异常刚出现时就尝试抓取 Dump。问题也在这里首机会异常可能很多。程序内部正常处理的异常、框架探测类异常、网络重试类异常、插件兼容异常都可能触发。不开过滤Dump 很容易失控。更稳的写法是加 -f 过滤关键异常procdump -ma -e 1 -f NullReferenceException -n 2 MyApp.exe D:\Dumps\FirstChance如果要匹配多个关键词可以按实际版本语法尝试使用逗号或多个过滤条件。你也可以先用更宽的方式观察异常输出再收敛关键字。不要盲目把一长串异常名全部塞进去。我的建议是首机会异常只在短时间窗口内使用并且必须加 -n。它是精确排查工具不是长期值守工具。5. 用-f做异常过滤从异常风暴里筛出关键现场首机会异常最大的问题是噪声。尤其是 .NET 程序正常运行过程中也可能出现大量可处理异常。如果全部生成 Dump磁盘和分析人员都会被淹没。上图表达的是过滤逻辑大量异常进入过滤器只有符合关键字的异常被保留下来最终生成 Dump。这里的重点不是“抓得越多越好”而是“抓到和问题相关的那一次”。例如 .NET 空引用异常procdump -ma -e 1 -f NullReferenceException -n 2 MyApp.exe D:\Dumps\NullRef例如 .NET 内存溢出异常procdump -ma -e 1 -f OutOfMemoryException -n 1 MyApp.exe D:\Dumps\OOM例如原生访问违规procdump -ma -e 1 -f 0xC0000005 -n 2 MyApp.exe D:\Dumps\AccessViolation过滤关键字建议从“异常类型名、异常代码、日志里反复出现的关键片段”里选择不建议凭感觉瞎写。如果过滤条件太窄可能完全抓不到如果过滤条件太宽又会变成异常风暴。过滤本质上是在精确性和召回率之间做取舍。6. .NET 程序异常抓取建议.NET 程序的异常抓取要更谨慎。因为托管程序里很多异常并不代表崩溃运行时、框架、业务代码都可能主动抛出并捕获异常。如果程序明确崩溃仍然建议先从未处理异常开始procdump -ma -e -n 1 MyApp.exe D:\Dumps\DotNetCrash如果程序不崩溃但日志显示业务异常反复出现可以使用首机会加过滤procdump -ma -e 1 -f System.NullReferenceException -n 2 MyApp.exe D:\Dumps\DotNetNullRef如果是疑似托管内存问题可以关注 OutOfMemoryExceptionprocdump -ma -e 1 -f System.OutOfMemoryException -n 1 MyApp.exe D:\Dumps\DotNetOOM.NET Dump 后续分析通常需要 WinDbg SOS或者结合 dotnet-dump、Visual Studio 等工具继续看托管堆、异常对象、线程栈和 GC 状态。不要看到 TaskCanceledException、OperationCanceledException 就直接判断为故障。这类异常在异步取消、超时控制、请求中断场景中可能是业务设计的一部分。7. 原生 SEH 异常重点看异常代码原生程序、驱动相关用户态组件、C/C 模块、插件 DLL 崩溃时异常代码通常非常关键。相比托管异常类型名原生异常更常见的是十六进制异常代码。几个常见代码可以先记住异常代码常见含义排查关注点0xC0000005访问违规空指针、非法内存访问、模块冲突0xC00000FD栈溢出递归、栈耗尽、异常调用链0xC0000094整数除零数据校验、计算逻辑缺陷0xC0000409栈缓冲区溢出安全保护触发、内存破坏例如抓访问违规procdump -ma -e 1 -f 0xC0000005 -n 2 MyApp.exe D:\Dumps\NativeAV如果程序会直接崩溃也可以先抓未处理异常procdump -ma -e -n 1 MyApp.exe D:\Dumps\NativeUnhandled原生崩溃分析时不要只看异常代码还要结合异常线程栈、故障模块、模块签名、版本号和最近更新记录。企业桌面环境里很多原生崩溃不是主程序本体问题而是插件、输入法、安全软件、DLP、EDR、打印驱动、Office 加载项或 Shell 扩展注入导致的。8. 等待进程启动与进程终止兜底有些问题不是进程已经在那里等你排查而是进程偶尔启动、偶尔退出甚至启动后很快崩溃。这类场景下先手动找 PID 再附加往往已经晚了。上图对应两个常用思路-w 等待进程出现-t 在进程终止时兜底抓取。前者解决“进程还没启动”的问题后者解决“进程退出太快”的问题。等待目标进程出现并监视未处理异常procdump -ma -e -w MyService.exe -n 2 D:\Dumps\SvcCrash进程终止时抓一份 Dumpprocdump -ma -t -n 1 MyApp.exe D:\Dumps\OnExit如果目标是服务类程序我更推荐先用 -w。因为很多服务进程在重启、拉起、崩溃恢复过程中窗口很短手动操作很容易错过。注意-t 是进程终止时触发不等于一定能解释“为什么崩溃”。如果进程是正常退出Dump 也可能只是退出现场。要结合事件日志、服务控制管理器日志和应用自身日志一起看。9. 输出策略目录、Dump 类型和数量控制异常触发最怕两件事第一抓不到第二抓太多。前者没有证据后者会把磁盘和分析过程拖垮。稳妥的策略是输出目录固定、Dump 类型明确、数量必须限制。我建议所有异常触发都使用目录输出例如D:\Dumps\Unhandled D:\Dumps\FirstChance D:\Dumps\OOM D:\Dumps\NativeAV不要把所有 Dump 扔到一个目录里。后续一旦生成多份文件很难判断是哪类触发、哪个问题、哪次排查。Dump 类型也要有取舍Dump 类型适用建议-ma信息最完整适合首次定位、托管堆、复杂崩溃-mp体积更友好适合空间有限或较长观察期默认 mini体积小但复杂问题可能信息不足首次定位建议优先 -ma抓到关键现场后再考虑是否改用 -mp 控制体积。无论用 -ma 还是 -mp长时间监控都必须加 -n。不加次数限制就是把磁盘风险交给运气。10. 实战推荐异常抓取优先级异常触发的选择顺序可以压缩成一句话先未处理再首机会先少量抓再扩大范围先目录化再分析。上图对应的是我在现场比较推荐的异常抓取策略第一轮先抓未处理异常确认是否能拿到崩溃现场第二轮如果怀疑异常被吞掉再开启首机会异常第三轮使用 -f 收敛关键字最后一定用 -n 控制数量用独立目录保存证据。是否程序异常或闪退是否明确崩溃先用 -e 抓未处理异常观察日志和异常关键字短时间使用 -e 1配合 -f 过滤关键异常使用 -n 控制数量输出到独立 Dump 目录WinDbg / VS / dotnet-dump 分析这套流程的重点不是命令漂亮而是让排障动作可控知道自己为什么抓、抓哪类异常、最多抓几份、抓完怎么分析。11. 即拿即用命令清单下面这些命令适合现场快速改造。实际使用时把进程名、PID 和 Dump 路径替换成自己的环境即可。11.1 未处理异常稳定首选procdump -ma -e -n 1 MyApp.exe D:\Dumps\Unhandled适合程序明确崩溃、闪退、异常退出的场景。11.2 首机会异常 过滤procdump -ma -e 1 -f NullReferenceException -n 2 MyApp.exe D:\Dumps\FirstChanceKey适合异常被程序捕获、日志里出现明确异常关键字的场景。11.3 原生访问违规procdump -ma -e 1 -f 0xC0000005 -n 2 MyApp.exe D:\Dumps\AccessViolation适合 C/C 模块、插件 DLL、原生组件崩溃。11.4 进程终止兜底procdump -ma -t -n 1 MyApp.exe D:\Dumps\OnExit适合进程异常退出、快速消失、用户反馈“打开一下就没了”的场景。11.5 等待服务进程出现procdump -ma -e -w MyService.exe -n 2 D:\Dumps\SvcCrash适合服务重启、按需启动、登录后拉起、启动窗口很短的进程。11.6 .NET OOM 专项procdump -ma -e 1 -f OutOfMemoryException -n 1 MyApp.exe D:\Dumps\DotNetOOM适合托管程序内存异常但后续必须结合托管堆分析不能只看 Dump 文件大小下结论。12. 常见问题和踩坑提醒12.1 为什么未处理异常抓不到可能原因是异常被程序内部捕获了或者实际故障不是异常而是卡死、死锁、阻塞、CPU 飙高、窗口未响应。这时可以改用 -e 1 首机会异常或者回到 6.6 中的 CPU、内存、挂起触发条件。12.2 为什么首机会异常抓太多这是正常现象。很多程序内部会频繁抛出并处理异常。处理办法是加 -f 过滤缩短观察时间并用 -n 限制最多生成几份 Dump。12.3 为什么 Dump 很大如果使用 -ma完整 Dump 会包含大量内存信息体积可能非常大。首次定位可以接受但长期观察不应无脑使用。空间有限时可以考虑 -mp但复杂托管问题仍可能需要完整 Dump。12.4 为什么进程名方式不准如果同名进程有多个实例进程名方式可能不够精确。建议先用任务管理器、Process Explorer 或 PowerShell 确认 PID再使用 PID 抓取。Get-ProcessMyApp|Select-ObjectId,ProcessName,Path12.5 为什么服务进程权限不足服务进程、系统进程、高权限进程通常需要管理员权限。建议在管理员命令行中运行 ProcDump并确保 Dump 输出目录可写。不要把 Dump 保存到 OneDrive 同步目录、用户桌面、网络不稳定共享路径。崩溃现场写文件越简单越好。13. 小结这一篇的重点不是让你背下所有参数而是建立一个清晰的异常抓取判断顺序。ProcDump 的异常触发要服务于证据链而不是为了显得命令复杂。最稳妥的路径是先抓未处理异常 再看是否需要首机会异常 首机会必须加过滤 长时间监控必须加 -n Dump 必须放到独立目录常用命令可以记成下面三类:: 未处理异常第一轮推荐 procdump -ma -e -n 1 MyApp.exe D:\Dumps\Unhandled :: 首机会异常 过滤短时窗口使用 procdump -ma -e 1 -f NullReferenceException -n 2 MyApp.exe D:\Dumps\FirstChance :: 进程终止兜底 procdump -ma -t -n 1 MyApp.exe D:\Dumps\OnExit一句话总结未处理异常负责抓崩溃现场首机会异常负责抓被吞掉的异常-f 负责降噪-n 负责控盘。真正成熟的异常排障不是“Dump 抓得越多越好”而是每一份 Dump 都能回答一个明确问题哪个进程、哪个异常、哪个模块、哪条调用栈、为什么发生。 返回顶部点击回到顶部