重点:Triggered by Thread这句话后边的线程号,快速定位问题出现在那个线程,是否是你的锅;Triggered by Thread所指的线程表示导致异常、崩溃的线程
下边内容转自简书
简介
当一个应用程序崩溃, 会产生一个崩溃报告(crash report) ,并存储到那个设备。崩溃报告描述了应用程序崩溃的条件,大多数情况会包含每个执行线程的一个完整的回溯,对我们调试应用程序的问题是非常有用的。你应该查看崩溃报告来了解你应用程序有什么崩溃,然后尝试修复它们。
崩溃报告必须被符号化(symbolicated),才能够被分析。符号化就是将内存地址替换成人能够阅读的函数名和代码所处的行数(即第几行)。如果你通过Xcode的Devices窗口,从一个设备中获取崩溃日志,几秒钟后会自动为你完成符号化。否则,你需要将.crash文件导入到Xcode的Devices窗口,来将它符号化。
低内存报告(Low Memory report)和崩溃报告不一样,这类型的报告没有回溯。当一个低内存报告发生时,你必须检查你的内存使用模式以及对低内存警告的应对方法。这篇文章将提供几种内存管理参考,你可能会有用。
获取崩溃和低内存报告
Debugging Deployed iOS Apps讨论怎样直接从设备获取崩溃和低内存报告。
App Distribution Guide中的Analyzing Crash Reports会讨论如何查看从TestFlight beta测试者以及从App Store下载你App的用户中收集的全部崩溃报告。
符号化崩溃报告
符号化是把回溯地址(即符号)还原成源码方法或者函数名的过程。不先把崩溃报告进行符号化,是很难判断崩溃发生在哪里。
Note:低内存报告不需要进行符号化。
Note:来至macOS的崩溃报告通常在它们产生的时候就已经符号化的,或者部分符号化的。这部分集中讨论来之iOS,watchOS和tvOS,但是总体过程和macOS相似。
Figure 1:崩溃的报告以及符号化过程的总览。
- 在编译器将你的源代码翻译成机器码的同时,它也会生成debug symbols (调试符号),它在编译后的二进制中,映射每个机器指令到原来的每一行源代码。这些调试符号是存储到二进制文件里还是其附属的调试符号文件,即Debug Symbol (dSYM) file,取决于build setting中调试信息格式(DEBUG_INFORMATION_FORMAT)的设定。默认情况是一个应用程序debug的build会存储到编译的二进制文件中,当Release的时候会存储调试符号到一个附属的dSYM文件来减轻二进制文件的大小。
Debug Symbol file和应用程序的二进制文件是通过预构建基础(per-build-basis)的构建UUID来绑定的。每次构建应用程序都会生成一个新的UUID,来唯一确定这次构建。甚至使用相同的编译器设定,对同样的源代码,来进行功能上一模一样的执行重新构建,也会有不同的构建UUID。来自本构建的Debug Symbol文件,尽管是相同的源文件,也不会和其他构建的二进制文件互通。
- 当你archive要发布应用程序时,Xcode会收集应用程序二进制文件以及.dSYM文件,然后把它们存储到你的home文件夹的一个地方。你可以在Xcode Organizer的"Archived" 部分中,找到所有你archived的应用程序。
Important:要符号化来之测试者,app审核以及用户的崩溃报告,你必须保存每次你发布应用程序的archive。
- 当你通过App Store发布你的App,或者通过TestFlight发起一次beta test,会有当上传你的Archive到iTunes Connect,包含dSYM文件的选项。在提交对话框中,勾选 “Include app symbols for your application…”。上传你的dSYM文件对于接收来自TestFlight用户和选择了分享诊断数据的顾客(即app store用户)的崩溃报告是必要的。
Important:来自App Review的崩溃报告会没法符号化,尽管当你上传到iTunes Connect的archive包含了dSYM文件。你需要通过Xcode来符号化来自App Review的崩溃报告。
-
当你的应用程序崩溃,一个未符号化的崩溃报告会产生并存储到设备上。
-
通过 Debugging Deployed iOS Apps
步骤,用户可以直接从他们的设备获取的崩溃报告。如果你是通过AdHoc发布你的应用程序,或者是企业发布(Enterprise distribution),这是唯一从你的用户获取崩溃报告的方法。 -
从一个设备获取的崩溃报告是没有被符号化的,需要使用Xcode来进行符号化。Xcode使用应用程序二进制文件关联的dSYM文件,把回溯中的每个地址替换为你源代码原来的位置。替换的结果就是符号化的崩溃报告。
-
如果用户选择分享诊断数据给Apple,或者如果用户通过TestFlight安装了你应用程序的一个beta版本,崩溃报告会被上传到App Store。
-
App store符号化那些崩溃报告,把相似的崩溃报告分组。这些全部相似崩溃报告,被称为崩溃点(Crash Point)。
-
已经符号化的崩溃报告可以在Xcode的Crashes organizer中找到和使用。
Bitcode
Bitcode 是代表一个已编译的程序的中间媒介。当Bitcode开启的时候,你archive一个应用程序,编译器产生包含bitcode二进制文件而不是机器码。一旦二进制已经上传到App Store,bitcode会被编译成机器码。App Store 可能在以后再次编译这个bitcode,用于未来编译器的提升,你这边不需要做任何事。
Figure 2:Bitcode编译过程。
因为你的二进制的最后编译是由App Store完成的,你的Mac不会包含dSYM文件,来符号化来自App Store崩溃报告或者用户从它们设备获取发送给你的崩溃报告。尽管当你archive你的App,会产生dSYM文件,但它是属于bitcode二进制文件的,不能用于符号化崩溃报告。App Store在进行bitcode编译会产程dSYM文件,你可以通过Xcode或者iTunes connect网页进行下载。你必须下载这些dSYM文件,才能符号化来自App Store崩溃报告或者用户从它们设备获取发送给你的崩溃报告。从崩溃报告服务获取的崩溃报告会被自动符号化。
Important: App Store编译的二进制文件的UUID会和你原来提交的二进制文件的UUID不同。
从Xcode下载dSYM文件
- 在 Archives organizer选项,选择你原来提交到App Store的archive。
- 点击dSYMs按钮来下载。
Xcode下载dSYM文件并把它们插入到被选择的archive。
从iTunes connect网页下载dSYM文件
- 打开App详情页。
- 点击活动。
- 从所有Builds列表中,选择一个版本。
- 点击Download dSYM链接。
把'hidden'符号名翻译它们原来的名字
当你上传你的bitcode App到App Store,你可以在提交对话框里,不勾选选择"Upload your app's symbols to receive symbolicated reports from Apple",从而不发送应用程序的symbols。如果你选择不发送的App的符号信息给Apple,在发送你的App到iTunes Connect之前,Xcode会用一个混淆的symbols,如 "__hidden#109_"来代替你App的symbols。Xcode会创建原始symbols和"hidden" symbols的映射关系并存储这个映射关系到一个. bcsymbolmap文件到这个应用程序的archive中,每一个.dSYM文件都有对应的一个.bcsymbolmap文件。
在符号化崩溃报告之前,你需要反向混淆(还原)这个从iTunes Connect下载的文件。如果你使用Xcode来下载dSYM文件,会为你自动进行反向混淆。然而,如果你使用iTunes Connect网址下载的.dSYM文件,打开终端并使用下面的命令行来反向混淆你的symbols(使用你自己的archive 和从iTunes connect下载的dSYMs文件夹来代替下面范例)。
xcrun dsymutil -symbol-map ~/Library/Developer/Xcode/Archives/2017-11-23/MyGreatApp\ 11-23-17\,\ 12.00\ PM.xcarchive/BCSymbolMaps ~/Downloads/dSYMs/3B15C133-88AA-35B0-B8BA-84AF76826CE0.dSYM
你下载的dSYMs文件夹中的每一个. dSYM文件需要运行这个命令。
确定一个崩溃报告是否被符号化了
一个崩溃报告可能未被符号化,完全符号化,或者部分符号化。未被符号化的崩溃报告在回溯中不会包含方法或者函数名。取而代之的是已加载二进制镜像的可执行代码的16进制地址。在一个完全符号化的崩溃报告,回溯的每一行16进制地址都会被对应的符号代替。在部分符号化的崩溃报告,只有部分地址被对应的符号代替。
显然,你应该试着完全符号化崩溃报告,以便更深入地分析崩溃。一个部分符号化的崩溃报告,也许能包含足够信息来明白崩溃,这取决崩溃的类型以及哪部分回溯被成功符号化。一个未被符号化的崩溃报告很少被使用。
Figure 3: 同样的回溯在不同程度的符号化。
使用Xcode符号化崩溃报告
Xcode 会自动尝试符号化它遇到的所有崩溃报告。你只需要将崩溃报告添加到Xcode Organizer。
Note: Xcode不会接收不是以.crash为扩展名的崩溃报告。如果你接收到一个崩溃报告没有扩展名或者扩展名是.txt的,在进行以下步骤之前请将它重命名.crash扩展名。
- 将你的Mac和一个iOS设备连接。
- 从"Window"菜单,选择"Device"。
- 在"DEVICES" 部分的左边栏,选择一个设备。
- 点击右手边板面"Device Information"部分的"View Device Logs"按钮。
- 将崩溃报告拖到左边栏当前的面板
- Xcode会自动符号化这个崩溃报告,并显示结果。
要符号化一个崩溃报告,Xcode必须能找到以下信息:
- 崩溃应用程序的二进制文件和dSYM文件
- 所有这个应用程序使用的自定义framework的二进制和dSYM文件。如果frameworks是编译来自应用程序的源代码,它们的dSYM文件会和应用程序的dSYM文件被一起复制进archive。如果frameworks是第三方编译的,你需要向其作者获取dSYM文件。
- 系统符号是应用程序运行崩溃的所在的系统。这些symbols包含frameworks的调试信息中,包括了一个指定的发布系统信息(如iOS9.3.3)。系统符号(OS symbols)是指定架构的-一个64位设备的iOS发布系统不会包含armv7的符号。Xcode会自动复制从连接你Mac的每个设备中自动复制系统符号。
如果任意这些信息丢失,Xcode可能无法符号化崩溃报告,或者只能部分符号化崩溃报告。
使用atos符号化崩溃报告
atos命令转换数字地址到它们等价的符号。如果调试符号信息能够使用,atos的输出包含文件名和源码的行数信息。atos命令能够符号化未符号化或部分符号化的崩溃报告回溯中的单个地址。使用atos符号化崩溃报告的一部分:
- 在回溯中找到你想符号化的一行。注意二进制镜像的名字在第二列,而地址在第三列。
- 找到名字在崩溃报告底部的二进制镜像列表中的二进制镜像。注意二进制的架构和加载地址。
Figure 4:使用atos所需要的崩溃报告信息。
- 找到二进制文件对应的dSYM文件。你可以使用Spotlight找到匹配dSYM文件UUID的二进制镜像。(可以参考