理解崩溃报告

此页面是从 MDN 导入的,内容可能已过时

如果用户遇到崩溃,系统会提示他们提交原始崩溃报告,该报告由 Breakpad 生成。原始崩溃报告由 Socorro 接收,创建 处理后的崩溃报告。处理后的崩溃报告基于原始崩溃报告,但也包含签名、分类和许多改进的字段(例如操作系统、产品、版本)。原始崩溃报告和处理后的崩溃报告中的许多字段都可以在 crash-stats 上查看和搜索。尽管存在两种不同的崩溃报告(原始和处理后的),但人们通常会谈论单个“崩溃报告”,因为 crash-stats 主要以组合方式呈现它们。

每个崩溃报告都包含大量有关崩溃情况的数据。尽管如此,许多崩溃报告缺乏足够的数据供开发人员了解崩溃发生的原因。除了提供一般概述外,此页面还旨在突出显示崩溃报告中可能提供非明显见解的部分。

请注意,大多数崩溃报告字段都是可见的,但其中一些隐私敏感部分仅对已登录且具有“小型转储访问权限”的用户可用。只有相对较少数量的用户拥有小型转储访问权限,并且他们必须遵守某些规则。有关访问权限,请参阅 Crash Stats 上的受保护数据访问文档

每个崩溃报告都包含以下选项卡:详细信息、元数据、模块、原始转储、扩展和(可选)关联。

详细信息选项卡

详细信息选项卡是首先查看的地方,因为它包含最重要的信息。

主要字段

详细信息选项卡的第一部分显示一个表格,其中包含最重要的崩溃报告字段。其中包括崩溃发生时间、在哪个产品和版本中发生、崩溃类型以及有关崩溃发生机器的操作系统和配置的各种详细信息。以下屏幕截图显示了其中一些字段。
Example fields in the "Details" tab of a crash report

所有字段都有工具提示。对于许多字段,工具提示描述了其含义。对于所有字段,工具提示都指示了当您想要执行涉及此字段的搜索时要使用的键。(字段名称通常与搜索键相似,但并非总是如此。例如,字段“适配器设备 ID”的搜索键为“adapter_device_id”。)这些描述显示在 SuperSearchFields API 中,并且可以通过 修改 super_search_fields.py 或编写 Socorro 中的错误 来修改。

此选项卡中显示的字段根据崩溃类型而有所不同。并非所有字段都始终存在。

“签名”字段是崩溃报告的主要标识符或标签。我们希望将崩溃报告分成集群,以便我们可以一次处理一组崩溃报告,而不是孤立地考虑每个崩溃报告。理想的聚类算法会将具有相同根本原因的所有崩溃报告放入一个集群中,并将具有不同根本原因的所有崩溃报告放入不同的集群中。崩溃签名是我们对这种算法的不完美但仍然有用的尝试。大多数崩溃签名都基于崩溃堆栈跟踪,但某些专用注释用于指示特定类型的崩溃。

  • Abort:受控中止,例如通过 NS_RUNTIMEABORT。(通过 MOZ_CRASHMOZ_RELEASE_ASSERT 发生的受控中止目前不会获得 Abort 注释,但它们确实会获得“MOZ_CRASH 原因”字段。)

  • OOM | <size>,其中 <size>largesmallunknown 之一:内存不足 (OOM) 中止。<size> 注释由“OOM 分配大小”字段确定;如果该字段丢失,则 <size> 将为 unknown

  • hang:关闭之前的挂起。

  • shutdownhang:关闭期间的挂起。

  • IPCError-browser:涉及 IPC 的问题。如果父 Firefox 进程检测到子进程发送了损坏或无法处理的 IPDL 数据,或者没有及时关闭,它会终止子进程并生成崩溃报告。这些崩溃现在将具有一个签名,指示进程被终止的原因,而不是子进程当时的堆栈。

当不存在专用注释并且签名以堆栈帧开头时,它通常是普通的不受控制的崩溃。可以从“崩溃原因”字段确定崩溃原因。最常见的是内存访问错误。在这种情况下,在 Windows 上,您可以从原因字段中判断崩溃是在读取、写入还是执行内存时发生的(例如,EXCEPTION_VIOLATION_ACCESS_READ 表示内存读取错误)。在 Mac 和 Linux 上,原因将是 SIGSEGV 或 SIGBUS,您无法从该字段中判断出是什么类型的内存访问。

请参阅 此文件,了解有关崩溃报告签名生成过程的详细说明,以及有关如何修改此过程的信息。

没有字段可以唯一标识崩溃报告来自的用户,但如果您想知道多个崩溃是否来自单个用户,“安装时间”字段是一个不错的选择。将其与其他不会更改的字段(例如描述操作系统或显卡的字段)结合使用,以获得更高的置信度。

对于内存访问错误,“崩溃地址”字段可以提供有关问题所在的其他指示。

  • 0x0 可能为空指针取消引用[*。]

  • 像 0x8 这样的小地址可能表示通过空 this 指针进行的对象访问(例如,this->mFoo)。

  • 像 0xfffffffffd8 这样的地址可能是堆栈访问,具体取决于平台[*。]

  • 像 0x80cdefd3 这样的地址可能是堆访问,具体取决于平台。

  • 地址可能已被污染:0xe4 表示地址来自由 jemalloc 分配但尚未初始化的内存;0xe5 表示地址来自由 jemalloc 释放的内存。JS 引擎还在 js/src/jsutil.h 中定义了多个污染值。

[*] 请注意,由于 x86-64 上的寻址方式,如果 Linux/macOS 崩溃报告的崩溃地址为 0x0,或者 Windows 崩溃报告的崩溃地址为 0xffffffffffffffff,则该值极有可能不正确。(此问题已有一个 错误报告。)您可以通过查看“原始转储”选项卡中的原始转储或小型转储来检查这些崩溃(请参见下文)。

请注意,对于非发布版本,“版本”字段表示多个不同的版本,因为 nightly 和 beta 版本号会在连续几天创建的版本中重复使用,直到版本号增加。(“构建 ID”字段可以消除歧义。)目前无法 将搜索限制到特定版本或更高版本(使用构建 ID 和给定发布渠道的 >= 可能会解决此问题)。

某些字段(例如“URL”和“电子邮件地址”)属于隐私敏感信息,仅对具有小型转储访问权限的用户可见。

仅 Windows 的“总虚拟内存”字段指示 Firefox 构建和操作系统是 32 位还是 64 位。

  • 值为 2 GiB 表示 32 位 Windows 上的 32 位 Firefox。

  • 值为 3 或 4 GiB 表示 64 位 Windows 上的 32 位 Firefox(又名“WoW64”)。此类用户可以切换到 64 位 Firefox。

  • 值远大于 4 GiB(例如 128 TiB)表示 64 位 Firefox。(在这种情况下,“构建架构”字段应为“amd64”。)

某些崩溃报告可能包含内存报告。此内存报告是在崩溃之前一段时间内生成的,当时可用内存较低。在这种情况下,详细信息选项卡中将显示内存报告的一些关键测量值,每个测量值都有一个以“MR:”开头的字段名称,缩写为“内存报告”。可以在“原始转储”选项卡中获取完整的内存报告(请参见下文)。

堆栈跟踪

“详细信息”选项卡的第三部分显示崩溃线程的堆栈跟踪和线程号,如下面的屏幕截图所示。

Information relating to threads in the "Details" tab of a crash report

每个堆栈帧都可能包含指向源代码的链接。如果崩溃是新的,则可以通过查看一个或多个顶部堆栈帧的归责注释中的最新更改来识别导致回归的更改集。归责注释也有助于识别可能了解相关代码的人员。

有时,突出显示的源代码令人费解,例如,即使崩溃与内存相关,标识的行也可能不会触及内存。这可能是由编译器优化引起的。通常最好查看反汇编(例如,在小型转储中)以准确了解正在执行的代码。

堆栈帧条目采用各种形式。

  • 最简单的形式是函数名称,例如 NS_InitXPCOM2

  • 名称/地址对,例如 nss3.dll@0x1eb720,位于系统库中。

  • 诸如 F1398665248_____________________________(“F”后跟许多数字,然后是许多下划线)之类的名称位于 Flash 中。

  • 诸如 @0xe1a850ac 之类的地址可能表示不属于任何合法代码的地址。如果此类地址出现在第一个堆栈帧中,则崩溃可能是可利用的

可以通过点击小的“显示其他线程”链接来查看其他线程的堆栈跟踪。

如果崩溃报告是针对挂起的,则崩溃线程将是“看门狗”线程,该线程纯粹是为了检测挂起而存在的;其顶部堆栈帧将类似于 mozilla::`anonymous namespace'::RunWatchdog。在这种情况下,您应该查看其他线程的堆栈跟踪以确定问题;其中许多线程将等待某种响应,如包含诸如 NtWaitForSingleObjectZwWaitForMultipleObjects 之类的函数的顶部堆栈帧所示。

元数据选项卡

“元数据”选项卡类似于“详细信息”选项卡的第一部分,包含一个包含各种字段的表格。这些是来自原始崩溃报告的字段,按字段名称按字母顺序排序,但隐私敏感字段仅显示给具有小型转储访问权限的用户。它与“详细信息”选项卡中显示的字段有一些重叠。

模块选项卡

“模块”选项卡显示崩溃时加载的所有系统库,如下面的屏幕截图所示。

Table of modules in the "Modules" tab of a crash report

在 Windows 上,这些主要是 DLL,在 Mac 上,这些主要是 .dylib 文件,在 Linux 上,这些主要是 .so 文件。

此信息对 Windows 崩溃最有用,因为防病毒软件或恶意软件加载的 DLL 经常导致 Firefox 崩溃。“关联”选项卡(见下文)中可以查看加载的模块与崩溃签名之间的关联。

此页面 指出缺少版本/调试标识符/调试文件名的文件可能是恶意软件。

原始转储选项卡

“原始转储”选项卡的第一部分显示原始崩溃报告,格式为 JSON。同样,隐私敏感字段仅显示给具有小型转储访问权限的用户。

JSON data in the "Raw Dump" tab of a crash report

对于具有小型转储访问权限的用户,“原始转储”选项卡的第二部分有一些链接,如下面的屏幕截图所示。

Links to downloadable files in the "Raw Dump" tab of a crash report

这些链接指向以下项目。

  1. 小型转储。小型转储在理解崩溃报告方面非常有用;请参阅此页面,了解如何使用它们。

  2. 上述 JSON 格式的原始崩溃报告。

  3. 崩溃报告中包含的内存报告。

  4. 未编辑的崩溃报告,其中包含其他信息。

扩展选项卡

“扩展”选项卡显示已安装和启用的扩展。

Table of extensions in the "Extensions" tab of a crash report

通常它只显示 ID 而不是正确的扩展名称。

请注意,Firefox 默认情况下附带了几个扩展,因此几乎所有崩溃报告中都会出现这些扩展。(默认扩展的确切集合取决于发布渠道。)其中最不明显的是 ID 为 {972ce4c6-7e08-4474-a285-3208198ce6fd},这是默认的 Firefox 主题。默认情况下附带的其他一些(但不是全部)扩展具有以下 ID:[email protected][email protected][email protected][email protected][email protected]

如果扩展程序只有十六进制标识符,则通常可以通过对该标识符进行 Google 搜索来识别扩展程序的名称。

此信息很有用,因为某些崩溃是由扩展程序引起的。“关联”选项卡(见下文)中可以查看扩展程序与崩溃签名之间的关联。

关联选项卡

仅当 crash-stats 识别出崩溃与存在的模块或扩展之间存在关联时才会显示此选项卡,这种情况偶尔会出现。

另请参阅