一、dSYM符号表分析崩溃
在能够获取到dSYM符号表文件的情况下,分析崩溃详情请移步iOS crash 解析定位,shell脚本查找crash,
或者使用可视化工具分析崩溃 CJCrashTools
二、无dSYM符号表文件崩溃分析
下面来讲一下本文的重点:无dSYM符号表文件下的崩溃分析。
要是很不幸缺失了dSYM文件,但如果能够获取到崩溃日志以及对应的.app文件的情况下,那么我们同样可以对崩溃详情进行分析。
获取crash log崩溃日志
将iOS设备连接到电脑上,打开 Xcode -> Window -> Devices and Simulators -> Devices,找到该台设备,点击View Device Logs,在 This Device的崩溃日志列表中中找到对应app的崩溃日志即可;也可以点击右键,Export Log将日志导出(后缀为 .crash 的 log 文件)。
如果你的应用已经上架App Store,那么开发者可以通过iTunes Connect(Manage Your Applications - View Details - Crash Reports)获取用户的crash log。不过这并不是100%有效的,而且大多数开发者并不依赖于此,因为这需要用户设备同意上传相关信息,详情可参见iOS: Providing Apple with diagnostics and usage information摘要。
第三方crash收集系统,甚至还带了符号化crash日志的功能。比较常用的有Crashlytics,Flurry等。
获取.app文件
如果是Xcode debug模式下崩溃获取.app文件:打开Xcode,找到项目工程Products文件夹下的编译产物,右键Show in Finder,即可找到 CJTest.app (本文示例.app名为CJTest.app,后同)。
如果是导出ipa安装之后的崩溃:修改.ipa后缀名为.zip,解压之后进入Payload文件夹,同样可以找到 CJTest.app 文件。注意如果是从App Store渠道获取的ipa文件,那么必须先经过砸壳处理!
.app文件瘦身(非必要步骤)
首先判断崩溃日志是来自arm64还是其他机器,以及得到的.app是否集成多架构。
查看.app架构,终端执行:
lipo -info CJTest.app/CJTest
如果结果提示本身就只包含arm64,那么可以跳过本步骤了。
否则执行以下指令进行瘦身:
lipo -thin arm64 CJTest.app/CJTest -output CJTest_arm64
符号恢复工具restore-symbol
下载后修改权限
chmod a+x restore-symbol
恢复符号
./restore-symbol CJTest -o CJTest_symbol
# 如果是.app有经过瘦身,则执行
./restore-symbol CJTest_arm64 -o CJTest_arm64_symbol
最终得到恢复了符号表的二时制文件 CJTest_symbol。
另外如果运行restore-symbol指令的过程中系统提示"无法打开restore-symbol,因为无法验证开发者“
,可通过以下步骤解决:打开系统偏好设置选项 — 点击打开安全性与隐私选项 — 点击上方的通用选项 — 点击选中下方的任何来源选项即可。
Bug位置定位
最后执行指令,定位到最终的崩溃代码。
atos -arch arm64 -o CJTest_arm64_symbol -l 0x1045e8000 0x0000000105b8b738 0x0000000105b8b724
atos指令说明:
# atos -arch ”CPU架构“ -o “二进制文件” -l “起始地址” “一系列内存地址。。。”
-l 后面跟的是模块的起始地址,然后后面可以罗列很多内存地址,执行命令后会依次解析出,所罗列的内存地址对应的所有函数。
对应的崩溃日志快照说明:
Binary Images表示的是app崩溃时程序加载的所有库的快照,找到CJTest所在行,开始的地址区间0x1045e8000 - 0x10658ffff代表的是程序崩溃时的内存区间,其中起始地址为0x1045e8000。其后是对应的app二进制文件名,架构类型arm64,再后面的尖括号里对应的是uuid说明。
查看.app文件uuid指令:
dwarfdump —uuid xxx.app/xxx