iOS Crash的收集与分析
2021-01-21 本文已影响0人
YanZi_33
Crash的收集
- 使用Xcode从设备中获取Crash日志,新建工程CrashTest;
- 将你的iPhone手机连接到Mac,然后选择
Xcode->Windows->Device and Simulator
,然后点击View Device Logs
,你会看到手机上会有好多Log,其中Type为Crash的就是崩溃的Log,如下图所示:
- 经过多方测试需要将iPhone从Mac上断开链接,当场发生的崩溃才立即会显示,否则不会立即显示;
- 从真机设备中直接获取Crash日志;
- 1)打开
设置->隐私->分析->分析数据
,在其中找到你想要的应用程序的日志,日志将使用以下格式命名:<应用名称> _ <崩溃时间> _ <设备名>; - 2)选择所需的日志,复制文本或点击右上角的分享按钮分享出去,并且把分享得到的.ips.synced或者复制文本而来的.txt文件的后缀名改为.crash,因为Xcode不接受没有.crash扩展名的崩溃日志;
- 1)打开
Crash分析定位
-
在分析Crash之前我们首先来了解一下
.dSYM文件
; -
dSYM 是保存十六进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中
,每次编译项目的时候都会生成一个新的 dSYM 文件,我们应该保存每个正式发布版本的 dSYM 文件,以备我们更好的定位问题,一般是在我们 release打包Archives 时保会存对应的版本文件,里面也有对应的.dSYM 和 .app 文件
; -
dSYM文件路径为:
~/Library/Developer/Xcode/Archives
;
-
dSYM 文件在 debug 模式下默认是不生成的
,我们需配置Build Settings -> Debug Information Format
下,将 DWARF 修改为DWARF with dSYM File
,再重新编译下就能生成 .dSYM文件了,直接去项目工程的Products 目录
下找就行;
方法一:使用symbolicatecrash工具
进行crash分析,下面使用的是Debug模式下生成的相关文件进行实例分析,正式release环境会涉及到打包和开发者账号,有点麻烦;
- symbolicatecrash 是 Xcode 自带的 crash 日志分析工具,在终端中输入命令:
find /Applications/Xcode.app -name symbolicatecrash -type f
,定位到它如下所示:
-
可以看到返回了五个不同的路径,我使用的路径是:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash
-
定位到路径中,内容如下所示:
-
在桌面上新建一个crash_test文件夹
,然后将上面截图中的symbolicatecrash文件,拷贝出来放在新建的crash_test文件夹中; - 在Release生产环境时,打开工程,配置好证书与描述文件,然后archive打包;
打包成功之后Xcode千万不能直接编译运行真机安装app(会造成crash文件与dSYM文件不匹配),app的安装需要从archive中导出的ipa,然后安装ipa文件到真机上
,真机运行app,导致崩溃会生成.crash文件,在Debug环境时,设置好配置直接在真机上运行就可以了; - crash文件的导出 见上面的 使用Xcode从设备中获取Crash日志 或者直接从真机中导出隔空投送给Mac,
将导出的.crash文件也拷贝放到新建的crash_test文件夹中
;
- 在Release生产环境时,将archive包中的dSYM文件拷贝出来放在crash_test文件夹中,在Debug环境时,直接去项目工程的 Products 目录下找到dSYM文件拷贝出来放在crash_test文件夹中,
至此crash_test文件夹中有三个文件分别是:
dSYM文件,
symbolicatecrash文件和
.crash文件`;
- 在进行.crash文件符号化之前必须要检测
.crash文件
和.dSYM文件
是否匹配,只有当两者匹配了,才能正确的符号化,; - UUID 是由一组 32 位数的十六进制数字所构成,每一个可执行程序都有一个 build UUID 唯一标识,由这个可执行程序生成的.crash文件,.dSYM文件和.app文件的UUID都是一致的,都是这个可执行程序的build UUID;
- 可执行程序的工程代码在不断的迭代,所以其UUID在不同版本时都会不同,那么对应生成的.crash文件,.dSYM文件和.app文件的UUID也都不同,为了正确的定位分析crash,必须要保证.crash文件,.dSYM文件和.app文件的UUID相同;
- 查询.crash文件的UUID, cd到.crash文件所在的文件夹,然后输入终端命令:
grep --after-context=2 "Binary Images:" *crash
; - 查询.dSYM文件的UUID cd到.dSYM文件所在的文件夹,然后输入终端命令:
dwarfdump --uuid CrashTest.app.dSYM
- 查询.app文件的UUID cd到.app文件所在的文件夹,然后输入终端命令:
dwarfdump --uuid CrashTest.app/CrashTest
- .crash文件符号解析 cd到新建的crash_test文件夹下执行下面的命令:
./symbolicatecrash crash文件路径 dSYM文件路径 > YYCrashTest.crash
- 可能报下面的错误:
Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 69.
,解决方案如下: - 删除YYCrashTest.crash文件 执行下面的命令:
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
- 然后再次执行上面的命令:
./symbolicatecrash crash文件路径 dSYM文件路径 > YYCrashTest.crash
- 如果crash文件与dSYM文件不匹配即UUID不一致,会报以下错误:
No symbolic information found
,表明两者不匹配; - 如果crash文件与dSYM文件匹配 即UUID一致,那么会生成一个新的YYCrashTest.crash文件,此文件是经过符号化的;
- 拿原来的CrashTest-2021-01-22-103943.crash文件(从真机上导出的crash文件)与经过符号化的新生成的YYCrashTest.crash文件进行一个比对:
方法二: 使用命令行工具 atos
- 同样使用atos也需要crash文件和dSYM,并且两者的UUID要一致;
- 打开crash文件 找到对应的内存地址 如下所示:
-
终端 cd到dSYM所在文件 执行下面的命令:
xcrun atos -o CrashTest.app.dSYM/Contents/Resources/DWARF/CrashTest -arch arm64 -l 0x102110000(内存地址)
-
回车后 再输入slide adress 最终看到的结果是:
- 注意arm64是dSYM文件架构 可能是armv7要根据dSYM文件的实际架构填写,否则会报错如下:
atos cannot load symbols for the file CrashTest for architecture armv7
方法三: GitHub上有个工具,可以辅助我们解析 dSYMTools
- 界面如下所示:
总结
- crash分析定位三种方法:
- symbolicatecrash工具;
- atos工具;
- dSYMTools工具;
- 这三种方法都需要
crash文件和dsym文件且两者需匹配即UUID一致
,其中symbolicatecrash
定位更加精准;