iOS崩溃解析&原理介绍

1. 为什么崩溃日志需要解析

如图所示是崩溃日志线程回溯信息,其中的调用堆栈都是二进制地址,而不是可读的函数名称因此需要对崩溃日志进行解析,解析成可以理解的函数调用堆栈。


image

2.生成dSYM符号文件

crashlog 解析需要调试符号表文件 dSYM(debugging symbols)dSYM 文件实际上是从Mach-O 文件抽取调试信息得到的文件目录。在编译工程时, debug 模式会默认选中生成dSYM文件, 该配置可在 Build Setting|Build Option 中更改。 dSYM文件生成比较耗时,如果不需要进行 crashlog 解析,可以选择不生成。

image

2.1 Debug下可以在DeriveData的目录下获取到dSYM文件

image

2.2 打包的时候可以在生成的.achive目录下找到对应的dSYM文件

image

2 解析方法

2.1 Xcode 解析

crashlogdSYM 文件和可执行文件放在同一目录下,然后将 crashlog 拖拽至 Devicelog中,右键 Re-symbolicate Log 就能解析。

image

image

2.2 使用 symbolicatecrash 命令行解析

  • 1.首先找到symbolicatecrash的路径
    image

    通常symbolicatecrash的路径为/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
  • 2.命令行解析
    首先将崩溃日志,dSYM以及symbolicatecrash复制出来放到同一个文件夹,然后cd到当前文件夹
    ,运行如下命令解析./symbolicatecrash temp.crash testxcConfig.app.dSYM > result.log
    image
  • 3.首次运行需要先运行命令export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"

3.解析原理

dSYM 文件介绍

image

其中真正保存保存数据的是 DWARF 文件, DWARF(Debuging With Arbitrary Format)是ELF 和 Mach-O 等文件格式中用来存储和处理调试信息的标准格式。 DWARF 中的数据是高度 压 缩 的 , 可以通过dwarfdump命令提取可读信息,比如提取关键的调试信息.debug_info、.debug_line。
注释: ELFMach-O用于存储二进制文件、可执行文件、目标代码和共享库的格式文件。
image

解析流程

  1. 计算崩溃地址对应符号表中的地址
    以某 crashlog 文件为例,如下图所示。是一个Exception类型的异常,从下至上依次为该线程的调用堆栈,右边红色框第一列为运行时的堆栈地址,第二列为进程运行时的起始地址(testxcConfig 所有行起始地址都相同),第三列为运行时的偏移地址。
    image

    运行时堆栈地址=运行时起始地址+偏移地址,以第 4 行为例。0x1022cd990=0x1022c8000 + 0x5990(22928),以上地址均为 app 发生崩溃时的运行地址,根据虚拟内存偏移地址不变的原理,只要知道符号表 TEXT 段的起始地址,加上偏移量(0x5990)就能得到崩溃地址对应符号表中的地址, 符号表 TEXT 段的起始地址可通过以下命令获得。
    image

    那么崩溃地址(0x1022cd990)对应符号表中的地址为:0x100005990 =0x0000000100000000+0x5990
  2. 地址重映射
    获取符号表地址后,在 debug-info 章节中查找包含该地址的 DIE(Debug Information Entry)单元就能获知该符号地址对应的函数名称(name)、 函数所在的文件路径(decl file)和函数所在行数(decl line),如下图所示。
    image

    上述步骤解析出了函数相关信息, 下面进一步获取该地址对应的准确行数, 这需要借助debug_line章节, debug_line 章节以文件为单位,准确记录了文件中的每一行对应的符号表地址, 0x100005990 对应 AppDelegate.m 的第 20 行。
    image
  3. 手动解析 crashlog
    当有完整的 crashlog 文件和对应的 dSYM 文件时,以上过程可以由 Xcode 自动完成。但对于用户反馈的 crash, 需要用户手动复制本地的crashlog 文件,而通常crashlog 文本较长,完整复制其实比较麻烦,那么此时可以只复制崩溃线程的 crash 信息,并通过手动解析。手动解析 crash 可以使用 dwarfdump、 atos 工具, 命令如下。
  • 方法一


    image
  • 方法二


    image
  • 方法三
    image

    方法二、三都使用了atos解析,区别是方法三不需要获取符号表地址, 其后倒数第一个地址为运行时堆栈地址,倒数第二个地址为进程起始地址。
    手动解析另一个应用场景是,若开发人员为了跟进某一偶现问题在日志中记录的是运行时的二进制地址,那么可以通过对应的 dSYM 文件手动解析出调用函数明文。

4.常见问题

  1. 如何找到crashlog 对应的 dSYM 文件?
    打开终端,使用以下命令获取 dSYM 文件对应的 uuid, 并与crashlog文件Binary Image后面的字符对比,如果字符完全相同,就说明 dSYM文件与crashlog对应。

    image

    image

    另外可以使用mdfind命令去寻找指定uuid的dSYM文件,如下,uuid需大写并转化成格式,如下图
    mdfind "com_apple_xcode_dsym_uuids == D5644244-F2C4-3C96-BD63-EF0F4DA518FA"
    image

  2. 如何手动生成 dSYM 文件?
    如果在编译之前忘记在 buildsetting 中选中生成 dSYM文件,然而 app 又发生了崩溃,那么可以通过 app 的可执行文件再手动生成 dSYM 文件。
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil /Users/ranjingfu/Desktop/testxcConfig/testxcConfig.app/testxcConfig -o out.dSYM

    image

    值得注意的是,只有可执行文件为 debug 模式产物时,才能使用上述方式手动抽取调试符号表文件(dSYM)release模式无法抽取。 因为debug产物会保存调试信息,而release产物不会, dSYM文件就是从调试信息中抽取出来的。

解析后的崩溃日志实例

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

推荐阅读更多精彩内容