乐趣区

关于.net:NET程序崩溃了怎么抓-Dump-我总结了三种方案

一:背景

1. 讲故事

最近几天接到了几个 crash 的求助,可能这几个敌人没玩过怎么去生成 dump,只能手把手教,感觉也不是一个方法,所以有必要总结一下,后续再有敌人征询的话,我就能够把这篇文章丢过来了😏😏😏,好了,我大略总结了上面三种形式:

  • procdump -e
  • procdump -> AEDebug
  • Windows Error Reporting

老读者应该晓得,我始终都推崇 procdump 去搞定这些事件,毕竟它是一款可跨平台抓取的弱小乖巧工具。

二: 实现可测试案例

从 dump 样本来看,web 类的程序是最多的,所以这里我就以 Asp.NET MVC 5 作为案例,在 RouteConfig 类中我应用一个 Timer 一直的抛出异样,目标就是把 w3wp 过程给弄挂掉,参考代码如下:


    public class RouteConfig
    {
        public static Timer timer;
        public static void RegisterRoutes(RouteCollection routes)
        {
            timer = new Timer(new TimerCallback(m =>
            {var r = 10 / Convert.ToInt32("0");
            }), null, 60000, 5000);

            routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

            routes.MapRoute(
                name: "Default",
                url: "{controller}/{action}/{id}",
                defaults: new {controller = "Home", action = "Index", id = UrlParameter.Optional}
            );
        }
    }

对了,必定有敌人问:为什么不在 Action 中抛异样,这是因为 Http 管道 会把这种异样包装成 http 500,所以就达不到 crash 的成果了。

接下来把程序部署到 IIS 上并运行,能够分明的看到 Windows 事件查看器 中胜利的记录到了解体信息,如下图所示:

三: 3 种抓取形式解析

1. 应用 procdump -e

这种形式简略但不太稳固,因为有几个敌人通知我,procdump 在抓取的过程中报错了,起因是过程已退出,不管怎么说这个要看你运气了哈,这里的 -eexception 的简写,具体可参见官网文档: https://docs.microsoft.com/zh…


-e    Write a dump when the process encounters an unhandled exception. Include the 1 to create dump on first chance exceptions.

残缺的参考命令如下:


C:\Windows\system32>procdump -e -ma -w w3wp E:\test

ProcDump v10.0 - Sysinternals process dump utility
Copyright (C) 2009-2020 Mark Russinovich and Andrew Richards
Sysinternals - www.sysinternals.com

Waiting for process named w3wp...

...

Press Ctrl-C to end monitoring without terminating the process.

[21:12:08] Exception: 04242420
[21:12:08] Exception: E0434352.CLR
[21:12:09] Exception: E0434352.CLR
[21:12:09] Exception: E0434352.CLR
[21:12:09] Exception: E0434352.CLR
[21:12:09] Exception: E0434352.CLR
[21:12:09] Exception: E0434352.CLR
[21:12:14] Exception: C0000094.INT_DIVIDE_BY_ZERO
[21:12:14] Unhandled: C0000094.INT_DIVIDE_BY_ZERO
[21:12:14] Dump 1 initiated: E:\test\w3wp.exe_210525_211214.dmp
[21:12:14] Dump 1 writing: Estimated dump file size is 326 MB.
[21:12:15] Dump 1 complete: 326 MB written in 1.2 seconds
[21:12:15] Dump count reached.

从输入信息看曾经胜利抓取了 dump 文件,如果你的机器有多个 w3wp,能够将其替换成 pid,参考命令如下:


C:\Windows\system32>procdump -e -ma 9320 E:\test

2. 将 procdump 作为 AeDebug 的默认调试器

它的大略运作原理是:当程序呈现了未解决异样,此时会激活操作系统的 Win32 unhandled exception filter,这个过滤器会调用注册表中 HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug 节点配置的调试器,也就是我的 Procdump,要将 procdump 送到注册表的 AeDebug 节点,能够应用 -i 进行注册。


-i    Install ProcDump as the AeDebug postmortem debugger. Only -ma, -mp, -d and -r are supported as additional options.

残缺参考命令如下:


C:\Windows\system32>procdump -ma -i E:\test

ProcDump v10.0 - Sysinternals process dump utility
Copyright (C) 2009-2020 Mark Russinovich and Andrew Richards
Sysinternals - www.sysinternals.com

Set to:
  HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug
    (REG_SZ) Auto     = 1
    (REG_SZ) Debugger = "C:\xcode\soft\Procdump\procdump.exe" -accepteula -ma -j "E:\test" %ld %ld %p

Set to:
  HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug
    (REG_SZ) Auto     = 1
    (REG_SZ) Debugger = "C:\xcode\soft\Procdump\procdump.exe" -accepteula -ma -j "E:\test" %ld %ld %p

ProcDump is now set as the Just-in-time (AeDebug) debugger.

从输入信息看曾经胜利将其送入到注册表了,接下来能够关上 注册表编辑器 去验证。

最初就是把 web 跑起来,1min 之后就会胜利的看到 E:\test 下的 dump 文件啦,截图如下:

从图中看有 2 个 dump,具体为什么是 2 个我就不论了,就怕不生成。😏😏😏

3. 借助 Windows Error Reporting 生成

它的大略运作原理是借助 windows 自带的 Windows Error Reporting 服务去帮忙咱们生成程序的 crash dump,要实现的话,必须开启这个服务并且在注册表中配置好你要抓取的 exe 程序,配置起来有点繁琐,这里有一个 bat 脚本,间接运行即可,简略粗犷。


SET DMPPATH=E:\test
SC CONFIG WerSvc START= AUTO
NET START WerSvc
ECHO 启用实现
 
REG DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger /f
REG DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger /f
 
REG DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger /f
REG DELETE HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\DbgManagedDebugger /f
 
ECHO 删除实现
 
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\w3wp.exe"  /f
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\w3wp.exe"  /t REG_SZ  /v DumpFolder /d   %DMPPATH% /f
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\w3wp.exe"  /t REG_DWORD   /v DumpCount /d  2 /f
REG ADD "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps\w3wp.exe"  /t REG_DWORD   /v DumpType /d  2 /f
 
ECHO 启用实现
 
PAUSE 

有 3 个参数须要简略解释一下。

  • DumpFolder:dump 的寄存门路
  • DumpCount:最多保留几个 dump 文件
  • DumpType:0:Custom dump. 1:Mini dump. 2:Full dump

bat 执行实现后,能够到注册表中验证一下。

接下来把 web 跑起来,1min 之后你就会看到生成的 dump 文件了,截图如下:

三:总结

对于抓取程序 crash 的 dump,这三种形式基本上就能够做到十拿九稳,总结完后,对你对我都是节俭贵重的工夫😘😘😘。

更多高质量干货:参见我的 GitHub: dotnetfly

退出移动版