30个版本 (14个破坏性更新)
0.22.0 | 2024年7月3日 |
---|---|
0.21.1 | 2024年3月1日 |
0.19.1 | 2023年11月2日 |
0.17.0 | 2023年5月17日 |
0.3.0 | 2021年5月21日 |
#249 in 解析实现
5,005 每月下载量
1.5MB
24K SLoC
minidump-stackwalk
是minidump-processor的命令行界面前端,提供minidump的机器可读和人类可读摘要,包括回溯和符号化。
(如果您需要图形用户界面,请参阅minidump-debugger。 这是一个实验性的外部项目。)
该软件专门设计为提供与mozilla的minidump-stackwalk兼容的接口,后者本身与google-breakpad的minidump-stackwalk类似。
(如果您需要区分它们,请将此称为“rust-minidump-stackwalk”)
使用此软件的最简单方法是使用cargo install
安装它
> cargo install minidump-stackwalk
> minidump-stackwalk path/to/minidump.dmp
CLI的完整文档可以在下面的“minidump-stackwalk CLI手册”部分找到(使用--help
将产生相同的输出)。
启用额外分析
可以使用--features标志盲目选择“更多分析”。请参阅CLI文档中的该条目,了解更多关于选择适当值的信息,但简而言之,您可以使用--features=unstable-all
打开所有功能并查看“新功能”。
输出格式
快速参考
--human
(默认)- 人类友好输出,由--brief
修改--json
- 机器友好输出,由--pretty
修改--cyborg=some/file/for/machine/output.json
- 人类和机器均可使用!--dump
- minidump内容的“原始”输出(用于调试)
minidump-stackwalk 默认以人类可读的格式输出报告,因为这对于日常使用来说更方便,但机器可读的输出被认为是“主要”输出格式。
如果您传递了 –json 标志,您将获得机器可读的(JSON)输出。从版本 0.9.6 开始,此格式 应该 是稳定的,并且具有完整的文档规范!(–pretty 将使此输出更容易人类阅读。)
如果您传递了 –human 标志,minidump-stackwalk 将以更符合人类习惯的格式输出报告,没有特定的结构。(–brief 将使此输出更简洁。)
默认情况下,输出写入标准输出,但 --output-file=some/file/name.txt
允许您指定一个文件来写入输出。我们将创建并完全覆盖指定的文件。如果发生致命错误,我们将尽量不写入任何内容,这可能导致 --output-file
完全没有被创建或清除。
同样,错误和警告默认情况下写入标准错误,可以使用 --log-file=...
进行配置。--verbose=...
可用于设置日志级别(默认为“错误”)。
如果您传递 –cyborg 标志,您将在一个执行中同时获得 –human 和 –json 输出(节省大量重复工作),具体来说,您必须传递 --cyborg=some/file/for/machine/output.json
。当启用机器人模式时,人类输出仍然是“主要”输出,会发送到标准输出,并且可以使用 --output-file
进行配置。
最后,–dump 标志 将提供 minidump 的“原始”输出,用于调试其内容。其确切含义是有意模糊的;输出将包含我们在调试过程中认为有用的任何内容。在此模式下,大多数其他标志都将相当不相关,因为 minidump_processor
不会被调用(我们只使用 minidump
crate 对每个流进行基本的解析)。这相当于旧的 minidump_dump 工具。
获取符号
minidump-stackwalk 可以在没有符号的情况下运行,但如果您提供它们,您将以两种方式获得更丰富的输出
- 更精确的回溯(使用类似 Dwarf CFI 或 PE32 Unwinding Tables 的机制)
- 符号化的堆栈帧(回溯将具有正确的函数名称和行号)
minidump-stackwalk 从 google-breakpad 符号文件 中获取符号。符号文件是一种纯文本格式,旨在统一各种平台特定的调试信息/回溯格式的内容,如 PE32 Unwinding Tables、Dwarf CFI、Macho Compact Unwinding Info 等。
要从您的构建工件生成这些文件,请使用 Mozilla 的 dump_syms(推荐)或 google-breakpad 的 dump_syms。
然后,您可以直接将符号文件作为 symbols-path
值提供(按位置传递,请参阅下面的 CLI 手册),或者间接设置一个符合 mozilla 的 Tecken 协议 的符号服务器,并通过 --symbols-url
标志传递该服务器的 URL。(该协议基本上是一个具有特定路径格式的静态文件服务器。)
分析 Firefox Minidumps
如果您正在尝试分析 Firefox Minidumps,请将 minidump-stackwalk 指向 Mozilla 的 Tecken 服务器。
minidump-stackwalk --symbols-url=https://symbols.mozilla.org/ /path/to/minidump.dmp
或者,如果您想在 https://crash-stats.mozilla.org(socorro)上重新处理崩溃报告,您可能想使用 socc-pair,它自动执行此过程(并将本地结果与服务器上的结果进行对比)。
调试 Stackwalking
rust-minidump 包含其栈遍历器的详细跟踪日志,您可以通过 --verbose=trace
启用它(我们不建议在生产环境中运行此模式,它非常详细,并且退化输入可能会产生巨大的日志)。
阅读这些日志的一些建议
- 所有栈遍历行将以
[TRACE] unwind
开始(其他日志可能会穿插其中)。 - 每个线程的展开将
- 以 "开始栈展开" 开始
- 以 "完成栈展开" 结束
- 每个帧的展开将
- 以 "正在展开 <名称>" 开始
- 以 "<展开方法> 看起来有效" 结束
- 包括最后的指令指针和栈指针值
- 尝试展开的方法按顺序尝试(质量逐渐降低)
- cfi
- 帧指针
- 扫描
如果您看到 "尝试扫描" 或 "尝试帧指针",这意味着之前的展开方法失败。有时失败的原因会记录下来,但有时失败发生在我们没有任何日志的地方。如果发生这种情况,您仍然可以根据该步骤之后通常发生的事情推断可能出错的原因。
例如,一个 cfi 跟踪通常看起来像
[TRACE] unwind: unwinding NtGetContextThread
[TRACE] unwind: trying cfi
[TRACE] unwind: found symbols for address, searching for cfi entries
如果您看到
[TRACE] unwind: unwinding NtGetContextThread
[TRACE] unwind: trying cfi
[TRACE] unwind: trying frame pointer
这表明 cfi 分析甚至无法到达 "找到地址的符号"。因此,假设它甚至无法找到当前指令指针的符号。这可能是因为它映射到一个已知的模块,或者因为该模块没有符号。
这是一个栈遍历跟踪的示例
[TRACE] unwind: starting stack unwind
[TRACE] unwind: unwinding NtGetContextThread
[TRACE] unwind: trying cfi
[TRACE] unwind: found symbols for address, searching for cfi entries
[TRACE] unwind: trying STACK CFI exprs
[TRACE] unwind: .cfa: $rsp 8 + .ra: .cfa 8 - ^
[TRACE] unwind: .cfa: $rsp 8 +
[TRACE] unwind: STACK CFI parse successful
[TRACE] unwind: STACK CFI seems reasonable, evaluating
[TRACE] unwind: successfully evaluated .cfa (frame address)
[TRACE] unwind: successfully evaluated .ra (return address)
[TRACE] unwind: cfi evaluation was successful -- caller_ip: 0x000000ec00000000, caller_sp: 0x000000ec7fbfd790
[TRACE] unwind: cfi result seems valid
[TRACE] unwind: unwinding 1013612281855
[TRACE] unwind: trying cfi
[TRACE] unwind: trying frame pointer
[TRACE] unwind: trying scan
[TRACE] unwind: scan seems valid -- caller_ip: 0x7ffd172c2a24, caller_sp: 0xec7fbfd7f8
[TRACE] unwind: unwinding <unknown in ntdll.dll>
[TRACE] unwind: trying cfi
[TRACE] unwind: found symbols for address, searching for cfi entries
[TRACE] unwind: trying frame pointer
[TRACE] unwind: trying scan
[TRACE] unwind: scan seems valid -- caller_ip: 0x7ffd162b7034, caller_sp: 0xec7fbfd828
[TRACE] unwind: unwinding BaseThreadInitThunk
[TRACE] unwind: trying cfi
[TRACE] unwind: found symbols for address, searching for cfi entries
[TRACE] unwind: trying STACK CFI exprs
[TRACE] unwind: .cfa: $rsp 8 + .ra: .cfa 8 - ^
[TRACE] unwind: .cfa: $rsp 48 +
[TRACE] unwind: STACK CFI parse successful
[TRACE] unwind: STACK CFI seems reasonable, evaluating
[TRACE] unwind: successfully evaluated .cfa (frame address)
[TRACE] unwind: successfully evaluated .ra (return address)
[TRACE] unwind: cfi evaluation was successful -- caller_ip: 0x0000000000000000, caller_sp: 0x000000ec7fbfd858
[TRACE] unwind: cfi result seems valid
[TRACE] unwind: instruction pointer was nullish, assuming unwind complete
[TRACE] unwind: finished stack unwind
(这是一个特别讨厌/无用的栈,但它展示了在已知函数中 CFИ 展开和在完全未知函数中扫描展开的两个极端情况。)
minidump-stackwalk CLI 手册
此手册可以通过
minidump-stackwalk --help-markdown
重新生成
版本: minidump-stackwalk 0.14.0
分析minidump并生成报告(可读性或JSON格式)
用法
minidump-stackwalk [FLAGS] [OPTIONS] <minidump> [--] [symbols-path]...
参数
<MINIDUMP>
要分析的最小转储文件的路径
<SYMBOLS_PATH_LEGACY>...
符号文件的路径。(按位置传递)
如果提供了多个 symbols-path-legacy 值,所有符号文件将合并到 minidump-stackwalk 的符号数据库中。
选项
--human
输出可读报告(默认)
可读报告没有指定格式,可能不如 JSON 格式详细。它旨在快速检查崩溃或调试 rust-minidump 本身。
可以通过 --brief 简化
--json
输出可读的 JSON 报告
此输出的模式在以下位置有官方文档
<https://github.com/rust-minidump/rust-minidump/blob/master/minidump-processor/json-schema.md>
可以通过 --pretty 格式化
--cyborg<CYBORG>
组合 --human 和 --json
因为这将创建两个输出流,您必须指定一个写入 --json 输出的路径。--human 输出将是“主要”输出,默认为 stdout,可以通过 --output-file 正常配置。
--dump
转储最小转储的“原始”内容
这是旧 minidump_dump 工具功能的一个实现。它最小程度地解析和解释最小转储,试图生成最小转储内容的相当“原始”转储。这对于调试 minidump-stackwalk 本身或行为不端的 minidump 生成器最有用。
可以通过 --brief 简化
--features<FEATURES>
指定要执行的分析程度
此标志提供了一种更盲目地选择额外分析的方法,而无需了解 minidump-stackwalk 的具体功能。这相当于 minidump-processor 中的 ProcessorOptions。当前支持的值有
- stable-basic(默认):提供大多数人想要的稳健详细分析
- stable-all:开启额外详细分析。
- unstable-all: 打开奇怪和实验性的功能。
stable-all启用:无(当前与stable-basic相同)
unstable-all启用:--recover-function-args
minidump-stackwalk希望成为一个可靠和稳定的工具,但我们也希望能够引入可能具有实验性或成本高昂的新功能。为了平衡这两方面的考虑,新功能通常默认禁用,并赋予一个特定的标志,但仍更容易被使用该标志的任何人“发现”。
任何担心输出稳定性的minidump-stackwalk用户可能不应该在生产环境中使用此标志,但建议在休闲使用或检查“新功能”时使用。
unstable-all下的功能可能会被弃用并变为空操作。需要额外输入(如--evil-json
)的功能不受此影响,必须手动“发现”。
[默认:stable-basic]
[可能的值:stable-basic, stable-all, unstable-all]
--verbose<VERBOSE>
如何详细记录日志(日志级别)
解包器已被大量使用trace
记录,因此如果您想调试解包器为何以这种方式发生,--verbose=trace非常有用(所有解包器日志都将以unwind:
开头)。
[默认:error]
[可能的值:off, error, warn, info, debug, trace]
--output-file<OUTPUT_FILE>
输出写入的位置(如果未指定,则使用stdout)
--log-file<LOG_FILE>
日志写入的位置(如果未指定,则使用stderr)
--no-color
防止输出/日志使用ANSI颜色
通过--log-file、--output-file或--cyborg写入文件的所有输出始终
--no-color,所以这只会强制stdout/stderr打印。
--pretty
美化打印--json输出
--brief
提供更简短的--human或--dump报告
对于人类用户:仅提供顶级摘要和崩溃线程的堆栈跟踪。
对于转储:省略所有内存十六进制转储。
--no-interactive
禁用所有交互式进度反馈
我们通常会尝试自动检测何时需要禁用此功能,但这里提供了它以防我们出错并且您需要将其移除。
--evil-json<EVIL_JSON>
UNSTABLE 包含额外信息的输入JSON文件。
这是对mozilla使用的某些旧版旁路信息的粗暴处理。希望它将被逐步淘汰并弃用,转而仅使用minidump本身的自定义流。
--recover-function-args
UNSTABLE 启发式恢复函数参数
这是一个实验性功能,目前仅在--human输出中显示。
--use-local-debuginfo
如果存在,使用minidump中引用的本地文件中的调试信息。
--symbols-url<SYMBOLS_URL>
构建符号文件URL的基数URL
如果提供了多个symbols-url值,则将按顺序尝试每个值,直到解析一个为止。
基数URL指向的服务器应遵循Tecken符号服务器协议。有关更多详细信息,请参阅Tecken文档
<https://tecken.readthedocs.io/en/latest/>
示例symbols-url值
- microsoft的符号服务器:https://msdl.microsoft.com/download/symbols/
- mozilla的符号服务器:https://symbols.mozilla.org/
--symbols-cache<SYMBOLS_CACHE>
一个目录,其中可以存储下载的符号
符号文件可能非常大,因此我们建议将缓存文件放置在系统临时目录中,以便它可以自动回收未使用的文件。为此,此标志的默认值是 rust-minidump-cache
子目录,位于 std::env::temp_dir()
下(通常在 Linux 系统上是 /tmp/rust-minidump-cache)。
符号缓存必须与 symbols-tmp 位于同一文件系统中(如果您不理解这代表什么,不必担心,您可能不会遇到相关问题)。
--symbols-tmp<SYMBOLS_TMP>
用于下载符号的临时空间目录。
需要临时目录以允许多个 rust-minidump 实例共享缓存而不发生竞态条件。在原子移动到缓存之前,要添加到缓存中的文件将在此位置构建。
如果未指定路径,则将使用 std::env::temp_dir()
来提高可移植性。如果您希望使用除系统默认临时目录之外的路径,请参阅 rust 文档了解如何设置该值。
symbols-tmp 必须与 symbols-cache 位于同一文件系统中(如果您不理解这代表什么,不必担心,您可能不会遇到相关问题)。
--symbols-download-timeout-secs<SYMBOLS_DOWNLOAD_TIMEOUT_SECS>
符号文件下载允许的最大时间(以秒为单位)
这是强制执行不正常行为的 http 响应的前进进度所必需的。
[默认值:1000]
--symbols-path <SYMBOLS_PATH>
符号文件的路径。
如果提供了多个 symbols-path 值,所有符号文件都将合并到 minidump-stackwalk 的符号数据库中。
-h, --help
打印帮助信息
-V, --version
打印版本信息
依赖项
~17–31MB
~563K SLoC