用 WinDbg + SOS 解读崩溃转储 ── 采集之后的实务分析入门
· 小村 豪 · WinDbg, SOS, 崩溃转储, .NET, CSharp, 调试, PDB, 故障排查, 技术咨询
之前的文章「Windows 崩溃转储采集入门」整理了用 WER LocalDumps、ProcDump、MiniDumpWriteDump 把转储文件“采集下来”的做法。不过,转储文件光是采集到手边并不会告诉你任何事情。要实际动手解读“是哪个线程”“为什么”崩溃,或者“是什么”一直握着内存不放,才能真正成为排查的素材。
本文接续采集篇,把焦点放在如何用 WinDbg 与 SOS 扩展实际读取已采集的转储文件。内容涵盖安装与符号设置、.NET 应用中不可或缺的 SOS 扩展加载、!clrstack、!dumpheap -stat 等代表性命令“该看什么、怎么判断”、原生崩溃的 !analyze -v,以及不用 WinDbg 的 dotnet-dump analyze 该如何区分使用。
1. 先说结论
- 转储分析的主角是 WinDbg(当前版本,原名 WinDbg Preview)。可用
winget install Microsoft.WinDbg或通过 Microsoft Store 获取,在 Windows 10 周年更新(1607)之后 / Windows 11 的 x64、ARM64 上均可运行。1 - 即使符号(PDB)没有正确加载,
!clrstack、!dumpheap -stat、!gcroot等命令仍会直接基于 CLR 的元数据和堆数据工作。丢失的只是托管代码的源文件名、行号,以及原生堆栈帧的符号名。不过,如果想追到源代码行,那就是另一回事了,因此常见做法是在_NT_SYMBOL_PATH中同时放入 Microsoft 的公共符号服务器与自有 PDB 的位置。2 - 在 .NET(Framework / Core / 5+)应用的转储文件中,要先加载 SOS 扩展才能看到托管侧的信息。仅靠原生的
k(显示堆栈)命令是追不到 C# 代码的。3 - 代表性的排查思路有 3 种。因异常而崩溃时走
!clrstack→!pe、内存持续增长时走!dumpheap -stat→!gcroot、原生崩溃时从!analyze -v入手。 - 不使用 WinDbg 的选项是
dotnet-dump analyze。大多数 SOS 命令都能直接沿用,但无法处理原生堆栈帧。如果手边要排查的是纯托管、不涉及原生 DLL 或 COM 的场景,这个工具的接入更轻量。4 - 本文写的是“怎么读”而不是“怎么取”。转储文件的获取方式(WER / ProcDump /
MiniDumpWriteDump)请参考采集篇,崩溃时与日志相互对照的设计,请参考「Windows 应用崩溃时保留日志与转储文件的设计」。
2. 安装 WinDbg 并设置符号
2.1 安装
当前版本的 WinDbg 可通过以下任一方式安装。1
winget install Microsoft.WinDbg
通过 Microsoft Store 安装也会得到相同的引擎,命令、扩展、工作流都是通用的。安装后会自动更新(通过 Store 或直接安装时在后台进行,通过 winget 安装时可用 winget upgrade Microsoft.WinDbg),因此不太需要为版本差异带来的行为不同而烦恼。1
2.2 打开转储文件
windbg -z C:\CrashDumps\MyApp\MyApp_20260702_101500.dmp
-z 是指定转储文件并启动的选项。通过 GUI 菜单“File > Open Dump File”也可以实现同样的效果。
2.3 设置符号路径
Windows 调试器查找符号文件(PDB)的位置,是通过 _NT_SYMBOL_PATH 环境变量,或在会话中用 .sympath 命令指定。2 实务中的基本做法是同时放入 Microsoft 的公共符号服务器与自有 PDB 的位置。
.symfix C:\Symbols\Microsoft
.sympath+ C:\Symbols\MyApp
.reload
.symfix是设置指向 Microsoft 公共符号服务器(https://msdl.microsoft.com/download/symbols)路径的快捷命令,并附带指定的本地缓存。操作系统标准 DLL 的符号会从这里自动下载。5.sympath+会把自有 PDB 的存放位置附加到已有路径之后。自有代码的 PDB 必须自行准备,不会出现在 Microsoft 的符号服务器上。- 用
.reload重新加载,确认模块列表的符号状态。
如果要用环境变量永久设置,格式如下。这种方式适合 CI 或构建服务器上的自动分析。
set _NT_SYMBOL_PATH=srv*C:\Symbols\Microsoft*https://msdl.microsoft.com/download/symbols;C:\Symbols\MyApp
符号是否正确加载,可用 lm(loaded modules)命令列出模块列表,确认目标模块是否显示为 pdb symbols。如果仍显示 deferred,说明符号还没有被解析。
3. 加载 SOS 扩展
.NET 应用的转储文件,仅靠原生的 WinDbg 命令是看不到“托管堆的内容”“C# 的堆栈帧”“异常对象的内容”的。填补这个缺口的正是 SOS(Son of Strike)扩展。堆的排查、堆损坏的检测、运行时内部数据类型的显示,一直到运行中托管代码状态的掌握,都是通过 SOS 命令完成的。3
3.1 因运行时而异
目标应用是 .NET Framework,还是 .NET (Core) / .NET 5+,会影响需要加载的运行时本体与 SOS 的来源。
| 目标 | 运行时本体 | 加载命令 |
|---|---|---|
| .NET Framework | clr.dll |
.loadby sos clr |
| .NET Core / .NET 5+ | coreclr.dll |
.loadby sos coreclr |
.loadby 是从指定模块(clr 或 coreclr)所在的目录,查找同一位置的扩展 DLL(sos.dll)并加载的命令。优点是不需要写完整路径,就能准确获取对应转储采集环境的 SOS 版本。6
10.0.18317.1001 及以后版本的 WinDbg、cdb,只要检测到目标进程加载了 coreclr.dll(或 Linux/macOS 上的 libcoreclr.so),就会自动从 Microsoft Extension Gallery 加载对应 .NET 的扩展。6 上面的 .loadby 手动命令,适用于自动加载不生效,或使用较旧版本调试器的情况。
3.2 找不到 SOS 时
在自动加载不生效的环境中,可以用 dotnet-sos 工具在本机安装。
dotnet tool install --global dotnet-sos
dotnet-sos install
安装完成后,也可以在 WinDbg 中如下手动加载(较旧的调试器可能需要这一步)。7
.load %USERPROFILE%\.dotnet\sos\sos.dll
3.3 确认是否加载成功
!sos.help
或者,如果目标是 Core 系列可以尝试 !Threads,Framework 系列可以尝试 !sosstatus,只要不报错并返回一些信息,就说明加载成功。如果命令在这里以类似 Unable to find module 的错误失败,几乎都是符号路径或运行时不一致所致(例如转储采集环境与本机运行时的位数、版本不同)。在进入下一章的命令之前,卡在这一步的情况在实务中并不少见。
4. 读取异常与堆栈 ── !clrstack 与 !pe
这是因未处理异常而崩溃的转储文件的第一步。
!threads
先用 !Threads(在 lldb 环境中别名为 clrthreads)确认托管线程列表,以及各线程的 Exception 字段。8 如果有线程持有异常,就切换到那个线程。
~5s
!clrstack
!CLRStack 只显示托管代码的堆栈跟踪。9 如果想连参数和变量都看到,可以加上 -a(相当于 -l 与 -p 的组合快捷方式)。
!clrstack -a
- 如果能看到自有代码的方法排列出来,就能直接读出“在哪里”“经过什么调用路径”崩溃的。能显示到源文件名、行号,是因为符号被正确加载了(第 2 章)。
CLRStack是直接从 CLR 的元数据枚举托管帧,因此符号有无并不影响帧是否显示。符号不足时丢失的只是源文件名、行号,帧本身不会因此被省略。9 - 如果一个自有代码的帧都看不到,先别怀疑符号不足,应该怀疑的是:选中的线程其实是没有异常的另一个线程(选错了线程)、只有原生侧崩溃而托管帧本来就不存在,或者转储文件的类型(如 Mini)没有包含足够的堆栈信息。
接下来看异常对象本身。
!pe
!PrintException(简称 !pe)在省略地址时,会显示当前线程最后一次抛出的异常。可以获取类型名、消息、内部异常(用 -nested 显示),一直到堆栈跟踪字符串。10 像 System.NullReferenceException 这种光看类型名看不出什么信息的异常,就需要与 !clrstack -a 看到的局部变量值互相对照。
5. 追踪堆与泄漏 ── !dumpheap -stat 与 !gcroot
在“内存缓慢增长,几小时到几天后才崩溃”这类排查中是核心命令。要先分辨是等待 GC 还是真正的泄漏,前置的判断方法已经在「用 .NET 区分 GC 等待与内存泄漏」中详细写过。本文接续其后,属于读一份转储文件并深入到“是什么握着”的部分。
!dumpheap -stat
-stat 选项只显示托管堆的统计摘要。会按类型的数量与总大小,大致从多到少排列,因此可以先锁定“数量压倒性偏多的类型”。11 实务中常见的有以下 2 种情况:
- 业务类本身在增加(例如
MyApp.Models.Customer有几十万个)── 说明某处一直存在强引用握着它 - 只有
System.String或数组异常多── 大多是排名靠前的业务类内部数据所致,先怀疑业务类,往往比逐个查看实例更快
锁定目标后,获取单个实例的地址。
!dumpheap -type MyApp.Models.Customer
然后排查该对象为什么没有被 GC 回收,一直残留着。
!gcroot 000001a2b3c4d5e0
!GCRoot 会搜索整个托管堆与句柄表,找出所有能到达指定对象的根(堆栈上的变量、静态字段、GC 句柄等)。12 如果输出中看到用于缓存的静态字段或事件处理程序的订阅,那里就是取消订阅遗漏的嫌疑对象。下面这种“放进缓存后就不释放”的代码是典型例子:
public static class CustomerCache
{
// 没有清理途径,只会不断增长的静态字典
private static readonly Dictionary<int, Customer> _cache = new();
public static void Add(Customer c) => _cache[c.Id] = c;
}
如果 !gcroot 的输出中出现像 CustomerCache 这样的静态容器,就是考虑加上有效期、上限数量,或改用 WeakReference 的依据。11
6. 原生崩溃的自动分析 ── !analyze -v
涉及 C++ DLL、COM、厂商 SDK 的原生崩溃(如访问违规),一律先从这个命令入手。
!analyze -v
!analyze 是进行崩溃、异常自动分析的扩展命令,加上 -v 会显示详细信息。13 输出中特别需要关注的有以下 3 项:
EXCEPTION_CODE/BUGCHECK_STR: 是哪种异常(访问违规、堆栈溢出等)FAULTING_IP/FOLLOWUP_IP: 实际崩溃的指令地址,以及对应的模块、函数名MODULE_NAME/IMAGE_NAME: 崩溃处是自有模块,还是第三方 DLL
如果崩溃发生在自有模块之外的厂商 DLL 中,要继续往下追就需要厂商的 PDB(通常拿不到)。实务中比较现实的做法,是回溯到“调用方(自有代码最后传入的参数)”,怀疑传入的值是否有问题。请用 !analyze -v 的 STACK_TEXT 字段确认自有代码调用了什么之后才崩溃。
!analyze 不仅能用于异常导致的转储文件。怀疑是挂起(hang)时,选定目标线程后执行以下命令,会分析线程之间的阻塞关系。
!analyze -hang
7. 不用 WinDbg 的选项 ── dotnet-dump analyze
如果只想排查 .NET Core / .NET 5+ 的托管代码(不涉及原生 DLL 或 COM),比 WinDbg 更轻量的 dotnet-dump 也是一个选项。
dotnet tool install --global dotnet-dump
dotnet-dump analyze C:\CrashDumps\MyApp\MyApp_20260702_101500.dmp
analyze 子命令会打开一个预装了 SOS 的交互式会话,clrstack、dumpheap、gcroot 等本文介绍过的大多数命令,都能直接使用而不需要 ! 前缀。4
区分使用的大致标准如下:
| 观点 | WinDbg + SOS | dotnet-dump analyze |
|---|---|---|
| 原生堆栈帧 | 可见 | 不可见(仅托管侧)4 |
!analyze -v 的原生自动分析 |
可用 | 不可用 |
| Linux 的转储文件 | 可在 Windows 上用 WinDbg 分析(x64 转储用 x64 版、Arm64 转储用 x64 版、x86 转储用 x86 版)14 | 支持(使用同一平台位数的工具)14 |
| macOS 的转储文件 | 不支持(WinDbg 的 Linux 转储支持不包含 macOS) | 支持(.NET 5 及以后)4 |
| 接入的轻量程度 | 安装程序或 winget | dotnet global tool 一条命令 |
| 纳入跨平台 CI | 较费工 | 较容易 |
“可能涉及 COM、P/Invoke、原生 DLL”就用 WinDbg,“纯托管代码的内存泄漏排查,且想在 CI 或多平台上运行”就用 dotnet-dump analyze,是实务中的分界线。两者共用 SOS 的命令体系,因此在一边学到的命令,在另一边几乎都能直接沿用。如果要处理在 macOS 上采集的转储文件,WinDbg 不在选项之内,这一点要注意,只能选 dotnet-dump(或 LLDB)。
8. 符号读不到就什么都做不了
到目前为止的部分步骤,即使符号(PDB)没有正确加载,也还算能正常工作。如第 4 章所写,!clrstack、!dumpheap -stat、!gcroot 是直接读取 CLR 的元数据与堆数据,因此即使没有 PDB,帧与类型信息本身依然会显示。PDB 缺失时丢失的是托管代码的源文件名、行号,以及原生帧、原生模块的符号名(只显示地址而不是函数名)。如果手边只有转储文件和可执行文件,在“先想弄清楚发生了什么”的场景下,不必卡在寻找 PDB 上,直接从 !threads → !clrstack 入手也没问题。不过,如果想追到源代码行以确定问题所在,那就是另一回事了。第 2 章在 .sympath+ 中加上了自有 PDB 的路径,但实务中光是“不知道对应已发布 EXE/DLL 的 PDB 在哪里”,就足以让排查卡在无法确定源代码行的阶段,这种情况比采集篇中写到的还要频繁。
PDB 本身包含什么、不包含什么、Portable PDB,以及 Source Link(把源代码管理的元数据嵌入程序集,让调试器能直接获取对应构建时间点提交的源代码的机制),都已在「PDB 是什么」这篇文章中整理过。15 如果要把转储分析纳入持续性的运维流程,按构建版本保存 PDB、并启用 Source Link,这件事的重要程度和采集配置本身不相上下。这一步偷懒的话,!clrstack 的输出就完全不会出现源代码行,只能靠地址和类型名摸索。
9. 实例 ── 句柄泄漏排查中的转储分析
之前写过的「工业相机长期运行崩溃排查 - 句柄泄漏篇」,是长时间运行后突然崩溃的工业相机控制应用的排查案例,元凶不是内存泄漏而是句柄泄漏。这类排查中转储文件能发挥作用,是在以下组合成立的时候:
- 先用
!dumpheap -stat确认托管堆一侧正常(各类型的数量、大小没有持续增长) - 如果进程的句柄数量仍在持续增长,就能区分出泄漏的不是托管对象,而是 操作系统句柄(文件、事件、相机 SDK 内部分配的句柄等)
- 如果还残留着持有
SafeHandle的托管包装对象,就用!gcroot追踪该包装对象的 GC 根,找出“本应释放却仍有引用残留”的位置
也就是说,!dumpheap -stat 是判断“是不是托管堆在增长”的分岔点,一旦确认不是,排查的重心就会转向像 Application Verifier 这类原生边界异常检测工具。这套异常路径测试基础设施的搭建方式,在「用 Application Verifier 搭建 Windows 异常路径测试基础设施」中有介绍。转储分析扮演的是“掌握当前发生的状态”,Application Verifier 扮演的是“提前重现异常”,两者并用是长时间运行系统故障排查的常规做法。
10. 总结
崩溃转储文件“采集”相对容易,“读懂”则需要更多时间才能熟练,但套路并不算多。
- 安装 WinDbg,并在符号路径中同时放入 Microsoft 的公共符号服务器与自有 PDB(第 2 章)
- .NET 应用要加载 SOS 扩展(
.loadby sos clr/.loadby sos coreclr,或自动加载。第 3 章) - 因异常而崩溃就走
!clrstack→!pe,内存增长就走!dumpheap -stat→!gcroot,原生崩溃就从!analyze -v入手(第 4~6 章) - 如果用途纯粹是托管侧的排查,也可以考虑轻量的
dotnet-dump analyze(第 7 章)
而支撑这一切的基础,就是 PDB 与符号的管理。在建立转储采集配置的同时,一并定好按构建版本保存 PDB、启用 Source Link,实际发生故障时的排查时间会有很大差异。如果自身难以完成分析,或抽不出时间,只要把转储文件和日志一起发过来,我们也可以协助分析。
相关文章
- Windows 崩溃转储采集入门 - WER/ProcDump/WinDbg
- Windows 应用崩溃时保留日志与转储文件的设计
- 用 .NET 区分 GC 等待与内存泄漏
- PDB(程序数据库)是什么
- 工业相机长期运行崩溃排查 - 句柄泄漏篇
- 用 Application Verifier 搭建 Windows 异常路径测试基础设施
相关咨询领域
合同会社小村软件提供结合崩溃转储文件与日志的故障原因排查、仅在长期运行后才出现的故障定位,以及转储文件、PDB 保存与分析体制本身的设计咨询。
参考链接
-
Microsoft Learn, Install the Windows debugger. 说明通过 winget / Microsoft Store 安装 WinDbg 的方式、支持的操作系统(Windows 10 1607 及以后、Windows 11)与架构(x64、ARM64),以及自动更新的行为。 ↩ ↩2 ↩3
-
Microsoft Learn, Symbol path for Windows debuggers. 说明通过
_NT_SYMBOL_PATH环境变量设置符号路径的方式,以及.symfix命令可以设置指向公共符号服务器的默认路径。 ↩ ↩2 -
Microsoft Learn, SOS debugging extension. 说明 SOS 扩展可用于托管堆信息的收集、堆损坏的检测、运行时内部数据类型的显示,以及在 WinDbg 上的语法为
![command]。 ↩ ↩2 -
Microsoft Learn, Dump collection and analysis utility (dotnet-dump). 说明
dotnet-dump analyze提供可直接使用 SOS 命令的交互式会话,但因不是原生调试器而无法显示原生堆栈帧,以及 macOS 支持从 .NET 5 开始。 ↩ ↩2 ↩3 ↩4 -
Microsoft Learn, Microsoft public symbol server. 说明
srv*DownstreamStore*https://msdl.microsoft.com/download/symbols格式的符号路径语法,以及.symfix可以附带本地缓存进行设置。 ↩ -
Microsoft Learn, Debugging Managed Code Using the Windows Debugger. 说明 .NET Framework 的运行时为
clr.dll、.NET Core/.NET 5+ 的运行时为coreclr.dll,.loadby可从模块附近加载扩展,以及 WinDbg 10.0.18317.1001 及以后版本的自动加载机制。 ↩ ↩2 -
Microsoft Learn, SOS installer (dotnet-sos). 说明通过
dotnet-sos install在本机安装 SOS 扩展,以及在较旧版本调试器中手动加载的命令。 ↩ -
Microsoft Learn, SOS debugging extension - Commands. 说明
Threads(在 lldb 环境中别名为clrthreads)命令会列出各线程的 ID、域、最后抛出的异常等信息。 ↩ -
Microsoft Learn, SOS debugging extension - Commands. 说明
CLRStack命令只显示托管代码的堆栈跟踪,-a选项可同时显示局部变量与参数,以及符号(SYMOPT_LOAD_LINES)只影响源文件名、行号能否显示,与帧本身是否显示无关。 ↩ ↩2 -
Microsoft Learn, SOS debugging extension - Commands. 说明
PrintException(pe)命令在省略地址时,会显示当前线程最后一次抛出的异常,并可用-nested显示嵌套异常。 ↩ -
Microsoft Learn, Debug a memory leak in .NET 以及 Dump collection and analysis utility (dotnet-dump) - Analyze memory leaks and allocations. 说明
dumpheap -stat按类型显示数量与总大小的统计,以及以此为起点推进排查的方法。 ↩ ↩2 -
Microsoft Learn, SOS debugging extension - Commands. 说明
GCRoot命令会搜索整个托管堆与句柄表,找出通往指定对象的引用(根)。 ↩ -
Microsoft Learn, Using the !analyze Extension 以及 !analyze (WinDbg). 说明
!analyze -v的崩溃、异常自动分析,输出中FAULTING_IP、MODULE_NAME等字段的含义,以及用于挂起排查的!analyze -hang。 ↩ -
Microsoft Learn, Debug Linux dumps. 说明可以在 Windows 上用 WinDbg 或 dotnet-dump 分析 Linux 的转储文件,并且需要按采集环境(x64/Arm64/x86)的位数使用对应版本的工具。 ↩ ↩2
-
Microsoft Learn, Source Link. 说明在创建 NuGet 包时,把源代码管理的元数据嵌入程序集,让调试器能直接访问构建时间点的源代码的机制。 ↩
相关文章
共享相同标签的最新文章。可以围绕相近的主题进一步加深理解。
用 PerfView 与 dotnet-trace 定位“变慢”的原因 ── .NET 性能排查实务入门
当业务应用出现“变慢”“CPU 占满”“偶尔卡死”时,该用哪个工具看什么?本文梳理 PerfView 与 dotnet-trace 的分工、CPU 采样的解读方法(inclusive/exclusive)、用 ThreadTime 排查阻塞时间,以及与 EventSourc...
PDB(程序数据库)是什么 ── 理解调试信息、符号与 Source Link
整理 PDB(Program Database / 程序数据库)到底是什么、里面有什么、没有什么,以及它与 Debug / Release、Portable PDB、Source Link、符号服务器、Dump 分析之间的关系,供实务参考。
Windows 事件日志・ETW 入门 ── 让业务应用程序的日志接入操作系统标准机制
Windows 业务应用程序的日志,是不是只靠文件日志来解决?事件日志与 ETW,是运维人员和操作系统标准工具所能看到的另一层记录。本文整理三种手段的分工方式、.NET 中的写入方法、通过 EventSource 进行的 ETW 埋点、收集与排查的实务做法,以及来源未注册、...
不只是 appsettings.json ── Windows 业务应用的配置管理实务(环境差异化设置・敏感信息・写入位置)
本文从实务角度整理 Windows 业务应用的配置管理,涵盖 appsettings.json 的分层、IConfiguration 与 IOptions/IOptionsSnapshot/IOptionsMonitor 的选用方式、环境差异化设置、可写入配置的存放位置、敏...
Windows 业务应用程序的打印与 PDF 输出 ── System.Drawing.Printing / WPF / 报表库的取舍选型
本文按需求整理成判断表,梳理 PrintDocument 的 WinForms 打印、WPF 的 FlowDocument/FixedDocument 打印,以及 PDF 输出的可选方案。并从实务角度讲解分页控制、DPI 偏差等实现陷阱,以及从 Windows 服务打印、依...
常见问题
汇总了咨询这一主题时常见的问题。
- .NET 应用的崩溃转储该从哪个命令开始读?
- 排查的思路大致分 3 种。如果是因未处理异常而崩溃,先用 !threads 找出持有异常的线程,再用 !clrstack 显示托管堆栈,并用 !pe 确认异常对象的类型、消息与内部异常。如果是内存持续增长的排查,先用 !dumpheap -stat 找出数量偏多的类型,再用 !gcroot 找出握住该对象的根(静态字段或事件处理程序的订阅等)。如果是原生崩溃,则从 !analyze -v 的自动分析入手。
- 在 WinDbg 中要如何加载 SOS 扩展?
- .NET Framework 用 .loadby sos clr,.NET Core/.NET 5+ 用 .loadby sos coreclr。10.0.18317.1001 及以后版本的 WinDbg,只要检测到目标进程加载了 coreclr.dll,就会自动加载 SOS。如果自动加载不生效,可以用 dotnet-sos 工具在本机安装后手动 .load。是否加载成功,可以用 !sos.help 或 !Threads 执行后不报错并返回信息来确认。
- 没有 PDB(符号)也能做转储分析吗?
- 在一定程度上可以。!clrstack、!dumpheap -stat、!gcroot 是直接读取 CLR 的元数据与堆数据,因此即使没有 PDB,堆栈帧与类型信息依然会显示。丢失的是托管代码的源文件名、行号,以及原生堆栈帧的符号名。如果想追到源代码行以确定问题所在,就需要在符号路径中同时放入 Microsoft 的公共符号服务器与自有 PDB 的位置。按构建版本保存 PDB,并启用 Source Link,在运维上非常重要。
- dotnet-dump analyze 与 WinDbg 该如何区分使用?
- 如果可能涉及 COM、P/Invoke 或原生 DLL,用 WinDbg;如果是纯托管代码的排查,dotnet-dump analyze 是基本方针。dotnet-dump 只需一条 dotnet global tool 命令即可安装,clrstack、dumpheap 等大多数 SOS 命令都能直接沿用,但无法处理原生堆栈帧,也无法使用 !analyze -v。在 macOS 上采集的转储无法用 WinDbg 分析,因此只能选 dotnet-dump 或 LLDB。两者共用 SOS 的命令体系,因此学会的命令几乎可以互通使用。
作者简介
本文作者的个人简介页面。
Go Komura
小村软件有限公司 代表
以 Windows 软件开发、技术咨询与故障排查为中心,擅长难以复现的故障调查,以及既有资产仍在运行的项目。