大家平时在开发过程中,经常会遇到Crash,那也是在正常不过的事,但是作为一个优秀的iOS开发人员,必将这些用户不良体验降到最低。
- 线下Crash:我们直接可以调试,结合stack信息,不难定位!
- 线上Crash:会直接存储到用户手机,需要连接Xcode导出
- 审核中Crash:审核人员会上传crash文件给你,自己符号化分析
一、dSYM,crash,ips详解和分析
1.什么是dSYM文件?
dSYM 文件是Xcode编译后保存 16 进制函数地址映射信息的中转文件,存储应用程序的调试 symbols。每次编译项目或者打包的时候都会生成一个新的 dSYM 文件,当我们软件release模式打包或上线后,不会像我们在Xcode中那样直观的看到用崩溃的错误,所以对于每一个发布版本我们都很有必要保存对应的 Archives 文件。不管你集没集成类似Buyly的三方,要符号化分析crash日志还是得要用到对应的dSYM文件,如果没有生成dSYM文件,可以看一下TARGETS下Build Settings里面有没有设置,如下图:
dSYM文件获取方式:
Xcode选择Window->Organize->Archives,Show in Finder
所有crash文件的符号化分析都需要dSYM文件
2.什么是Crash文件?(本人手机崩溃分析)
当程序运行Crash的时候,系统会把运行的最后时刻的运行信息记录下来,存储到一个文件中,也就是我们所说的Crash文件。
有六部分组成:
- Process Information(进程信息)
- Basic Information(时间版本)
- Exception(非常重要异常类型)
- Thread Backtrace(Crash调用栈)
- Thread State(线程的状态)
- Binary Images(Crash时加载的所有的库)
crash文件获取方式:
手机插上电脑Xcode选择Window->Devices and Simulators,找到对应的iphone,View Device Logs,右键Export Log。
3.什么是ips文件?(非本人手机崩溃分析)
不方便连接Xcode导出crash文件,针对这种场景需要他们提供给我们用真机导出来的ips文件
ips文件获取方式:
通过真机的设置->隐私->分析->分析数据,找到对应崩溃应用的日志并导出发送给技术
注:ips文件和crash文件不一样,Xcode13,iOS15以前设备ips文件改后缀成crash好像可以,但是之后 Apple 对符号化文件格式进行了 JSON 支持, 所以针对 iOS 15 以上产生的崩溃文件, 写入方式应该是做了调整, 所以在对 iOS 15 以上崩溃文件进行符号化时, ips改后缀会出现符号化失败, 报错 No crash report version in file 的问题,改为直接使用 CrashSymbolicator.py下面会讲到。
二、iOS手动还原符号表
前提条件:
dSYM文件要和crash,ips等文件一一对应,否则符号化会失败,比如你1.0.1产生的crash,ips文件要和1.0.1编译的dSYM文件匹配,注意每次编译都会生成新的dSYM文件
1.利用Xcode:(针对Testflight或者已上线版本)
如果是发布Testflight或者线上版本,有些公司APP更新前会先提交Testflight版本公测一下,然后很多crash的日志可以通过Apple Store Connect里面对应的应用,Testflight下的反馈崩溃里面看到,可以直接Xcode打开,直接到Window->Organize->Crashes下直观看到崩溃错误
2.利用symbolicatecrash符号化分析crash文件
首先在桌面创建一个dsym文件夹,里面再创建一个crash文件夹,将dYSM文件 .crash文件 symbolicatecrash 三个一起拖入crash文件夹
终端以下执行命令,通过命令来得到符号化分析后的crash文件:
1.cd Desktop/dsym/crash
2.export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"
3../symbolicatecrash Test.crash Test.app.dSYM > Result.crash
执行完成,Result.crash是符号化分析后的产物
3.利用CrashSymbolicator.py符号化解析ips文件
获取CrashSymbolicator.py脚本文件路径:
/Applications/Xcode.app/Contents/SharedFrameworks/CoreSymbolicationDT.framework/Versions/A/Resources
首先进入CrashSymbolicator.py脚本所在文件夹下
把 dSYM 文件和 ips 文件放入到该文件夹下
终端命令进入到这个文件夹下执行符号化解析命令
1.cd /Applications/Xcode.app/Contents/SharedFrameworks/CoreSymbolicationDT.framework/Versions/A/Resources
2.sudo python3 CrashSymbolicator.py -d Test.app.dSYM -o Result.ips -p Test.ips
注意: CrashSymbolicator.py不能像复制symbolicatecrash工具一样复制出来,操作稍微和 symbolicatecrash 会有些不同,因为是用 python 写的脚本,所以要使用 python3 来进行调用,否则会报错
4.利用atos命令定位问题(需要具体符号)
xcrun atos -o 项目名.app.dSYM/Contents/Resources/DWARF/项目名 -l 基地址 偏移后的地址
笔者使用的命令参考如下
xcrun atos -o Spark.app.dSYM/Contents/Resources/DWARF/Spark -l 0x0000000102b78000 0x0000000102bea678
5.利用AppleScript脚本快速进行符号化分析
上述在文件夹里面执行命令虽然可以完成,但是比较麻烦,于是做了个脚本执行,下面就看看脚本里面的代码(其实就是封装了几条命令)
Makefile.scpt脚本如下:(用户名需要替换成自己的用户名,路径可以自行根据需要更改)
# 打开终端APP
tell application "Terminal"
# 拼接导出ips结果命令 在此处替换对应的路径
set pythonOrderStart to "python3 CrashSymbolicator.py"
# 三个路径的前面的空格不要忽略了
set dSYMPath to " -d /Users/用户名/Desktop/dsym/ips/Test.app.dSYM"
set outfilePath to " -o /Users/用户名/Desktop/dsym/ips/Result.ips"
set ipsPath to " -p /Users/用户名/Desktop/dsym/ips/Test.ips"
set pythonOrderEnd to ";"
# 第一条命令 进入CrashSymbolicator.py对应的文件夹下执行操作 因为CrashSymbolicator.py关联其它的库也在这个文件夹内
set order1 to "cd /Applications/Xcode.app/Contents/SharedFrameworks/CoreSymbolicationDT.framework/Versions/A/Resources;"
# 第二条命令 分析导出ips结果文件
set order2 to pythonOrderStart & dSYMPath & outfilePath & ipsPath & pythonOrderEnd
# 第三条命令 打开分析的结果文件
set order3 to "open Result.ips"
# 拼接多条命令
set order to order1 & order2 & order3
#多条命令执行用;分割
do script order
end tell
同样首先在之前桌面的dsym文件夹下创建一个 ips 文件夹,dYSM文件和 .ips 文件拖入进去,Makefile脚本准备好,打开执行,Result.ips文件就出来了
总结:
最好的方式还是集成第三方,实时上传分析bug,方便解析。
- 本文作者: Grx
- 本文链接: https://ruixiaoguo.github.io/Grx.github.io/Grx.github.io/2022/11/03/iOS手动还原Crash符号表/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!