• .NET程序崩溃了怎么抓 Dump ? 我总结了三种方案


    引用网址:https://zhuanlan.zhihu.com/p/375301879

    一:背景

    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在抓取的过程中报错了,原因是进程已退出,不管怎么说这个要看你运气了哈,这里的 -e 是 exception 的简写,具体可参见官方文档: https://docs.microsoft.com/zh-cn/sysinternals/downloads/procdump。

    -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

    发布于 2021-05-26 09:29
  • 相关阅读:
    leetcode 1301. 最大得分的路径数目
    LeetCode 1306 跳跃游戏 III Jump Game III
    LeetCode 1302. 层数最深叶子节点的和 Deepest Leaves Sum
    LeetCode 1300. 转变数组后最接近目标值的数组和 Sum of Mutated Array Closest to Target
    LeetCode 1299. 将每个元素替换为右侧最大元素 Replace Elements with Greatest Element on Right Side
    acwing 239. 奇偶游戏 并查集
    acwing 238. 银河英雄传说 并查集
    acwing 237程序自动分析 并查集
    算法问题实战策略 MATCHORDER 贪心
    Linux 安装Redis全过程日志
  • 原文地址:https://www.cnblogs.com/bruce1992/p/16032647.html
Copyright © 2020-2023  润新知