iOS基础之崩溃日志符号化

在 App 审核时,可能会出现类似下图这种被拒的情况:

Reject.png

原来出现了闪退,这对于 App 是个致命的问题,要马上修复。那么问题来了,我测试的时候没有崩溃的问题呀!我看不到 crash 的信息呀?我并不知道问题出现在哪里呀?
这时,我们就要用到崩溃日志了,这里面包含了我们需要的内容。当你拿到崩溃日志的时候,你看到的是这样的东西:

Unsymbolicated.png

顿时一脸懵逼,感觉不会再爱了。


What?.jpg

别急,只需要做一些简单的操作,把它符号化之后就变成人看的东西了。
本文将从以下几部分讲述崩溃日志符号化:

  • 什么是崩溃日志
  • 什么是符号化
  • 如何判断符号化是否完成
  • 如何获取崩溃日志
  • 如何符号化
    • 使用 symbolicatecrash 符号化
    • 使用 Xcode 符号化

什么是崩溃日志

概念部分我们来看一下相关的官方文档

When an application crashes, a crash report is created and stored on the device. Crash reports describe the conditions under which the application terminated, in most cases including a complete backtrace for each executing thread, and are typically very useful for debugging issues in the application. You should look at these crash reports to understand what crashes your application is having, and then try to fix them.

崩溃日志就是在 App 异常终止时,生成的记录运行环境、线程、栈回溯的用于调试的文件。

什么是符号化

Symbolication is the process of resolving backtrace addresses to source code method or function names, known as symbols. Without first symbolicating a crash report it is difficult to determine where the crash occurred.

符号化就是解决把栈回溯地址转化为为源码方法名或函数名的过程。

如何判断符号化是否完成

A crash report may be unsymbolicated, fully symbolicated, or partially symbolicated. Unsymbolicated crash reports will not contain the method or function names in the backtrace. Instead, you have hexadecimal addresses of executable code within the loaded binary images. In a fully symbolicated crash report, the hexadecimal addresses in every line of the backtrace are replaced with the corresponding symbol. In a partially symbolicated crash report, only some of the addresses in the backtrace have been replaced with their corresponding symbols.

Obviously, you should try to fully symbolicate any crash report you receive as it will provide the most insight about the crash. A partially symbolicated crash report may contain enough information to understand the crash, depending upon the type of crash and which parts of the backtraces were successfully symbolicated. An unsymbolicated crash report is rarely useful.

SymbolicationLevels.png

符号化分为三个级别:未符号化、半符号化和全符号化:

级别 特点 是否有用
未符号化 全是十六进制地址 不是人给看的,基本没用
半符号化 部分十六进制地址、部分方法名函数名 部分是给人看的,有点用
全符号化 全是方法名函数名 全都是给人看的,特别有用

由此可见,全符号化才是最终的完成状态。

如何获取崩溃日志

  • 审核时出现的问题,苹果官方会把崩溃日志作为回复的附件,直接点击下载即可。
  • 从设备中获取(有时已经是完全符号化状态,可直接查看)
    1. 目标设备连接电脑 > 打开Xcode > Window > Devices (快捷键 shift + ⌘ + 2)
    2. 选择 View Devices Logs
    3. 在列表中选择文件,右键选导出

如何符号化

本文介绍两种方法,第一种相对第二种有些复杂,其实按步骤做也是很简单的

  • 使用 symbolicatecrash 符号化
    symbolicatecrash 是苹果官方提供的符号化工具,需要我们在终端输入命令执行,在此之前还有一些准备工作。
  1. 在桌面创建文件夹,把 symbolicatecrash、崩溃日志和 dSYM 文件放进去
    首先,找到 symbolicatecrash,打开终端输入:
find /Applications/Xcode.app -name symbolicatecrash -type f

会输出 symbolicatecrash 的路径位置(可能不一样)

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash

拷贝 symbolicatecrash 文件到创建的文件夹中。
然后,查看崩溃日志文件的拓展名,如果是 .txt(苹果审核时返回的是.txt文件),修改为 .crash。
最后,找到崩溃日志对应的 dSYM 文件(dSYM 是保存十六进制函数地址映射信息的中转文件,符号化过程中的十六进制函数地址对应的方法名函数名就保存在这个文件中)。
dSYM 文件在打好的包中:
· 打开 Organizer 面板:Xcode > Window > Organizer
· 选择与崩溃日志版本对应的包,右键 Show In Finder
· 选择 xcarchive 文件,右键 显示包内容
· dSYM 文件就在 dSYMs 文件夹里
Xcode 默认打包时不创建 dSYM 文件,需要在 Build Settings 设置 Debug Information Format 为 DWARF with sSYM File(如下图),否则 dSYMs 文件夹是空的。


Setting.png

2.查看 dSYM 文件的 uuid,终端输入下面的命令

dwarfdump --uuid dSYM文件路径

得到如下输出:

UUID: CD78BB00-BE55-3FC2-89AC-580437E54D36 (armv7) + 很长的路径
UUID: AB0EC401-77B7-3FF6-BF99-567FA14A45FC (arm64) + 很长的路径

3.对比崩溃日志中的 uuid 与 输出的 uuid 是否一致
下面列出了崩溃日志中 Header 的部分信息:

{
    "app_name": "XXXXXX",
    "timestamp": "2017-06-03 02:15:01.50 +0800",
    "app_version": "1.2.00",
    "slice_uuid": "ab0ec401-77b7-3ff6-bf99-567fa14a45fc",
    "adam_id": 1128617051,
    "build_version": "1.0.1",
    "share_with_app_devs": false,
    "is_first_party": false,
    "bug_type": "109",
    "os_version": "iPhone OS 10.3.2 (14F89)",
    "incident_id": "1DE9E3EF-D2DF-4A54-992A-1912BF8D285A",
    "name": "XXXXXX"
}
Incident Identifier: 1DE9E3EF-D2DF-4A54-992A-1912BF8D285A
CrashReporter Key:   5abb1af3a567bd61ac640b7daf57c472c59d9547
Hardware Model:      xxx
Version:             1.0.1 (1.2.00)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]

这里我们需要关注两个字段 "Code Type" 和 "slice_uuid","Code Type"的类型为 ARM-64,所以从上一步输出的 UUID 信息中,找到 arm64 类型对应的 UUID 为 "AB0EC401-77B7-3FF6-BF99-567FA14A45FC",对比 Header 信息中的 "slice_uuid",如果不一致,说明生成崩溃日志的应用包与当前 dSYM 所在的包不同;如果一致,进行下一步。
4.执行 symbolicatecrash 命令
终端 cd 到第1步创建的文件夹,先定义 DEVELOPER_DIR:

export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

执行符号化:

./symbolicatecrash XXXX/XXXX/appName.crash XXXX/XXXX/appName.app.dSYM > customName.crash

命令执行完成后,在文件夹中会多出一个 customName.crash 文件,不出意外的话,这个就是完成符号化的崩溃日志。
PS:这个命令中 .crash 文件的路径一定要在 .dSYM 文件路径之前,否则会符号化失败;路径可以简化为 ./,生成的文件拓展名也可以为 log、txt等

./symbolicatecrash ./appName.crash ./appName.app.dSYM > customName.log

5.查资料的时候,有些文章上说用 symbolicatecrash 符号化还需要应用的 .app 文件,我没有把这个文件放到创建的文件夹中,符号化也成功了,如果大家在操作的时候出现了什么问题,可以先试试复制一份 .app 文件到文件夹中,再执行命令。
应用的 .app 文件,在打包后导出的 .ipa 文件里。把 .ipa 文件的拓展名改成 .zip,解压打开,在 Payload 文件夹中。

  • 使用 Xcode 符号化
    这种方式比较简单,具体操作如下:
    首先,处理崩溃日志的拓展名如果不是 .crash 需要改成 .crash。
    然后,设备连接电脑 > 打开Xcode > Window > Devices (快捷键 shift + ⌘ + 2),选择 View Devices Logs
    最后,把崩溃日志拽到左侧的列表中,Xcode 就会自动符号化。
    当然,这种方式也要满足一定条件这,如 Mac 中要有应用的二进制文件和 dSYM 文件。

To symbolicate a crash report, Xcode needs to be able to locate the following:
·The crashing application's binary and dSYM file.
·The binaries and dSYM files for all custom frameworks that the application links against. For frameworks that were built from source with the application, their dSYM files are copied into the archive alongside the application's dSYM file. For frameworks that were built by a third-party, you will need to ask the author for the dSYM file.

结果对比分析

完成符号化之后,我们来对比一下未符号化和全符号化的崩溃日志,还有 Xcode 控制台打印的关键信息(只截取部分信息)。

未符号化.png

全符号化.png
Xcode控制台.png

由此可见,正如前面所说,符号化完成后,崩溃日志中所有的十六进制地址都转化为了方法名函数名,而且与控制台打印的内容基本一致。
定位崩溃问题主要看 Last Exception Backtrace 部分,如红框所示,在 NSException 抛出异常之前,应用正在进行字符串截取,所以可能是字符串为空或 index 越界导致的。

关于崩溃日志符号化的操作就讲这么多。

还有这种操作?.jpg

第一次写东西,写得不是很好,如有问题欢迎指正。
**若有转载,请注明出处,谢谢~ **

(完)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容