#符号 #minidump #breakpad #回溯 #调试 #可读性 #JSON

app minidump-stackwalk

分析minidump并生成报告(可读性或JSON格式)

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 解析实现

Download history 856/week @ 2024-05-03 930/week @ 2024-05-10 1006/week @ 2024-05-17 798/week @ 2024-05-24 1285/week @ 2024-05-31 1306/week @ 2024-06-07 1513/week @ 2024-06-14 1466/week @ 2024-06-21 1492/week @ 2024-06-28 1287/week @ 2024-07-05 1043/week @ 2024-07-12 1790/week @ 2024-07-19 1192/week @ 2024-07-26 1222/week @ 2024-08-02 1100/week @ 2024-08-09 1229/week @ 2024-08-16

5,005 每月下载量

MIT 许可证

1.5MB
24K SLoC

minidump-stackwalk

crates.io docs.rs

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值

--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