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擴展名的崩潰日志;
- 1)打開
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
定位更加精準;