Crash日志解析

当应用程序崩溃时,会建立一个崩溃报告,这对于了解致使崩溃的缘由很是有用。本文档包含有关如何表示,理解和解释崩溃报告的基本信息。html

  • 一、介绍
  • 二、获取崩溃和低内存报告
  • 三、象征性的奔溃报告
    • 一、位码(bitCode)
    • 二、肯定奔溃报告是否符号化
    • 三、用Xcode标记iOS奔溃报告
    • 四、用atos表示崩溃报告
    • 五、符号故障排除
  • 四、崩溃报告分析
    • 一、头
    • 二、例外信息
    • 三、其余诊断信息
    • 四、回溯
    • 五、线程状态
    • 六、二进制图像
  • 五、了解低内存报告

介绍

当应用程序崩溃时,会建立崩溃报告并将其存储在设备上。崩溃报告描述了应用程序终止的条件,在大多数状况下包括每一个执行线程的完整回溯,而且一般对于调试应用程序中的问题很是有用。您应该查看这些崩溃报告,以了解您的应用程序崩溃了什么,而后尝试修复它们。node

带有回溯的崩溃报告须要在进行分析以前进行符号化。符号化用人类可读的函数名称和行号替换内存地址。若是您经过Xcode的设备窗口从设备上获取崩溃日志,那么几秒钟后它们将自动被符号化。不然,您须要经过将.crash文件导入Xcode Devices窗口来自行符号化。有关详细信息,请参阅符号崩溃报告。ios

一个低内存报告不一样之处在于有这类型的报告没有回溯其余的崩溃报告。当发生低内存崩溃时,您必须调查内存使用模式以及对低内存警告的响应。git

获取崩溃和低内存报告

调试已部署的iOS应用程序讨论了如何直接从iOS设备检索崩溃和低内存报告。github

分析“ 应用程序分发指南”中的崩溃报告讨论了如何查看从TestFlight beta测试人员和从App Store下载应用程序的用户收集的聚合崩溃报告。sql

象征性的崩溃报告

符号化是将回溯地址解析为源代码方法或函数名称(称为符号)的过程。若是没有首先表示崩溃报告,则很难肯定崩溃发生的位置。数据库

注意:  低内存报告不须要进行符号化。
注意:  macOS的崩溃报告一般在生成时被符号化或部分符号化。本节重点介绍iOS,watchOS和tvOS的崩溃报告,但整个过程与macOS相似。
复制代码

Crash日志.png

一、当编译器将源代码转换为机器代码时,它还会生成调试符号,这些符号将编译后的二进制文件中的每一个机器指令映射回源自它的源代码行。根据Debug Information Format(DEBUG_INFORMATION_FORMAT)构建设置,这些调试符号存储在二进制文件或伴随的Debug Symbol(dSYM)文件中。默认状况下,应用程序的调试版本将调试符号存储在已编译的二进制文件中,而应用程序的发布版本将调试符号存储在配套dSYM文件中以减少二进制文件大小。 调试符号文件和应用程序二进制文件经过构建UUID在每一个构建的基础上绑定在一块儿。为应用程序的每一个构建生成一个新的UUID,并惟一标识该构建。即便从相同的源代码重建功能相同的可执行文件,使用相同的编译器设置,它也将具备不一样的构建UUID。调试来自后续版本的符号文件,即便是来自相同的源文件,也不会与来自其余版本的二进制文件互操做。xcode

  • 二、归档应用程序以进行分发时,Xcode将收集应用程序二进制文件以及。dSYM将文件存储并保存在主文件夹内的某个位置安全

  • 三、若是您经过App Store分发应用程序,或使用Test Flight进行beta测试,您能够选择dSYM在将存档上传到iTunes Connect时包含该文件。在提交对话框中,选中“为您的应用程序包含应用程序符号...”。上传dSYM文件对于接收从TestFlight用户和选择共享诊断数据的客户收集的崩溃报告是必要的bash

  • 四、当您的应用程序崩溃时,会建立一个非符号化的崩溃报告并将其存储在设备上。

  • 五、用户能够按照调试已部署的iOS应用程序中的步骤直接从其设备检索崩溃报告。若是您经过AdHoc或Enterprise分发分发了应用程序,则这是从用户获取崩溃报告的惟一方法。

  • 六、从设备检索到的崩溃报告是非符号化的,须要使用Xcode进行符号化。Xcode使用dSYM与应用程序二进制文件关联的文件将回溯中的每一个地址替换为源代码中的原始位置。结果是一个符号化的崩溃报告。

  • 七、若是用户选择与Apple共享诊断数据,或者用户已经过TestFlight安装了应用程序的测试版,则崩溃报告将上载到App Store

  • 八、App Store表示崩溃报告,并将其与相似的崩溃报告分组。这种相似崩溃报告的汇总称为崩溃点。

  • 九、Xcode的Crashes组织者可使用符号化的崩溃报告。

位码

Bitcode是编译程序的中间表示。当您使用bitcode存档应用程序时,编译器会生成包含bitcode而不是机器代码的二进制文件。将二进制文件上传到App Store后,bitcode将编译为机器代码。App Store可能会在未来再次编译bitcode,以利用将来的编译器改进,而无需您采起任何操做

Crash日志1.png

因为二进制文件的最终编译发生在App Store上,所以Mac不会包含用于表示dSYM从App Review收到的崩溃报告或从其设备向您发送崩溃报告的用户所需的调试符号()文件。虽然dSYM归档应用程序时会生成一个文件,但它是用于bitcode二进制文件,不能用于表示崩溃报告。App Store使dSYM您能够从Xcode或iTunes Connect网站下载bitcode编译期间生成的文件。您必须下载这些dSYM文件,以便表示从App Review或从其设备向您发送崩溃报告的用户收到的崩溃报告。经过崩溃报告服务收到的崩溃报告将自动进行符号化。

App Store编译的二进制文件将具备与最初提交的二进制文件不一样的UUID。

复制代码

从Xcode下载dSYM文件

  • 一、在Archives管理器中,选择最初提交到App Store的存档
  • 二、单击“下载dSYMs”按钮。 Xcode下载dSYM文件并将其插入选定的存档。

从iTunes Connect网站下载dSYM文件

  • 一、打开“应用详情”页面。
  • 二、单击活动。
  • 三、从“全部构建”列表中,选择一个版本。
  • 四、单击“ 下载dSYM”连接

将“隐藏”符号名称翻译回原始名称

当您将带有bitcode的应用程序上传到App Store时,您能够选择不经过取消选中“上传您的应用程序的符号以从Apple接收符号化报告”框来发送应用程序的符号。若是您选择不将应用程序的符号信息发送给Apple,Xcode将替换您应用程序中的符号。dSYM在将应用程序发送到iTunes Connect以前,带有模糊符号的文件,例如“_hidden#109”。Xcode在原始符号和“隐藏”符号之间建立映射,并将此映射存储.bcsymbolmap在应用程序归档内的文件中。每一个。dSYM文件将有一个相应的.bcsymbolmap文件。

在对崩溃报告进行符号化以前,您须要对符号中的符号进行去混淆。dSYM从iTunes Connect下载的文件。若是您使用Xcode中的下载dSYMs按钮,将自动执行此去混淆。可是,若是您使用iTunes Connect网站下载。dSYM文件,打开终端并使用如下命令对符号进行反模糊处理(用您本身的存档替换示例路径和从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

复制代码

为每一个运行此命令。dSYM您下载的dSYMs文件夹中的文件。

肯定崩溃报告是否符号化

崩溃报告能够是非符号化的,彻底符号化的或部分符号化的。非符号化的崩溃报告将不包含回溯中的方法或函数名称。相反,您在加载的二进制图像中具备可执行代码的十六进制地址。在彻底符号化的崩溃报告中,回溯的每一行中的十六进制地址将替换为相应的符号。在部分符号化的崩溃报告中,只有回溯中的某些地址已替换为其相应的符号。

显然,您应该尝试彻底符合您收到的任何崩溃报告,由于它将提供有关崩溃的最深刻看法。部分符号化的崩溃报告可能包含足够的信息来了解崩溃,具体取决于崩溃的类型以及成功符号化的回溯的哪些部分。非符号化的崩溃报告不多有用

Crash日志2.png

用Xcode标记iOS崩溃报告

Xcode将自动尝试表示它遇到的全部崩溃报告。您须要为符号化作的只是将崩溃报告添加到Xcode Organizer。

Xcode不接受没有.crash扩展名的崩溃报告。若是您收到没有扩展程序或扩展程序的崩溃报告,请在执行下面列出的步骤以前.txt将其重命名为.crash扩展程序。
复制代码
  • 一、将iOS设备链接到Mac
  • 二、从“窗口”菜单中选择“设备”
  • 三、 在左列的“设备”部分下,选择一个设备
  • 四、单击右侧面板“设备信息”部分下的“查看设备日志”按钮
  • 五、将崩溃报告拖到所显示面板的左列
  • 六、Xcode将自动表示崩溃报告并显示结果

为了表示崩溃报告,Xcode须要可以找到如下内容

  • 一、崩溃的应用程序的二进制dSYM文件和文件。
  • 二、dSYM应用程序连接的全部自定义框架的二进制文件和文件。对于使用应用程序从源构建的框架,它们的dSYM文件将与应用程序的dSYM文件一块儿复制到存档中。对于由第三方构建的框架,您须要向做者询问该dSYM文件。
  • 三、崩溃时该应用程序运行的操做系统的符号。这些符号包含特定操做系统版本(例如iOS 9.3.3)中包含的框架的调试信息。OS符号是特定于体系结构的 - 用于64位设备的iOS版本不包含armv7符号。Xcode将自动从链接到Mac的每一个设备复制OS符号。

若是缺乏任何这些,Xcode可能没法表示崩溃报告,或者可能只是部分地表示崩溃报告。

用atos表示崩溃报告

该 ATOS命令将数字地址转换为其符号等效项。若是有完整的调试符号信息,则输出atos将包括文件名和源行号信息。该atos命令可用于在非符号化或部分符号化的崩溃报告的回溯中表示各个地址。使用atos如下命令表示崩溃报告的一部分:

  • 一、在回溯中找到要符号化的行。请注意第二列中二进制图像的名称,以及第三列中的地址。
  • 二、在崩溃报告底部的二进制图像列表中查找具备该名称的二进制图像。请注意二进制映像的体系结构和加载地址。

Crash日志3.png

符号故障排除

若是Xcode未能彻底符合崩溃报告,多是由于您的Mac缺乏dSYM应用程序二进制dSYM文件的文件,应用程序连接的一个或多个框架的文件,或者应用程序运行的OS的设备符号它坠毁了。如下步骤显示如何使用Spotlight肯定dSYM在Mac上是否存在表示二进制图像中的回溯地址所需的文件。

Crash日志4.png

  • 一、在回溯中找到Xcode没法符号化的行。请注意第二列中二进制图像的名称
  • 二、在崩溃报告底部的二进制图像列表中查找具备该名称的二进制图像。此列表包含崩溃时加载到进程中的每一个二进制映像的UUID。
您可使用grep命令行工具快速查找二进制映像列表中的条目。
$ grep --after-context = 1000“二进制图像:”<崩溃报告的路径> | grep <二进制名称>
复制代码
  • 三、将二进制映像的UUID转换为以8-4-4-4-12(XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX)为一组分隔的32个字符串。请注意,全部字母必须是大写的。
  • 四、使用mdfind命令行工具使用查询搜索UUID "com_apple_xcode_dsym_uuids == "(包括引号)。
使用mdfind命令行工具搜索dSYM具备给定UUID的文件。
$ mdfind“com_apple_xcode_dsym_uuids == <UUID>”

复制代码
  • 五、若是Spotlight找到dSYMUUID 的文件,mdfind将打印该dSYM文件的路径,并可能打印其包含的存档。若是dSYM找不到UUID 的文件, mdfind将退出而不打印任何内容。

分析崩溃报告

每一个崩溃报告都以标题开头。

Incident Identifier(事件标识符): B6FD1E8E-B39F-430B-ADDE-FC3A45ED368C
CrashReporter Key(密钥): f04e68ec62d3c66057628c9ba9839e30d55937dc
Hardware Model(硬件型号): iPad6,8
Process(进程): TheElements [303]
Path(路径): /private/var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
Identifier(标识符): com.example.apple-samplecode.TheElements
Version(版本): 1.12
Code Type(代码类型): ARM-64 (Native)
Role: Foreground
Parent Process: launchd [1]
Coalition: com.example.apple-samplecode.TheElements [402]

Date/Time: 2016-08-22 10:43:07.5806 -0700
Launch Time: 2016-08-22 10:43:01.0293 -0700
OS Version: iPhone OS 10.0 (14A5345a)
Report Version: 104
复制代码
  • 一、Incident Identifier事件标识符:报告的惟一标识符。两个报告永远不会共享相同的事件标识符。
  • 二、CrashReporter KeyCrashReporter密钥:匿名的每设备标识符。来自同一设备的两个报告将包含相同的值。
  • 三、Beta IdentifierBeta标识符:崩溃应用程序的设备和供应商组合的惟一标识符。来自同一供应商和同一设备的两个应用程序报告将包含相同的值。此字段仅存在于为经过TestFlight分发的应用程序生成的崩溃报告中,并替换CrashReporter Key字段。
  • 四、Process进程:崩溃进程的可执行文件名称。这与CFBundleExecutable应用程序的信息属性列表中的键值匹配。
  • 五、Version版本:崩溃的进程版本。该字段的值是崩溃的应用程序CFBundleVersion和的串联CFBundleVersionString。
  • 六、Code Type代码类型:崩溃的进程的目标体系结构。这将是一ARM-64,ARM,x86-64,或x86。
  • 七、Role角色:终止时分配给进程的task_role。
  • 八、OS Version操做系统版本:发生崩溃的操做系统版本,包括内部版本号。

因为未捕获的Objective-C异常致使进程终止时生成的崩溃报告中的Exception Codes部分的摘录。

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Exception Note: EXC_CORPSE_NOTIFY
Triggered by Thread: 0

复制代码

当进程由于取消引用NULL指针而终止时生成的崩溃报告中的Exception Codes部分的摘录。

Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000000
Termination Signal: Segmentation fault: 11
Termination Reason: Namespace SIGNAL, Code 0xb
Terminating Process: exc handler [0]
Triggered by Thread: 0
复制代码
  • 一、Exception Codes异常代码:有关异常的处理器特定信息,编码为一个或多个64位十六进制数。一般,此字段将不存在,由于Crash Reporter会解析异常代码以将其做为人类可读的描述呈如今其余字段中。
  • 二、Exception Subtype异常子类型:异常代码的人类可读名称。
  • 三、Exception Message异常消息:从异常代码中提取的其余人类可读信息。
  • 四、Exception Note异常注意:非特定于一种异常类型的附加信息。若是该字段包含,SIMULATED (this is NOT a crash)那么进程没有崩溃,可是在系统请求时被杀死,一般是看门狗
  • 五、Termination Reason终止缘由:终止进程时指定的退出缘由信息。进程内部和外部的关键系统组件将在遇到致命错误时终止进程(例如,错误的代码签名,缺乏的依赖库,或在没有适当权利的状况下访问隐私敏感信息)。macOS Sierra,iOS 10,watchOS 3和tvOS 10采用了新的基础设施来记录这些错误,这些操做系统生成的崩溃报告列出了终止缘由字段中的错误消息
  • 六、Triggered by Thread由线程触发:发生异常的线程。

内存访问不良[EXC_BAD_ACCESS // SIGSEGV // SIGBUS]

该进程尝试访问无效内存,或者尝试之内存保护级别不容许的方式访问内存(例如,写入只读内存)。该例外子类型字段包含一个kern_return_t描述错误,而且被错误地访问的存储器的地址。

如下是调试错误内存访问崩溃的一些提示:

  • 一、若是崩溃线程的Backtraces顶部objc_msgSend或objc_release附近,则该进程可能已尝试向已释放的对象发送消息。您应该使用Zombies工具对应用程序进行概要分析,以便更好地了解此崩溃的状况。
  • 二、若是在崩溃线程gpus_ReturnNotPermittedKillClient的Backtraces顶部附近,则该进程被终止,由于它在后台尝试使用OpenGL ES或Metal进行渲染。请参阅QA1766:如何在移动到后台时修复OpenGL ES应用程序崩溃。
  • 三、启用Address Sanitizer运行您的应用程序。地址清理程序在已编译的代码中添加了有关内存访问的附加检测。当您的应用程序运行时,若是以可能致使崩溃的方式访问内存,Xcode将提醒您。

异常退出[EXC_CRASH // SIGABRT]

该过程异常退出。使用此异常类型致使崩溃的最多见缘由是未被​​捕获的Objective-C / C ++ 异常和调用abort()。

若是App Extensions花费太多时间进行初始化(看门狗终止),它将以此异常类型终止。若是因为启动时挂起而致使扩展名被终止,则生成的崩溃报告的异常子类型将是LAUNCH_HANG。因为扩展没有main函数,所以初始化所花费的时间都发生在+load扩展和依赖库中的静态构造函数和方法中。你应该尽量多地推迟这项工做。

跟踪陷阱[EXC_BREAKPOINT // SIGTRAP]

与异常退出相似,此异常旨在为附加的调试器提供在其执行的特定点中断进程的机会。您可使用该__builtin_trap()函数从您本身的代码中触发此异常。若是未附加调试器,则终止该过程并生成崩溃报告。

较低级别的库(例如libdispatch)会在遇到致命错误时捕获进程。有关错误的其余信息能够在崩溃报告的“ 其余诊断信息”部分或设备的控制台中找到。

若是在运行时遇到意外状况,则Swift代码将以此异常类型终止,例如:

  • 一、具备nil值的非可选类型
  • 二、强制类型转换失败

非法指令[EXC_BAD_INSTRUCTION // SIGILL] 该进程试图执行非法或未定义的指令。该进程可能试图经过配置错误的函数指针跳转到无效地址。

在Intel处理器上,ud2操做码会致使EXC_BAD_INSTRUCTION异常,但一般用于捕获进程以进行调试。若是在运行时遇到意外状况,则Intel处理器上的Swift代码将以此异常类型终止。有关详细信息,请参阅跟踪陷阱

退出[SIGQUIT]

该进程在另外一个进程的请求下终止,并具备管理其生命周期的权限。SIGQUIT并不意味着该过程崩溃,但它确实可能以可检测的方式行为不端。

在iOS上,若是加载时间过长,主机应用将退出键盘扩展。崩溃报告中显示的Backtraces不太可能指向负责的代码。最有可能的是,扩展的启动路径上的一些其余代码须要很长时间才能完成,但在时间限制以前完成,而且当扩展退出时执行移动到Backtraces中显示的代码。您应该对扩展进行概要分析,以便更好地了解启动期间大多数工做的位置,并将该工做移至后台线程或将其推迟到之后(扩展加载后)。

被杀[SIGKILL]

该过程在系统请求时终止。查看“ 终止缘由”字段以更好地了解终止缘由。

该终止缘由字段将包含一个名称空间,而后一个代码。如下代码特定于watchOS:

  • 一、终止代码0xc51bad01表示监视应用程序已终止,由于它在执行后台任务时使用了太多CPU时间。要解决此问题,请优化执行后台任务的代码以提升CPU效率,或减小应用程序在后台运行时执行的工做量。
  • 二、终止代码0xc51bad02表示监视应用程序因未能在分配的时间内完成后台任务而终止。要解决此问题,请减小应用在后台运行时执行的工做量。
  • 三、终止代码0xc51bad03表示监视应用程序未能在分配的时间内完成后台任务,而且系统总体上很是繁忙,以致于应用程序可能没有多少CPU时间来执行后台任务。虽然应用程序能够经过减小它在后台任务中执行的工做量来避免此问题,0xc51bad03但并不表示该应用程序执行了任何错误操做。更有可能的是,因为总体系统负载,应用程序没法完成其工做

保护资源违规[EXC_GUARD]

该过程违反了受保护的资源保护。系统库可能会将某些文件描述符标记为保护,以后对这些描述符的正常操做将触发EXC_GUARD异常(当它想要对这些文件描述符进行操做时,系统使用特殊的“保护”私有API)。这有助于您快速跟踪问题,例如关闭系统库打开的文件描述符。例如,若是某个应用程序关闭了用于访问支持Core Data存储的SQLite文件的文件描述符,那么Core Data将在之后神秘地崩溃。保护异常会更快地发现这些问题,从而使它们更容易调试。

来自较新版本的iOS的崩溃报告包括有关EXC_GUARD在异常子类型和异常消息字段中致使异常的操做的人类可读详细信息。在来自macOS或旧版iOS的崩溃报告中,此信息被编码为第一个异常代码,做为位域,按以下方式分解:

资源限制[EXC_RESOURCE]

该过程超出了资源消耗限制。这是来自操做系统的通知,该进程使用了​​太多资源。确切的资源列在Exception Subtype字段中。若是包含“ 异常备注”字段NON-FATAL CONDITION,则即便生成了崩溃报告,也不会终止该进程。

  • 一、异常子类型MEMORY表示进程已超过系统强加的内存限制。这多是终止超额内存使用的先兆。
  • 二、异常子类型WAKEUPS表示进程中的线程每秒被唤醒太屡次,这迫使CPU常常唤醒并消耗电池寿命。

一般,这是由线程到线程的通讯(一般使用peformSelector:onThread:或者dispatch_async)引发的,这种通讯在不知不觉中发生的频率远远超过它应该发生的频率。由于触发此异常的通讯类型常常发生,因此一般会有多个具备很是类似的Backtraces的后台线程- 指示通讯的来源。

其余异常类型 某些崩溃报告可能包含未命名的异常类型,它将打印为十六进制值(例如00000020)。若是您收到其中一个崩溃报告,请直接查看“ 例外代码”字段以获取更多信息。

  • 一、异常代码0xbaaaaaad表示日志是整个系统的堆栈,而不是崩溃报告。要拍摄叠印,请同时按侧面按钮和两个音量按钮。这些日志一般是由用户意外建立的,并不表示错误。
  • 二、异常代码0xbad22222表示iOS已终止VoIP应用程序,由于它过于频繁地恢复。
  • 三、异常代码0x8badf00d表示iOS已终止应用程序,由于发生了监视程序超时。应用程序启动,终止或响应系统事件花费的时间太长。其中一个常见缘由是在主线程上进行同步网络链接。不管什么操做都Thread 0须要移动到后台线程,或者以不一样的方式处理,以便它不会阻塞主线程。
  • 四、异常代码0xc00010ff表示应用程序被操做系统杀死以响应热事件。这多是因为发生此崩溃的特定设备或其运行环境的问题。有关使您的应用程序更高效运行的提示,请参阅iOS性能和使用Instruments WWDC会话进行功耗优化。
  • 五、异常代码0xdead10cc表示应用程序已被操做系统终止,由于它在挂起期间保留了文件锁或sqlite数据库锁。若是您的应用程序在挂起时对锁定文件或sqlite数据库执行操做,则它必须请求额外的后台执行时间来完成这些操做并在挂起以前放弃锁定。
  • 六、异常代码0x2bad45ec表示因为安全违规而致使应用程序被iOS终止。终止描述“在安全模式下检测到进行不安全绘制的过程”表示应用程序试图在不容许的状况下绘制到屏幕,例如屏幕被锁定时。用户可能不会注意到此终止,由于屏幕关闭或发生此终止时会显示锁定屏幕。
使用应用切换器终止暂停的应用不会生成崩溃报告。应用程序暂停后,它有资格随时被iOS终止,所以不会生成崩溃报告。


复制代码

其余诊断信息 本节包括特定于终止类型的其余诊断信息,其中可能包括:

  • 一、特定于应用程序的信息:在进程终止以前捕获的框架错误消息
  • 二、内核消息:有关代码签名问题的详细信息
  • 三、Dyld错误消息:动态连接器发出的错误消息

流程终止时生成的崩溃报告中的“应用程序特定信息”部分的摘录,由于找不到连接的框架

Dyld Error Message:
Dyld Message: Library not loaded: @rpath/MyCustomFramework.framework/MyCustomFramework
Referenced from: /private/var/containers/Bundle/Application/CD9DB546-A449-41A4-A08B-87E57EE11354/TheElements.app/TheElements
Reason: no suitable image found.

复制代码

流程终止时生成的崩溃报告中的“特定于应用程序的信息”部分的摘录,由于它没法快速加载其初始视图控制器

Application Specific Information:
com.example.apple-samplecode.TheElements failed to scene-create after 19.81s (launch took 0.19s of total time limit 20.00s)

Elapsed total CPU time (seconds): 7.690 (user 7.690, system 0.000), 19% CPU
Elapsed application CPU time (seconds): 0.697, 2% CPU

复制代码

回溯

崩溃报告中最有趣的部分是它终止时每一个进程线程的回溯。这些跟踪中的每一条都与将进程与调试器暂停时看到的相似

Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   TheElements                       0x000000010006bc20 -[AtomicElementViewController myTransitionDidStop:finished:context:] (AtomicElementViewController.m:203)
1   UIKit                             0x0000000194cef0f0 -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] + 312
2   UIKit                             0x0000000194ceef30 -[UIViewAnimationState animationDidStop:finished:] + 160
3   QuartzCore                        0x0000000192178404 CA::Layer::run_animation_callbacks(void*) + 260
4   libdispatch.dylib                 0x000000018dd6d1c0 _dispatch_client_callout + 16
5   libdispatch.dylib                 0x000000018dd71d6c _dispatch_main_queue_callback_4CF + 1000
6   CoreFoundation                    0x000000018ee91f2c __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
7   CoreFoundation                    0x000000018ee8fb18 __CFRunLoopRun + 1660
8   CoreFoundation                    0x000000018edbe048 CFRunLoopRunSpecific + 444
9   GraphicsServices                  0x000000019083f198 GSEventRunModal + 180
10  UIKit                             0x0000000194d21bd0 -[UIApplication _run] + 684
11  UIKit                             0x0000000194d1c908 UIApplicationMain + 208
12  TheElements                       0x00000001000653c0 main (main.m:55)
13  libdyld.dylib                     0x000000018dda05b8 start + 4

Thread 1:
0   libsystem_kernel.dylib            0x000000018deb2a88 __workq_kernreturn + 8
1   libsystem_pthread.dylib           0x000000018df75188 _pthread_wqthread + 968
2   libsystem_pthread.dylib           0x000000018df74db4 start_wqthread + 4
复制代码

第一行列出了线程号和当前正在执行的调度队列的标识符。其他行列出了有关回溯中各个堆栈帧的详细信息。从左到右:

  • 一、堆栈帧号。堆栈帧以调用顺序呈现,其中第0帧是在执行暂停时执行的函数。第一帧是在第0帧调用函数的函数,依此类推。
  • 二、堆栈帧的执行函数所在的二进制文件的名称。
  • 三、对于第0帧,执行中止时执行的机器指令的地址。对于剩余的堆栈帧,当控制返回到堆栈帧时将下一次执行的机器指令的地址。
  • 四、在符号化崩溃报告中,堆栈框架中函数的方法名称。

来自非符号化崩溃报告的Last Exception Backtrace部分的摘录。

Last Exception Backtrace:
(0x18eee41c0 0x18d91c55c 0x18eee3e88 0x18f8ea1a0 0x195013fe4 0x1951acf20 0x18ee03dc4 0x1951ab8f4 0x195458128 0x19545fa20 0x19545fc7c 0x19545ff70 0x194de4594 0x194e94e8c 0x194f47d8c 0x194f39b40 0x194ca92ac 0x18ee917dc 0x18ee8f40c 0x18ee8f89c 0x18edbe048 0x19083f198 0x194d21bd0 0x194d1c908 0x1000ad45c 0x18dda05b8)
复制代码

必须对包含仅包含十六进制地址的Last Exception Backtrace的崩溃日志进行符号化,以生成可用的回溯

号化崩溃报告中的Last Exception Backtrace部分的摘录。在应用程序的故事板中加载场景时引起了此异常。缺乏用于链接到场景中元素的相应IBOutlet

Last Exception Backtrace:
0   CoreFoundation                    0x18eee41c0 __exceptionPreprocess + 124
1   libobjc.A.dylib                   0x18d91c55c objc_exception_throw + 56
2   CoreFoundation                    0x18eee3e88 -[NSException raise] + 12
3   Foundation                        0x18f8ea1a0 -[NSObject(NSKeyValueCoding) setValue:forKey:] + 272
4   UIKit                             0x195013fe4 -[UIViewController setValue:forKey:] + 104
5   UIKit                             0x1951acf20 -[UIRuntimeOutletConnection connect] + 124
6   CoreFoundation                    0x18ee03dc4 -[NSArray makeObjectsPerformSelector:] + 232
7   UIKit                             0x1951ab8f4 -[UINib instantiateWithOwner:options:] + 1756
8   UIKit                             0x195458128 -[UIStoryboard instantiateViewControllerWithIdentifier:] + 196
9   UIKit                             0x19545fa20 -[UIStoryboardSegueTemplate instantiateOrFindDestinationViewControllerWithSender:] + 92
10  UIKit                             0x19545fc7c -[UIStoryboardSegueTemplate _perform:] + 56
11  UIKit                             0x19545ff70 -[UIStoryboardSegueTemplate perform:] + 160
12  UIKit                             0x194de4594 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1352
13  UIKit                             0x194e94e8c -[UITableView _userSelectRowAtPendingSelectionIndexPath:] + 268
14  UIKit                             0x194f47d8c _runAfterCACommitDeferredBlocks + 292
15  UIKit                             0x194f39b40 _cleanUpAfterCAFlushAndRunDeferredBlocks + 560
16  UIKit                             0x194ca92ac _afterCACommitHandler + 168
17  CoreFoundation                    0x18ee917dc __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 32
18  CoreFoundation                    0x18ee8f40c __CFRunLoopDoObservers + 372
19  CoreFoundation                    0x18ee8f89c __CFRunLoopRun + 1024
20  CoreFoundation                    0x18edbe048 CFRunLoopRunSpecific + 444
21  GraphicsServices                  0x19083f198 GSEventRunModal + 180
22  UIKit                             0x194d21bd0 -[UIApplication _run] + 684
23  UIKit                             0x194d1c908 UIApplicationMain + 208
24  TheElements                       0x1000ad45c main (main.m:55)
25  libdyld.dylib                     0x18dda05b8 start + 4

复制代码

64位iOS使用“零成本”异常实现。在“零成本”系统中,每一个函数都有附加数据,这些数据描述了若是在函数中抛出异常,如何展开堆栈。若是在没有展开数据的堆栈帧中抛出异常,则异常处理没法继续,进程将中止。堆栈上可能有一个异常处理程序,但若是没有一个框架的展开数据,那么就没法从抛出异常的堆栈框架到达那里。指定该-no_compact_unwind标志意味着您没有得到该代码的展开表,所以您不能在这些函数之间抛出异常。

此外,若是要在应用程序或库中包含纯C代码,则可能须要指定该-funwind-tables标志以包含该代码中全部函数的展开表。

线程状态

本节列出了崩溃线程的线程状态。这是一个寄存器列表及其执行中止时的值。在阅读崩溃报告时,无需了解线程状态,但您可使用此信息更好地了解崩溃的状况

来自ARM64设备的崩溃报告的“线程状态”部分的摘录。

Thread 0 crashed with ARM Thread State (64-bit):
x0: 0x0000000000000000   x1: 0x000000019ff776c8   x2: 0x0000000000000000   x3: 0x000000019ff776c8
x4: 0x0000000000000000   x5: 0x0000000000000001   x6: 0x0000000000000000   x7: 0x00000000000000d0
x8: 0x0000000100023920   x9: 0x0000000000000000  x10: 0x000000019ff7dff0  x11: 0x0000000c0000000f
x12: 0x000000013e63b4d0  x13: 0x000001a19ff75009  x14: 0x0000000000000000  x15: 0x0000000000000000
x16: 0x0000000187b3f1b9  x17: 0x0000000181ed488c  x18: 0x0000000000000000  x19: 0x000000013e544780
x20: 0x000000013fa49560  x21: 0x0000000000000001  x22: 0x000000013fc05f90  x23: 0x000000010001e069
x24: 0x0000000000000000  x25: 0x000000019ff776c8  x26: 0xee009ec07c8c24c7  x27: 0x0000000000000020
x28: 0x0000000000000000  fp: 0x000000016fdf29e0   lr: 0x0000000100017cf8
sp: 0x000000016fdf2980   pc: 0x0000000100017d14 cpsr: 0x60000000

复制代码

崩溃报告的二进制映像部分中应用程序条目的摘录

Binary Images:
0x100060000 - 0x100073fff TheElements arm64 <2defdbea0c873a52afa458cf14cd169e> /var/containers/Bundle/Application/888C1FA2-3666-4AE2-9E8E-62E2F787DEC1/TheElements.app/TheElements
...
复制代码

每行包括单个二进制图像的如下详细信息:

  • 进程中的二进制映像的地址空间。
  • 二进制文件的二进制名称或包标识符(仅限macOS)。在来自macOS的崩溃报告中,若是二进制文件是操做系统的一部分,则前缀为(+)。
  • (仅限macOS)二进制文件的短版本字符串和包版本,用短划线分隔。
  • (仅限iOS)二进制图像的体系结构。二进制文件可能包含多个“切片”,每一个“切片”支持一个体系结构。这些切片中只有一个加载到过程当中。
  • 惟一标识二进制映像的UUID。此值随二进制的每一个构建而变化,用于在表示崩溃报告时定位相应的dSYM文件。
  • 磁盘上二进制文件的路径

了解低内存报告

当检测到低内存条件时,iOS中的虚拟内存系统依赖于应用程序的协做来释放内存。低内存通知做为释放内存的请求发送到全部正在运行的应用程序和进程,但愿减小使用的内存量。若是内存压力仍然存在,系统能够终止后台进程以减轻内存压力。若是能够释放足够的内存,您的应用程序将继续运行。若是没有,您的应用程序将被iOS终止,由于没有足够的内存来知足应用程序的需求,而且将生成低内存报告并将其存储在设备上。

低内存报告的格式与其余崩溃报告的不一样之处在于,应用程序线程没有回溯。低内存报告以相似于崩溃报告的标头的标头开头。标题后面是列出系统范围内存统计信息的字段集合。记下“ 页面大小”字段的值。低内存报告中每一个进程的内存使用量按内存页数报告。

低内存报告中最重要的部分是进程表。此表列出了生成低内存报告时全部正在运行的进程,包括系统守护程序。若是一个过程被“抛弃”,缘由将列在[reason]列下。一个过程可能会被抛弃

  • 一、[per-process-limit]:该进程超过了系统强加的内存限制。驻留内存的每进程限制由系统为全部应用程序创建。越过此限制使该过程有资格终止。
  • 二、[vm-pageshortage] / [vm-thrashing] / [vm]:因为内存压力,该进程被终止。
  • 三、[vnode-limit]:打开的文件太多。
  • 四、[highwater]:系统守护进程越过其高水位标记以便使用内存。
  • 五、[jettisoned]:因为其余缘由,该过程被抛弃了。

文章转载自:iOS crash官方文档

想要更加详细的了解,能够参考一下的一些文章

相关文章
相关标签/搜索