崩溃日志的符号化

app上架后,通过崩溃统计平台,可以看到用户的崩溃日志,有了崩溃日志,和该发布包对应的dSYM文件,我们就可以定位到发生崩溃的代码。那么第一步,就是找到对应包体的dSYM文件,并确认与崩溃日志的对应关系。

通过UUID确认对应关系

如果是通过Xcode的Archive打包,可通过以下路径找到dSYM文件:

$ cd ~/Library/Developer/Xcode/Archives/yyyy-mm-dd/appname.xcarchive/dSYMs

在终端进入dSYM文件所在路径,运行以下命令(dSYM文件的路径是xcarchive/dSYMs/):

$ dwarfdump --uuid YourApp.app.dSYM

你将得到以下结果,它们分别对应32位、64位处理器的机子(iphone5S之前的机器为32位机):

$ UUID: FDCFADE2-9A18-3631-80F4-84601BFB47C7 (armv7) YourApp.app.dSYM/Contents/Resources/DWARF/YourApp
$ UUID: 3393365E-FB29-381C-AE01-F14ABB8E458A (arm64) YourApp.app.dSYM/Contents/Resources/DWARF/YourApp

而崩溃日志的UUID位于日志中Binary Images第一行尖括号内。如下面所示,

Binary Images:
0x1029b0000 - 0x10394bfff +YourApp arm64 <8309e255de663204b3e9ddd4138e3111>
/var/containers/Bundle/Application/AFD507CF-5D16-4518-BD70-D725FF0CFA84/YourApp.app/YourApp

UUID一旦对应上了,就进入下一步,符号化。像上面举的例子,UUID就没对应上,不能进行符号化。

局部符号化

所谓局部符号化,就是对崩溃日志中的某一个崩溃地址进行符号化,与全局符号化相对应。这里我们需要两个地址,一个是二进制镜像运行时加载的地址(后面简称段地址),一个是崩溃代码所在的调用栈地址。
以上面的崩溃日志片段为例,“Binary Images:”后面跟着的 0x1029b0000 为段地址,结合下面截取的崩溃日志片段,崩溃时的调用栈地址是0x0000000102c124c4

Last Exception Backtrace:
0 CoreFoundation          0x000000018184b164 0x181708000 + 1323364
1 libobjc.A.dylib              0x0000000180a94528 0x180a8c000 + 34088
2 CoreFoundation          0x00000001817e3c9c 0x181708000 + 900252
3 CoreFoundation          0x0000000181718b0c 0x181708000 + 68364
4 YourApp                      0x0000000102c124c4 0x1029b0000 + 2499780

这里使用的是atos工具,一个可以把地址转换为函数名(包括行号)的工具, atos 语法:

atos -arch arm64 -o ‘dysm文件路径’ -l 段地址 调用栈地址1 调用栈地址2

按照上面的例子,此处命令应为:

$ atos -arch arm64 -o '~/.../xxx.xcarchive/dSYMs/YourApp.app.dSYM/Contents/Resources/DWARF/YourApp' -l 0x1029b0000 0x0000000102c124c4

该命令使用的参数:

  • -arch —— 所运行设备的架构,有arm64,armv7
  • -o —— 符号文件或者含有调试符号的可执行文件(debug编译所产生的可执行文件默认是包含调试符号的)。
  • -l —— 二进制镜像运行时加载的地址,这里也称段地址
  • 最后跟着的就是需要符号化的调用栈地址

终端输出:

$ main (in YourApp) (main.m:16)

注意:
0x1029b0000 + 2499780 = 0x0000000102c124c4

全局符号化

使用以上方法进行符号化的范围有限,效率太低,有没有一次性对整个崩溃日志进行符号化的操作,当然是有的,Xcode本身就有提供这么一个工具。首先,找到这个工具,命令如下:

$ find /Applications/Xcode.app -name symbolicatecrash -type f

我的机子安装的是Xcode版本是9.3,终端输出如下,这里我使用的是最后一个路径的symbolicatecrash工具:

$ /Applications/Xcode.app/Contents/Developer/Platforms/WatchSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
$ /Applications/Xcode.app/Contents/Developer/Platforms/AppleTVSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
$ /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
$ /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

方法一

对这个工具的使用,有两种方法,一种是把symbolicatecrash、YourApp.app.dSYM、*.crash文件放到一个文件夹里面,还有一种,就是直接使用原始路径下的symbolicatecrash,但每次都输入那么长一串路径确实不方便,这里建议先对symbolicatecrash设置一个使用的alias,命令如下:

$ alias symbolicatecrash="/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash"

然后再执行:

$ export 'DEVELOPER_DIR'="/Applications/Xcode.app/Contents/Developer"

如果不执行此命令,进行下面的操作时会报以下错误:

$ Error: "DEVELOPER_DIR" is not defined at /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash line 69.

设置完这一切之后,在终端切换到YourApp.app.dSYM、*.crash文件所在路径下,就可以使用以下命令进行符号化了(-o也可改为>):

symbolicatecrash 崩溃日志 dSYM文件 -o 输出文件

实际操作如下(符号化后的崩溃日志将写入该路径下的processed.crash中):

$ symbolicatecrash ./*.crash ./YourApp.app.dSYM -o processed.crash

方法二

如果设置alias失败,可以使用方法二,把symbolicatecrash复制到操作路径下,执行以下命令:

$ ./symbolicatecrash ./*.crash ./YourApp.app.dSYM -o processed.crash

批量符号化

  前面提到Xcode提供了符号化工具,那么我们可以直接使用Xcode进行符号化吗,答案当然是可以的。
  如果是本机编译的包,那么打开Xcode->Window->Devices and Simulators,选择Devices->View Device Logs,找到我们需要分析的crash文件,一般情况下,这时候Xcode已经替你自动符号化好了。如果没有,可以右键crash文件,选择Re-Symbolicate Log。
  如果非本设备的crash文件,可以把crash文件拖进去DeviceLogs列表,其他操作同上。
  如果是非机编译的包,我们需要把对应的dSYM文件放入某个文件夹下,然后执行手动索引命令 “mdimport 文件夹路径“,如:

$ mdimport ~/CrashAnalyze

  再回去Xcode看,就可以看到符号化好的crash文件了。借助这个方法,我们可以把所有版本的.dSYM文件,都放入该路径下,然后把崩溃日志集体拖入Xcode中,这样就可以实现批量符号化了,大大提供了工作效率。

注意:
进行该操作时,我只是创建了个空的CrashAnalyze文件夹,忘记把dSYM文件放进去,执行了mdimport命令之后,竟然也实现了自动符号化,原因不明。

自动符号化

现在更流行的,也是更适合团队项目质量管控的做法,是使用crash report管理系统来管理crash,譬如国外的Crashlytics,还有国内的Bugtags。这些只要引入该第三方的SDK,进行启动时注册,然后在管理平台进行版本管理就可以了,此处就不进行详述了。

参考:
Symbolicating Your iOS Crash Reports

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值