本文来告诉大家如何一步步搭建一个 DUMP 分析平台,核心是用来分析桌面端的应用软件,如 WPF 软件的 DUMP 文件。在开始之前需要说明的是,如果桌面端软件使用纯 WPF 实现,中途没有调用不安全的 C++ 库,那么 DUMP 平台几乎无用,原因是 WPF 是 .NET 应用,而 .NET 是安全的,除非是系统环境问题,否则依靠捕获异常所拿到的信息就完全超过了 DUMP 能获取的信息。因此本文的核心功能是提供给调用了不安全的 C++ 等语言编写的库的桌面端软件 DUMP 分析平台

对于 C++ 等不安全语言编写的逻辑,将会比较多依赖 DUMP 的调试。但对于 dotnet 应用来说,依靠异常就完全足够了,只要遵循规范,那么基本只有内存爆了、无限递归等很有限的几个问题才能玩炸,其他情况都能稳稳接住

在搭建 DUMP 平台的工作中,可以分为两个部分,第一个部分需要做到自己的构建平台上,在构建的时候需要保存足够的符号文件用于后续调试。另一个是通过 WinDbg 进行的稍微自动化的自动读取 DUMP 信息导出的工作,以及通过这些导出的内容再次做处理的工作

敲黑板,如果是 .NET 的应用,如 WPF 或 WinForms 应用,还请优先搭建日志模块,将异常记录到日志将能解决几乎所有的问题。如果靠异常也不能定位,那么靠 DUMP 基本也是不能的,除非你更熟悉 DUMP 而不是 .NET 机制。更多关于 .NET 的异常处理请看 一文看懂 .NET 的异常处理机制、原则以及最佳实践 - walterlv

构建平台保存符号

在使用 DUMP 调试的过程中,很重要一定就是需要有符号 PDB 文件。在后续的分析过程需要用到符号文件。在自己的构建平台,如 GitHub 的 Runner 自托管服务上需要自行部署

只需要将保存的符号文件和 dll 和 exe 等文件,开启文件服务器或者作为网络磁盘挂载等都可以作为符号服务器。关于开启文件服务器,我推荐使用此方法 dotnet serve 一句话开启文件服务器 通过 HTTP 将文件共享给其他设备

想要被 WinDbg 所使用的符号文件服务器,需要将符号文件按照一定的格式存放在文件夹中,格式如下

xx.dll -> GUID -> xx.dll

此时需要用到 symstore 工具,这个工具和 WinDbg 工具都是放在 WDK 工具集里面,建议不要使用绿色版,而是自行安装 WDK 工具集。以下是安装 WDK 工具集的方法

先进入到官方文档 Download the Windows Driver Kit (WDK) - Windows drivers 按照步骤,先安装 VS 然后安装 Windows SDK 然后安装 WDK 工具集

安装 WDK 推荐安装到默认的路径,也就是 c:\Program Files (x86)\Windows Kits\10 文件夹

接着可以在打包平台上使用 symstore 工具将自己的应用存放到符号服务器的文件夹

symstore.exe add /r /t [项目名] /s [符号服务器文件夹] /f [本地构建输出文件夹] 

如符号文件夹是 C:\lindexi\Symbol 文件夹,而本地构建输出文件夹是 F:\code\lindexi\lindexi\bin\Debug\net5.0\ 文件夹,此项目名是 LindexiDoubi 那么命令如下

symstore.exe add /r /t LindexiDoubi /s "C:\lindexi\Symbol" /f "F:\code\lindexi\lindexi\bin\Debug\net5.0" 

上面命令的 add 就是添加保存的文件,而 /r 表示 /f 的本地构建输出文件夹的内容需要递归文件夹,也就是获取文件夹里面的文件夹的内容

调用上面命令之后,将会在 C:\lindexi\Symbol 文件夹里面创建如下内容

│  pingme.txt
│  
├─000Admin
│      0000000001
│      history.txt
│      lastid.txt
│      server.txt
│      
├─lindexi.exe
│  └─F78EFB318000
│          lindexi.exe
│          refs.ptr
│          
└─lindexi.pdb
    └─4E7E5EA6C9414D2B8B0204E7D146D3901
            lindexi.pdb
            refs.ptr

在新版本的 .NET 里面,将使用 Portable PDB 这将会让旧版本的 symstore 失败。也就是说如果你的 symstore 无法存储 PDB 文件时,请确定你的 symstore 是使用最新的 WDK 工具

此时只需要在 000Admin 文件夹所在的文件夹,如 C:\lindexi\Symbol 文件夹开启文件服务器,那么此文件夹服务器就是符号服务器

使用 WinDbg 分析

在从用户端或开发端收集到 DUMP 文件之后,可以利用上面步骤创建出来的符号服务器和 DUMP 文件借助 WinDbg 来分析

我推荐你在自动分析服务器上,先使用 WinDbg 手动分析一个 DUMP 用来确定你的本地环境,以及让本地缓存足够的符号文件。我的符号文件大概有 10G 左右,大部分都是各个版本系统的文件

在 Windows 下可以说 WinDbg 是最强的调试工具,自然 WinDbg 工具也可以了命令行版本的自动化方法,可以将命令通过命令行方式传入到 WinDbg 中,让 WinDbg 执行,然后输出为本地文件。这样做的优势在于可以利用 WinDbg 加上预定义的命令进行自动化调试 DUMP 文件,然后输出的日志可以进入下一个步骤的处理,获取到信息

每个团队的需求都不同,因此也不存在万能的预定义命令。如我所在的团队,只需要处理甩锅就可以了,我只需要了解到当前 DUMP 的大概原因,通过分类算法处理 WinDbg 输出的文件,然后分为不同的其他团队就可以了

在 WinDbg 中,可以使用 -c 命令,让 WinDbg 执行预定义的命令。可以使用 -z 告诉 WinDbg 将要调试的 DMP 文件路径。通过 -y 命令可以指定上面步骤创建的符号服务器。通过 -logo 命令可以让 WinDbg 输出日志文件

格式大概如下

"C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -z [DUMP文件路径] -y "SRV*[本地缓存自定义符号文件夹]*[自己搭建的符号服务器]" -c "$<[预定义命令文件]" -logo [输出的日志文件]

例如 WinDbg 是通过 WDK 安装到默认的文件夹,可以使用 C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe 调试工具,当然也有 x86 的版本

需要调试的 DMP 文件是 F:\temp\foo.dmp 文件,而自己搭建的符号服务器以及需要做的本地符号缓存文件夹分别是 http://localhost:5000F:\lindexi\AppSymCachePath 文件夹。预定义的 WinDbg 命令放在 C:\lindexi\WinDbgFile.txt 文件。输出的日志放在 C:\lindexi\log.txt 文件

那么命令如下

"c:\Program Files (x86)\Windows Kits\10\Debuggers\x64\windbg.exe" -z F:\temp\foo.dmp -y "SRV*F:\lindexi\AppSymCachePath*http://localhost:5000" -c "$<C:\lindexi\WinDbgFile.txt" -logo C:\lindexi\log.txt

如果在 -c 命令中,传入的是命令本身,如 -c !analyze;!clrstack;qq; 而在 WinDbg 提示 The command line argument cannot specify more than one kind of debugging to start 那么就是少加了引号了。对于上面命令的路径都需要加上引号

-c "!analyze -v;!clrstack;qq;"

-c 命令中,可以加上的参数是命令,或者存放命令的文件。存放命令的文件,将一条命令放在一行里面,如下面代码

!analyze; -v
!clrstack
q

大家需要根据自己的需求,修改自己的命令文件

通过上面方法就可以自己搭建 DUMP 平台,自己需要做的就是先自己本地先跑一下,包括自己创建符号服务器,自己命令行 WinDbg 调试一下。然后就是开发自动化的逻辑

因为 WinDbg 是一个十分强大的调试工具,需要的知识也特别多,所以还请大家准备足够的精力再来开这个坑。如果不需要批量调试 DUMP 文件,不如试试将 DUMP 拖入到 VisualStudio 中,使用熟悉的 VS 调试

和大家推荐 DUMP 调试群 169225649

a (Run Script File) - Windows drivers

Debugging Tools for Windows (WinDbg, KD, CDB, NTSD) - Windows drivers

SymStore Command-Line Options - Win32 apps

Using SymStore - Win32 apps

.NET Framework system requirements

Download the Windows Driver Kit (WDK) - Windows drivers

搭建Windows符号服务器

windbg 边学边记attach 进程和open dump的两个方式查看线程的占用cpu资源

core/portable_pdb.md at main · dotnet/core


本文会经常更新,请阅读原文: https://blog.lindexi.com/post/%E6%90%AD%E5%BB%BA%E4%B8%80%E4%B8%AA%E8%87%AA%E5%8A%A8%E5%8C%96%E5%88%86%E6%9E%90-DUMP-%E5%B9%B3%E5%8F%B0.html ,以避免陈旧错误知识的误导,同时有更好的阅读体验。

如果你想持续阅读我的最新博客,请点击 RSS 订阅,推荐使用RSS Stalker订阅博客,或者收藏我的博客导航

知识共享许可协议 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。欢迎转载、使用、重新发布,但务必保留文章署名林德熙(包含链接: https://blog.lindexi.com ),不得用于商业目的,基于本文修改后的作品务必以相同的许可发布。如有任何疑问,请 与我联系

微软最具价值专家


无盈利,不卖课,做纯粹的技术博客

以下是广告时间

推荐关注 Edi.Wang 的公众号

欢迎进入 Eleven 老师组建的 .NET 社区

以上广告全是友情推广,无盈利