如图所示是崩溃日志线程回溯信息,其中的调用堆栈都是二进制地址,而不是可读的函数名称所以须要对崩溃日志进行解析,解析成能够理解的函数调用堆栈。 xcode
dSYM
符号文件crashlog
解析须要调试符号表文件 dSYM(debugging symbols)
, dSYM
文件其实是从Mach-O
文件抽取调试信息获得的文件目录。在编译工程时, debug
模式会默认选中生成dSYM
文件, 该配置可在 Build Setting|Build Option
中更改。 dSYM
文件生成比较耗时,若是不须要进行 crashlog
解析,能够选择不生成。 markdown
Debug
下能够在DeriveData
的目录下获取到dSYM文件.achive
目录下找到对应的dSYM
文件将crashlog
、 dSYM
文件和可执行文件放在同一目录下,而后将 crashlog
拖拽至 Devicelog
中,右键 Re-symbolicate Log
就能解析。
app
symbolicatecrash
的路径 一般symbolicatecrash的路径为
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
函数
首先将崩溃日志,dSYM以及symbolicatecrash复制出来放到同一个文件夹,而后cd到当前文件夹 ,运行以下命令解析./symbolicatecrash temp.crash testxcConfig.app.dSYM > result.log
工具
export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"
其中真正保存保存数据的是 DWARF 文件, DWARF(Debuging With Arbitrary Format)是ELF 和 Mach-O 等文件格式中用来存储和处理调试信息的标准格式。 DWARF 中的数据是高度 压 缩 的 , 能够经过
dwarfdump
命令提取可读信息,好比提取关键的调试信息.debug_info、.debug_line。 注释: ELF
、Mach-O
用于存储二进制文件、可执行文件、目标代码和共享库的格式文件。 ui
以某 crashlog 文件为例,以下图所示。是一个Exception
类型的异常,从下至上依次为该线程的调用堆栈,右边红色框第一列为运行时的堆栈地址,第二列为进程运行时的起始地址(testxcConfig 全部行起始地址都相同),第三列为运行时的偏移地址。 运行时堆栈地址=运行时起始地址+偏移地址,以第 4 行为例。
0x1022cd990=0x1022c8000 + 0x5990(22928)
,以上地址均为 app 发生崩溃时的运行地址,根据虚拟内存偏移地址不变的原理,只要知道符号表 TEXT 段的起始地址,加上偏移量(0x5990)就能获得崩溃地址对应符号表中的地址, 符号表 TEXT 段的起始地址可经过如下命令得到。 那么崩溃地址(
0x1022cd990
)对应符号表中的地址为:0x100005990 =0x0000000100000000+0x5990
2) 地址重映射 获取符号表地址后,在 debug-info
章节中查找包含该地址的 DIE(Debug Information Entry)
单元就能获知该符号地址对应的函数名称(name)、 函数所在的文件路径(decl file)和函数所在行数(decl line),以下图所示。 上述步骤解析出了函数相关信息, 下面进一步获取该地址对应的准确行数, 这须要借助
debug_line
章节, debug_line
章节以文件为单位,准确记录了文件中的每一行对应的符号表地址, 0x100005990
对应 AppDelegate.m
的第 20
行。 3) 手动解析 crashlog 当有完整的
crashlog
文件和对应的 dSYM
文件时,以上过程能够由 Xcode
自动完成。但对于用户反馈的 crash
, 须要用户手动复制本地的 crashlog
文件,而一般 crashlog 文
本较长,完整复制其实比较麻烦,那么此时能够只复制崩溃线程的 crash
信息,并经过手动解析。手动解析 crash
可使用 dwarfdump、 atos
工具, 命令以下。spa
方法2、三都使用了
atos
解析,区别是方法三不须要获取符号表地址, 其后倒数第一个地址为运行时堆栈地址,倒数第二个地址为进程起始地址。 手动解析另外一个应用场景是,若开发人员为了跟进某一偶现问题在日志中记录的是运行时的二进制地址,那么能够经过对应的 dSYM
文件手动解析出调用函数明文。命令行
crashlog
对应的 dSYM
文件?打开终端,使用如下命令获取 dSYM
文件对应的 uuid
, 并与crashlog
文件Binary Image
后面的字符对比,若是字符彻底相同,就说明 dSYM
文件与crashlog
对应。
另外可使用mdfind命令去寻找指定uuid的
dSYM
文件,以下,uuid需大写并转化成格式,以下图 mdfind "com_apple_xcode_dsym_uuids == D5644244-F2C4-3C96-BD63-EF0F4DA518FA"
线程
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
值得注意的是,只有可执行文件为
debug
模式产物时,才能使用上述方式手动抽取调试符号表文件(dSYM)
, release
模式没法抽取。 由于debug
产物会保存调试信息,而release
产物不会, dSYM
文件就是从调试信息中抽取出来的。debug