.NET -- 使用Dump文件分析异常

这篇具有很好参考价值的文章主要介绍了.NET -- 使用Dump文件分析异常。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1. Dump文件

2. 程序崩溃时自动生成Dump文件

2.1 注册表生成

2.2 代码生成

3. 手动生成Dump文件

3.1 任务管理器生成

3.2 VS生成

4. Dump文件调试分析

4.1 简易崩溃测试代码

4.2 VS2022调试

4.3 非本机测试


1. Dump文件

Dump文件是进程的内存镜像。可以把程序的执行状态通过调试器保存到dump文件中。主要是用来在系统中出现异常或者崩溃的时候来生成dump文件,然后用调试器进行调试,这样就可以快速定位到程序崩溃位置,对问题进行排查。

2. 程序崩溃时自动生成Dump文件

2.1 注册表生成

Win + R 输入regedit打开注册表

找到如下项:

计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps

 新建如下:

.NET -- 使用Dump文件分析异常​ 

说明:

DumpCount: 文件数量      ( 值设为0即禁用此功能)
DumpFolder:存储位置    (Dump文件名:(应用程序名称全称.进程号.dmp))
DumpType:   dmp文件类型  (1:mini 2:full)

                        mini:只包含某个线程和部分模块的信息。

                        full: 包含了某个进程完整的地址空间数据,以及许多用于调试的信息 

2.2 代码生成

使用win32 api :MiniDumpWriteDump  实现

封装了DumpHelper类

using System.Runtime.InteropServices;

namespace DumpTest
{
    public class DumpHelper
    {
        [Flags]
        public enum DumpType : uint
        {
            // From dbghelp.h:
            MiniDumpNormal = 0x00000000,                        //只包含调用栈相关信息
            MiniDumpWithDataSegs = 0x00000001,                  //包含已加载的模块的数据段信息,比如全局变量
            MiniDumpWithFullMemory = 0x00000002,                //包含全部可访问的内存
            MiniDumpWithHandleData = 0x00000004,                //包含句柄信息
            MiniDumpFilterMemory = 0x00000008,                  //过滤一些敏感信息,保护重建调用栈需要的信息
            MiniDumpScanMemory = 0x00000010,                    //扫描,以包含引用内存
            MiniDumpWithUnloadedModules = 0x00000020,           //包含最近被卸载的模块信息
            MiniDumpWithIndirectlyReferencedMemory = 0x00000040,//包含未直接引用的内存
            MiniDumpFilterModulePaths = 0x00000080,             //过滤某块的路径信息
            MiniDumpWithProcessThreadData = 0x00000100,         //包含完整的进程和线程信息
            MiniDumpWithPrivateReadWriteMemory = 0x00000200,    //包含页面属性为 PAGE_READWRITE 的页面
            MiniDumpWithoutOptionalData = 0x00000400,           //不包含可选数据
            MiniDumpWithFullMemoryInfo = 0x00000800,            //包含内存区信息
            MiniDumpWithThreadInfo = 0x00001000,                //包含线程状态信息
            MiniDumpWithCodeSegs = 0x00002000,                  //包含所有代码和有关的内存段
            MiniDumpWithoutAuxiliaryState = 0x00004000,         //关闭辅助内存收集
            MiniDumpWithFullAuxiliaryState = 0x00008000,        //使用所有的内存收集器
            MiniDumpWithPrivateWriteCopyMemory = 0x00010000,    //包含页面属性为 PAGE_WRITECOPY 的页面
            MiniDumpIgnoreInaccessibleMemory = 0x00020000,      //忽略不可访问的页面
            MiniDumpValidTypeFlags = 0x0003ffff,                //包含安全令牌相关信息
        };

        //typedef struct _MINIDUMP_EXCEPTION_INFORMATION {
        //    DWORD ThreadId;
        //    PEXCEPTION_POINTERS ExceptionPointers;
        //    BOOL ClientPointers;
        //} MINIDUMP_EXCEPTION_INFORMATION, *PMINIDUMP_EXCEPTION_INFORMATION;
        [StructLayout(LayoutKind.Sequential, Pack = 4)]  // Pack=4 is important! So it works also for x64!
        struct MiniDumpExceptionInformation
        {
            public uint ThreadId;
            public IntPtr ExceptioonPointers;
            [MarshalAs(UnmanagedType.Bool)]
            public bool ClientPointers;
        }

        //BOOL
        //WINAPI
        //MiniDumpWriteDump(
        //    __in HANDLE hProcess,  :要转储的进程句柄。
        //    __in DWORD ProcessId,  :要转储的进程ID。
        //    __in HANDLE hFile,     :通过 CreateFile() 等 API 打开的,用来保存 dump 的文件句柄。
        //    __in MINIDUMP_TYPE DumpType,  :转储类型。此参数会直接影响转储文件的大小
        //    __in_opt PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,     :指向异常信息结构 MiniDumpExceptionInformation 的指针。如果本参数为 NULL,则转储文件中不会包含异常信息。
        //    __in_opt PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,  :指向用户自定义信息结构的指针
        //    __in_opt PMINIDUMP_CALLBACK_INFORMATION CallbackParam        :指向回调例程 MINIDUMP_CALLBACK_INFORMATION 的指针。如果此参数为NULL,转储过程中不会执行任何回调例程。
        //    );
        [DllImport("dbghelp.dll",EntryPoint = "MiniDumpWriteDump",CallingConvention = CallingConvention.StdCall,CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
        static extern bool MiniDumpWriteDump(
          IntPtr hProcess,
          uint processId,
          IntPtr hFile,
          uint dumpType,
          ref MiniDumpExceptionInformation expParam,
          IntPtr userStreamParam,
          IntPtr callbackParam);

        [DllImport("kernel32.dll", EntryPoint = "GetCurrentThreadId", ExactSpelling = true)]
        static extern uint GetCurrentThreadId();

        [DllImport("kernel32.dll", EntryPoint = "GetCurrentProcess", ExactSpelling = true)]
        static extern IntPtr GetCurrentProcess();

        [DllImport("kernel32.dll", EntryPoint = "GetCurrentProcessId", ExactSpelling = true)]
        static extern uint GetCurrentProcessId();

        public static bool WriteDump(string fileName)
        {
            return Write(fileName, DumpType.MiniDumpNormal);
        }
        public static bool Write(string fileName, DumpType dumpType)
        {
            var path = Path.Combine(Environment.CurrentDirectory, fileName);
            using var fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.None);
            MiniDumpExceptionInformation exp;
            exp.ThreadId = GetCurrentThreadId();
            exp.ClientPointers = false;
            exp.ExceptioonPointers = Marshal.GetExceptionPointers();
            bool bRet = MiniDumpWriteDump(
              GetCurrentProcess(),
              GetCurrentProcessId(),
              fs.SafeFileHandle.DangerousGetHandle(),
              (uint)dumpType,
              ref exp,
              IntPtr.Zero,
              IntPtr.Zero);
            return bRet;
        }
    }
}

调用:

当某个系统异常未被捕获时,调用方法生成Dump文件

AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(
    (obj, args) => DumpHelper.WriteDump($"Error_{DateTime.Now.ToString("yyyy_M_dd_HH_mm")}.dmp")
);

结果:

代码出现异常导致程序崩溃时,会在程序的工作目录下自动生成Dump文件,如图:

文件1:DumpType:MiniDumpWithFullMemory

文件2:DumpType:MiniDumpNormal

可以看出Dump文件保存的内容不同,文件大小差异巨大。

.NET -- 使用Dump文件分析异常

3. 手动生成Dump文件

3.1 任务管理器生成

打开任务管理器 --> 找到对应进程 --> 右击选择创建转储文件

.NET -- 使用Dump文件分析异常

创建成功如图:

.NET -- 使用Dump文件分析异常

3.2 VS生成

在代码中断时,调试 --> 将转储另存为 --> 设置文件路径&文件名

.NET -- 使用Dump文件分析异常

4. Dump文件调试分析

4.1 简易崩溃测试代码

var lists=new List<string>() {"a","b","c"};
Console.WriteLine(lists[3]);

4.2 VS2022调试

运行DumpTest.exe,程序崩溃后,自动生成Dump文件

.NET -- 使用Dump文件分析异常

用VS打开.dmp文件

.NET -- 使用Dump文件分析异常​ 

点击右侧"使用混合进行调试" -- > 就定位到异常位置,如图

.NET -- 使用Dump文件分析异常

 得出结论:列表引用超范围的异常

4.3 非本机测试

若将Dump文件拷贝到另一台PC上调试时,则需要将以下3个文件都拷下来,放在同一目录下,必须保证pdb与出问题的exe是同一时间生成的。

.NET -- 使用Dump文件分析异常

参考:

【1】 MiniDumpWriteDump function (minidumpapiset.h) - Win32 apps | Microsoft Learn

【2】Dump文件的生成和使用_思影影思的博客-CSDN博客_dump

【3】C#使用MiniDump捕获异常 - 你不知道的浪漫 - 博客园 (cnblogs.com)

【4】向大厂看齐!为自己的程序增加自动转储的功能! - 知乎 (zhihu.com)文章来源地址https://www.toymoban.com/news/detail-439526.html

到了这里,关于.NET -- 使用Dump文件分析异常的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 使用IDA查看汇编代码,结合安卓系统生成的Tombstone文件,分析安卓app程序崩溃问题

    目录 1、IDA工具介绍 2、产品及问题场景描述 3、查看Tombstone文件

    2024年02月13日
    浏览(49)
  • Docker 中的 .NET 异常了怎么抓 Dump

    有很多朋友跟我说,在 Windows 上看过你文章知道了怎么抓 Crash, CPU爆高,内存暴涨 等各种Dump,为什么你没有写在 Docker 中如何抓的相关文章呢?瞧不上吗? 哈哈,在DUMP的分析旅程中,跑在 Docker 中的 .NET 占比真的不多,大概10个dump有 1-2 个是 docker 中的,市场决定了我的研究

    2024年02月11日
    浏览(31)
  • Docker 中的 .NET 异常了怎么抓 Dump (转载)

    1. 讲故事 有很多朋友跟我说,在 Windows 上看过你文章知道了怎么抓 Crash, CPU爆高,内存暴涨 等各种Dump,为什么你没有写在 Docker 中如何抓的相关文章呢?瞧不上吗? 哈哈,在DUMP的分析旅程中,跑在 Docker 中的 .NET 占比真的不多,大概10个dump有 1-2 个是 docker 中的,市场决定了

    2024年02月12日
    浏览(48)
  • Java的dump文件分析及JProfiler使用

    从软件开发的角度上,dump文件就是当程序产生异常时,用来记录当时的程序状态信息(例如堆栈的状态),用于程序开发定位问题。 idea配置发生OOM的时候指定路径生成dump文件 2.1 下载 JProfiler下载: 链接:https://pan.baidu.com/s/1WXCc4FMOC3QQtjkhY4Qeow 提取码:5xrm 版本:JProfiler 12.0.4

    2024年02月06日
    浏览(50)
  • 使用Windbg静态分析dump文件的一般步骤详解

    目录   1、概述 2、静态分析dump文件的一般步骤 2.1、查看异常类型

    2024年02月07日
    浏览(40)
  • Linux下ROS程序崩溃,程序段错误process has died [pid 20083, exit code -11, cmd /home GDB core dump 调试

           在Linux下可通过core文件来获取当程序异常退出(如异常信号SIGSEGV, SIGABRT等)时的堆栈信息。 core dump叫做核心转储 ,当程序运行过程中发生异常的那一刻的一个内存快照,操作系统在程序发生异常而异常在进程内部又没有被捕获的情况下,会把进程此刻内存、寄存器状态

    2024年02月12日
    浏览(47)
  • 记一次 .NET 某企业采购平台 崩溃分析

    前段时间有个朋友找到我,说他们的程序有偶发崩溃的情况,让我帮忙看下怎么回事,针对这种 crash 的程序,用 AEDebug 的方式抓取一个便知,有了 dump 之后接下来就可以分析了。 既然是程序的崩溃,我们可以像看蓝屏一下看dump文件,使用 !analyze -v 命令即可。 从上面的信息

    2024年02月11日
    浏览(53)
  • 记一次 .NET某防伪验证系统 崩溃分析

    昨晚给训练营里面的一位朋友分析了一个程序崩溃的故障,因为看小伙子昨天在群里问了一天也没搞定,干脆自己亲自上阵吧,抓取的dump也是我极力推荐的用 procdump 注册 AEDebug 的方式,省去了很多沟通成本。 windbg有一个非常强大的点就是当你双击打开后,会自动帮你切换到

    2024年03月28日
    浏览(63)
  • 记一次 .NET 某企业内部系统 崩溃分析

    前些天有位朋友找到我,说他的程序跑着跑着就崩溃了,让我看下怎么回事,其实没怎么回事,抓它的 crash dump 就好,具体怎么抓也是被问到的一个高频问题,这里再补一下链接: [.NET程序崩溃了怎么抓 Dump ? 我总结了三种方案] https://www.cnblogs.com/huangxincheng/p/14811953.html ,采用

    2024年02月10日
    浏览(53)
  • 记一次 .NET某股票交易软件 灵异崩溃分析

    在dump分析的旅程中也会碰到一些让我无法解释的灵异现象,追过这个系列的朋友应该知道,上一篇我聊过 宇宙射线 导致的程序崩溃,后来我又发现了一例,而这一例恰恰是高铁的 列控连锁一体化 程序,所以更加让我确定这是由于 电离辐射 干扰了计算机的 数字信号 导致程

    2024年02月04日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包