iOS 上的崩溃报告工具如何对发布版本的崩溃报告进行去符号化处理?

How does crash reporting tools on iOS desymbolicate the crash reports on a release build?

在 iOS,出于安全原因,调试符号从发布二进制文件中删除。那么像 Fabric、Hockey 等这样的崩溃报告工具如何 "desymbolicate" 并显示来自发布版本的崩溃点的良好堆栈跟踪???

他们 capture/trace 是自己崩溃,而不是依赖 OS 生成的痕迹吗?

以下内容适用于 OS X、iOS、tvOS 以及 watchOS:

  1. 如果二进制文件本身包含符号,它们只能提供class 名称和方法名称。但绝不是文件名或行号。所以他们的好处是有限的,但二进制文件大小的增加很大,大约增加了 30-50%(估计,根据应用程序可以更大或更小)
  2. 如果您的构建设置设置正确(默认设置 = DEBUG_INFORMATION_FORMAT 设置为 DWARF with dSYM File),那么您每次构建时都会得到一个 dSYM 包,其中包含一个 dwarf 文件包含符号化以及获取文件名和行号所需的一切。

那么 iTunes Connect、Xcode、Fabric、HockeyApp 等实际上是如何进行符号化的呢?

他们都在使用 dSYM 包中的 dwarf 文件。他们从堆栈帧中获取内存地址,通过匹配地址范围在崩溃报告的二进制图像部分找到相应的二进制图像,获取二进制图像的 UUID,找到包含匹配 UUID 的 dSYM 包以进行匹配CPU 体系结构,然后 运行 像 atos 这样的工具反对它以获得(demangled)符号。

他们如何获得堆栈跟踪?

  1. OS 在 iTunes Connect 和 Xcode 使用的进程外生成崩溃报告。
  2. 所有第 3 方系统都需要将代码添加到应用程序中,为基于信号的崩溃和未处理的异常设置崩溃处理程序,并在崩溃时尝试安全地获取崩溃报告中所需的所有信息。此代码 运行s 在应用程序进程中因此可能不会做很多事情(例如它可能不会在崩溃时分配内存)来安全地收集该数据并且不会破坏任何用户数据或导致设备死锁。第三方系统无法获取系统生成的崩溃报告,因为它们位于应用程序沙箱之外。