最近分析了一波上传的crash日志,方法和iOS的几乎一模一样,毕竟都是苹果的东西。这里对于一些基础的crash日志里面的信息不作解释,只介绍如何符号化crashlog获取具体的崩溃代码位置,方便以后自己查阅。第一次写文章水平有限,有不对的地方希望大家指出,共同学习,共同进步!
首先需要获取你发布产品的dSYM文件,如果你上线的产品是在本地打包的话,最好保存一份Xcode生成的.dSYM文件。如果是统一用服务器打包的话,应该会保存有一份.dSYM文件,例如上传到192.../** 文件夹下,如果没有,建议锤死搭建环境的人。
接下来,打开crash文件,查看是否已经符号化。crash文件大体分为3种:Unsymbolicated(未符号化)、Partially Symbolicated(半符号化)和 Fully Symbolicated(符号化)。
一般我们拿到的.crash都是Unsymbolicated。在符号化之前,首先确保.crash文件相关崩溃模块的uuid和相关崩溃模块的.dSYM的uuid一致,这样得到的结果才是准确的。这里为什么说相关崩溃模块呢,稍后再做解析。
dwarfdump获取uuid
通过dwarfdump --uuid <Path to dSYM file>得到.dSYM的uuid(<>不需要)。例如得到的uuid:17D96A43-531E-3E3C-9399-A7D1FCCD015F。这个和.crash上的uuid:17d96a43531e3e3c9399a7d1fccd015f一致,所以我们可以获得正确的偏移结果。
那么怎么看.crash 文件崩溃模块的uuid呢?如下图:
其中TheElements即为崩溃的模块,app可能由多个framework,多个bundle组成,所以TheElements有可能就是你的app名字,也有可能是某个bundle或者某个framework的名字。所以刚才说:相关崩溃模块的uuid和相关崩溃模块的.dSYM的uuid。
dwarfdump获取具体崩溃代码信息
a.获取符号表中的TEXT段起始地址
$otool -l <Path to dSYM file>/Contents/Resources/DWARF/<binary image name>
找到如下的运行结果:
Load command 2
cmd LC_SEGMENT_64
cmdsize 1032
segname __TEXT
vmaddr 0x0000000000000000
vmsize 0x0000000000023000
fileoff 0
filesize 0
maxprot 0x00000007
initprot 0x00000005
nsects 12
flags 0x0
其中vmaddr 0x0000000000000000即为起始地址。
b.崩溃信息还原
首先找到崩溃的地址。例如:
7 TheElements 0x0000000109ae552a 0x109ae3000 + 9514
其中9514(0x252A)就是偏移量,实际堆栈地址可由下面公式来计算:
实际堆栈地址 = TEXT段起始地址 + 偏移量
所以计算的出结果为:0x252A。
在终端输入如下命令:
dwarfdump --arch <Binary Architecture> <Path to dSYM file> --lookup 0x252a
<Binary Architecture>,可以通过.crash文件信息得到。比如Mac OS的应用程式为:x86_64,iOS的为:arm64等。
得到结果:
Line table file: 'TSDownloadObj.m' line 164, column 13 with start address 0x0000000000002522
Looking up address: 0x000000000000252a in .debug_frame... not found.
所以崩溃的代码所在文件为TSDownloadObj.m,行号为164。
通过atos符号化Crash Report
通过上面的步骤确认uuid一致后,输入如下命令:
atos -arch <Binary Architecture> -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l <load address> <address to symbolicate>
例如:
atos -arch x86_64 -o <Path to dSYM file>/Contents/Resources/DWARF/<binary image name> -l 0x109ae3000 0x0000000109ae552a
得到如下结果:
-[TSDownloadObj URLSession:task:didCompleteWithError:] (in TheElements) (TSDownloadObj.m:164)
这样得到的结果和dwarfdump的结果一模一样。
苹果官方文献
如果没有.dSYM文件,那么就比较麻烦了,需要符号化.crash的话,必须保证本地或者服务器上路径:~/Library/Developer/Xcode/DerivedData/YOUR_PROJECT_CONFIGFILE存在,即可通过dsymutil命令提取.dSYM文件。
dsymutil appName.app/Contents/MacOS/appName
如果上述路径不存在的话,虽然能提取出.dSYM文件,但是这个文件是不能用来符号化的。路径不存在的话运行上述命令会得到一堆类似如下的警告:
warning: (x86_64) /***/***/Library/Developer/Xcode/DerivedData/***-bivwwbqnjqxnlrcoeospkrentncw/Build/Intermediates.noindex/***.build/Release/***.build/Objects-normal/x86_64/TUILinkTextField.o unable to open object file: No such file or directory
***-bivwwbqnjqxnlrcoeospkrentncw即为YOUR_PROJECT_CONFIGFILE。