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文件 是否匹配,只有當兩者匹配了,才能正確的符號化,\color{red}{匹配的條件就是它們的 UUID是否一致}
  • 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定位更加精準;
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容