通过WinDbg分析转储文件
在调试过程中回遇到一些很奇怪的问题,编译器调试无法正常定位问题,所以需要WinDbg,这篇博客是对照多篇文档的简易的入门整理
一、必备知识
1.1、下载WinDbg
微软文档
下载 Windows 调试工具 - WinDbg - Windows drivers | Microsoft Learn
WinDbg Preview 是 WinDbg 的新版本。WinDbg Preview 使用与 WinDbg 相同的基础引擎,因此所有命令、扩展和工作流的运行仍然与从前相同。
文档中有三种下载方式,我使用了应用商店的方式,可以在没有环境的机器上独立使用;
WinDbg Preview - Microsoft Store 应用程序
1.2、WinDbg命令行选项
WinDbg 命令行选项 - Windows drivers | Microsoft Learn
1.3、微软系列文档
使用 WinDbg 进行调试 - Windows drivers | Microsoft Learn
1.4、用户模式转储文件类型
1.5、 完整用户模式转储
完整的用户模式转储_是基本的用户模式转储文件。 完整的用户模式转储文件包括:
- 进程的整个内存空间。
- 程序的可执行映像。
- 句柄表。
- 其他信息,可帮助调试器在转储发生时重建正在使用的内存。
1.6、Minidumps
小型转储文件的大小和内容因要转储的程序、执行转储的应用程序和所选选项而异。 有时,小型转储文件的大小适中,并且包含完整的内存和句柄表。 在其他情况下,小型转储文件要小得多。 例如,小型转储文件可能仅包含有关单个线程的信息,也可能仅包含有关堆栈中引用的模块的信息。
术语 minidump 具有误导性,因为最大的小型转储文件包含的信息比完整的用户模式转储文件更多。
二、在程序崩溃时自动创建dump
\注册表中位置:计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\Windows Error Reporting\LocalDumps
新建REG_DWORD类型、名称为DumpCount的元素值为10;
新建REG_EXPAND_SZ类型、名称为DumpFolder的元素值为%LOCALAPPDATA%\CrashDumps;
DUMP存放位置:C:\Users\duwenlong\AppData\Local\CrashDumps
三、开始使用WinDbg分析mimidumps转储文件
因为项目时间原因,而且这篇不是系列的文章,所以我只记录如何分析转储文件;
启动WinDbg通过从“文件”菜单中选择“打开故障转储”或按 Ctrl+D 打开转储文件。 出现“ 打开故障转储 ”对话框时,在“文件名”框中输入故障转储文件的完整路径和 名称 ,或使用对话框选择正确的路径和文件名。 选择正确的文件后,选择“ 打开”。
等待加载完成:
我创建一个示例程序,点击Button后thow一个异常,下面的命令窗口中输入“!analyze -v”命令,工具就对dump文件进行分析;
可以看到关键报错信息
MethodDesc: 00007ffe75b0b4e8
Method Name: WpfApp4.MainWindow.Button_Click(System.Object, System.Windows.RoutedEventArgs)
Class: 00007ffe75af6d98
MethodTable: 00007ffe75b0b5c8
mdToken: 0000000006000009
Module: 00007ffe756f68d8
IsJitted: yes
Current CodeAddr: 00007ffe75d76530
Version History:
ILCodeVersion: 0000000000000000
ReJIT ID: 0
IL Addr: 00000226d51a20e4
CodeAddr: 00007ffe75d76530 (MinOptJitted)
NativeCodeVersion: 0000000000000000
Source file: D:\demo\WpfApp4\WpfApp4\MainWindow.xaml.cs @ 32
下面还有关键的代码位置信息
STACK_COMMAND: ~0s; .ecxr ; kb
FAULTING_SOURCE_LINE: D:\demo\WpfApp4\WpfApp4\MainWindow.xaml.cs
FAULTING_SOURCE_FILE: D:\demo\WpfApp4\WpfApp4\MainWindow.xaml.cs
FAULTING_SOURCE_LINE_NUMBER: 32
FAULTING_SOURCE_CODE:
28: private void Button_Click(object sender, RoutedEventArgs e)
29: {
30: var f = 0;
31: var g = 0;
32: var gfg = f / g;
33: }
34: }
35: }
这里能初步的看到NET的崩溃问题,代码位置;
有一些常用的指令类型
- 常规指令,控制被调试程序: kv, g, lm, dds等
- 元指令,控制调试器: .sympath, .cls
- 扩展指令: !anlayze, !teb, !handle
定位错误
- .ecxr 指令 定位到当前异常的上下文
- !anlayze -v 可以让调试器自动分析得到基本的异常信息
但是虽然我也是.NET但是崩问题发生时有时候不是在.NET内的。所以上面的例子其实看不到问题点,还是很麻烦。
找了很久发现.NET的话买本《.NET高级调试》系统的学习一下,比较好。这篇博客就写这么多。后续会整理《.NET高级调试》学习笔记。