iOS APP 崩溃日志分析
文章目录
在日常开发中,我们难免遇到崩溃.如果是在开发过程中,我们可以直接通过 Xcode 来找到问题所在。如果是在测试的时候崩溃,我们也可以轻易的通过测试机导出 crash 进行问题定位。 可是一旦当产品上线之后,这一切就变得不那么容易了。庆幸的是市场上已经出现了一些比较好的第三方 crash 统计服务比如 bugly。 可以让我轻松了解到crash时的堆栈信息。 但是bugly也有符号化不到位的情况, 比如:
那么在这种情况下我们应该怎么办呢?
崩溃日志符号化
使用xcode符号化
条件: (需要崩溃手机)
如果发生崩溃的手机在手边.可以连上电脑 在 Xcode 中的 organizer>device 中直接查看符号化好的日志.
优点: 操作简单
缺点: 如果崩溃日志较多 还需要崩溃时间才能确定是哪个crash文件. crash不好统计
使用symbolicatecrash符号化
条件: crash文件 dsYM 文件 symbolicatecrash
symbolicatecrash 位置
|
|
方法: 将三个文件放在同级下 然后打开终端 进入文件夹目录下
- 设置环境变量
|
|
- 符号化
|
|
优点:操作简单
缺点:适合针对单个crash 文件符号化
使用 atos 命令符号化
条件: dSYM 和堆栈信息
使用 grep
命令 获取该模块的 指令集和加载起始地址
|
|
然后用获得的指令集(armv7) 和起始地址(0x4000) 来符号化
|
|
注意 模块只能定位到本模块的位置 不能越层 如:
AFN.framework.dSYM 只能定位到AFN内的目标地址位置
appName.app.dSYM 只能定位到app内代码的地址位置
优点: 只需要堆栈信息 和符号表就可以. 可以在获取不到Crash文件 但在bugly等第三方统计中获得了堆栈信息的情况下使用.
缺点: 一次只能符号化一行,比较繁琐.(可以作为bugly符号化不完全情况下的补充.)
有兴趣的可以实际动手操作下:
Xcode 自带 atos 脚本: symbolicatecrash 下载
crash 文件 : demoAPP.crash 下载
符号表: demoAPP.app.dSYM 下载
第三方模块符号表 RBPlayer.framework.dSYM 下载
crash文件组成分析
让我们看一下一个实际的 crash 文件组成
|
|
进程信息
第一部分是闪退进程的相关信息。
Incident Identifier
是崩溃报告的唯一标识符。
CrashReporter Key
是与设备标识相对应的唯一键值。虽然它不是真正的设备标识符,但也是一个非常有用的情报:如果你看到 100 个崩溃日志的 CrashReporter Key 值都是相同的,或者只有少数几个不同的 CrashReport 值,说明这不是一个普遍的问题,只发生在一个或少数几个设备上。
Hardware Model
标识设备类型。 如果很多崩溃日志都是来自相同的设备类型,说明应用只在某特定类型的设备上有问题。上面的日志里,崩溃日志产生的设备是 iPhone 5 。
Process
是应用名称。中括号里面的数字是闪退时应用的进程ID。
基本信息
Version
APP的版本号
OS Version
iOS操作系统版本号 iPhone OS 10.3.1 (14E304)
10.3.1:系统版本
14E304:build 号
这里要所以下 build 号。每个系统版本号有可能会对应多个 build 号。如苹果发布的 10.3.1 会有几个版本,如:电信版本、联通版本等。build 号我们后面对日志符号化的时候会用到。
异常信息
在这部分,你可以看到闪退发生时抛出的异常类型。还能看到异常编码和抛出异常的线程。根据崩溃报告类型的不同,在这部分你还能看到一些另外的信息。
Crashed Thread
crash 线程号。可以根据这个编号找到对应的 crash 调用堆栈,当前crash 线程的编号为 0,所以我们可以直接找到 crash 线程的堆栈信息:
线程回溯
线程回溯这部分提供应用中所有线程的回溯日志。 回溯是闪退发生时所有活动帧清单。它包含闪退发生时调用函数的清单。
Crash 调用堆栈
这一部分是我们分析 crash 最重要的信息。一般我们会把焦点放在 crash 线程的堆栈上。因为这样可以帮我最快的找到 crash 的原因。
看下面这行日志:
|
|
这条调用栈包括下面四部分:
- 模块号:这里是 6
- 二进制库名:这里是 demoApp
- 调用方法的地址:这里是 0x005b6e78
- 第四部分分为两列,基地址和偏移地址。此处基地址为 0x66000,偏移地址为 19244367。基地址指向 crash 的模块(也是模块的 load 地址)如 UIKit。偏移地址指向 crash 代码的行数。如何转换我们后面讨论。这些信息都保存在 dsym 文件中。
动态库信息
这些信息包括动态库名称、UUID、模块起始地址、模块结束地址、指令集种类、安装路径等信息。
这些信息都是在符号化堆栈用到的。后面我们讨论怎么用。
特别注意
注意: 你必需同时保留应用二进制文件和 .dSYM 文件才能将崩溃日志完整符号化。每次提交到 iTunes Connect 的构建都必需归档保存。
.dSYM 文件和二进制文件是特定绑定于每一次构建和后续构建的,即使来自相同的源代码文件,每一次构建也与其他构建不同,不能相互替换。
如果你使用 Build 和 Archive 命令,这些文件会自动放在适当位置。 如果不是使用 Build 和 Archive 命令,最好放到单独的文件夹保存。
附录
符号化好的crash文件
|
|
从符号化完的堆栈信息可以清楚的看出 崩溃是由 RBPlayer 类 RBPlayerSlider 文件 setValue: 方法中 第 194 行引起的. 该行对 layer 的 frame 和 position 进行赋值操作时引起了崩溃.
–原创所有,转载请注明出处。