iOS Crash的收集与分析

Crash的收集

  • 使用Xcode从设备中获取Crash日志,新建工程CrashTest;
  • 将你的iPhone手机连接到Mac,然后选择Xcode->Windows->Device and Simulator,然后点击View Device Logs,你会看到手机上会有好多Log,其中Type为Crash的就是崩溃的Log,如下图所示:
Snip20210122_53.png
  • 经过多方测试需要将iPhone从Mac上断开链接,当场发生的崩溃才立即会显示,否则不会立即显示;
Snip20210123_69.png
  • 从真机设备中直接获取Crash日志;
    • 1)打开设置->隐私->分析->分析数据,在其中找到你想要的应用程序的日志,日志将使用以下格式命名:<应用名称> _ <崩溃时间> _ <设备名>;
    • 2)选择所需的日志,复制文本或点击右上角的分享按钮分享出去,并且把分享得到的.ips.synced或者复制文本而来的.txt文件的后缀名改为.crash,因为Xcode不接受没有.crash扩展名的崩溃日志;
Snip20210123_68.png

Crash分析定位

  • 在分析Crash之前我们首先来了解一下 .dSYM文件

  • dSYM 是保存十六进制函数地址映射信息的中转文件,我们调试的 symbols 都会包含在这个文件中,每次编译项目的时候都会生成一个新的 dSYM 文件,我们应该保存每个正式发布版本的 dSYM 文件,以备我们更好的定位问题,一般是在我们 release打包Archives 时保会存对应的版本文件,里面也有对应的.dSYM 和 .app 文件

  • dSYM文件路径为: ~/Library/Developer/Xcode/Archives

Snip20210122_54.png
Snip20210122_56.png
Snip20210122_57.png
  • dSYM 文件在 debug 模式下默认是不生成的,我们需配置 Build Settings -> Debug Information Format下,将 DWARF 修改为 DWARF with dSYM File,再重新编译下就能生成 .dSYM文件了,直接去项目工程的 Products 目录下找就行;
Snip20210121_40.png

方法一:使用symbolicatecrash工具进行crash分析,下面使用的是Debug模式下生成的相关文件进行实例分析,正式release环境会涉及到打包和开发者账号,有点麻烦;

  • symbolicatecrash 是 Xcode 自带的 crash 日志分析工具,在终端中输入命令:find /Applications/Xcode.app -name symbolicatecrash -type f,定位到它如下所示:
Snip20210121_44.png
  • 可以看到返回了五个不同的路径,我使用的路径是:/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/PrivateFrameworks/DVTFoundation.framework/symbolicatecrash

  • 定位到路径中,内容如下所示:

Snip20210121_45.png
  • 在桌面上新建一个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文件夹中
Snip20210122_59.png
  • 在Release生产环境时,将archive包中的dSYM文件拷贝出来放在crash_test文件夹中,在Debug环境时,直接去项目工程的 Products 目录下找到dSYM文件拷贝出来放在crash_test文件夹中,至此crash_test文件夹中有三个文件分别是:dSYM文件symbolicatecrash文件.crash文件`;
Snip20210122_60.png
  • 在进行.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文件,此文件是经过符号化的;
Snip20210122_63.png
  • 拿原来的CrashTest-2021-01-22-103943.crash文件(从真机上导出的crash文件)与经过符号化的新生成的YYCrashTest.crash文件进行一个比对:
Snip20210122_66.png

方法二: 使用命令行工具 atos

  • 同样使用atos也需要crash文件和dSYM,并且两者的UUID要一致;
  • 打开crash文件 找到对应的内存地址 如下所示:
Snip20210123_71.png
  • 终端 cd到dSYM所在文件 执行下面的命令:xcrun atos -o CrashTest.app.dSYM/Contents/Resources/DWARF/CrashTest -arch arm64 -l 0x102110000(内存地址)

  • 回车后 再输入slide adress 最终看到的结果是:

Snip20210123_72.png
  • 注意arm64是dSYM文件架构 可能是armv7要根据dSYM文件的实际架构填写,否则会报错如下:atos cannot load symbols for the file CrashTest for architecture armv7

方法三: GitHub上有个工具,可以辅助我们解析 dSYMTools

  • 界面如下所示:
Snip20210123_73.png

总结

  • crash分析定位三种方法:
    • symbolicatecrash工具;
    • atos工具;
    • dSYMTools工具;
  • 这三种方法都需要crash文件和dsym文件且两者需匹配即UUID一致,其中symbolicatecrash定位更加精准;

你可能感兴趣的:(iOS Crash的收集与分析)