iOS崩潰日誌解析&原理

1. 爲何崩潰日誌須要解析

如圖所示是崩潰日誌線程回溯信息,其中的調用堆棧都是二進制地址,而不是可讀的函數名稱所以須要對崩潰日誌進行解析,解析成能夠理解的函數調用堆棧。 xcode

2.生成dSYM符號文件

crashlog 解析須要調試符號表文件 dSYM(debugging symbols)dSYM 文件其實是從Mach-O 文件抽取調試信息獲得的文件目錄。在編譯工程時, debug 模式會默認選中生成dSYM文件, 該配置可在 Build Setting|Build Option 中更改。 dSYM文件生成比較耗時,若是不須要進行 crashlog 解析,能夠選擇不生成。 markdown

2.1 Debug下能夠在DeriveData的目錄下獲取到dSYM文件

2.2 打包的時候能夠在生成的.achive目錄下找到對應的dSYM文件

2 解析方法

2.1 Xcode 解析

crashlogdSYM 文件和可執行文件放在同一目錄下,而後將 crashlog 拖拽至 Devicelog中,右鍵 Re-symbolicate Log 就能解析。 app

2.2 使用 symbolicatecrash 命令行解析

  • 1.首先找到symbolicatecrash的路徑

一般symbolicatecrash的路徑爲/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash函數

  • 2.命令行解析

首先將崩潰日誌,dSYM以及symbolicatecrash複製出來放到同一個文件夾,而後cd到當前文件夾 ,運行以下命令解析./symbolicatecrash temp.crash testxcConfig.app.dSYM > result.log 工具

  • 3.首次運行須要先運行命令export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"

3.解析原理

dSYM 文件介紹

其中真正保存保存數據的是 DWARF 文件, DWARF(Debuging With Arbitrary Format)是ELF 和 Mach-O 等文件格式中用來存儲和處理調試信息的標準格式。 DWARF 中的數據是高度 壓 縮 的 , 能夠經過dwarfdump命令提取可讀信息,好比提取關鍵的調試信息.debug_info、.debug_line。 註釋: ELFMach-O用於存儲二進制文件、可執行文件、目標代碼和共享庫的格式文件。 ui

解析流程

  1. 計算崩潰地址對應符號表中的地址

以某 crashlog 文件爲例,以下圖所示。是一個Exception類型的異常,從下至上依次爲該線程的調用堆棧,右邊紅色框第一列爲運行時的堆棧地址,第二列爲進程運行時的起始地址(testxcConfig 全部行起始地址都相同),第三列爲運行時的偏移地址。 運行時堆棧地址=運行時起始地址+偏移地址,以第 4 行爲例。0x1022cd990=0x1022c8000 + 0x5990(22928),以上地址均爲 app 發生崩潰時的運行地址,根據虛擬內存偏移地址不變的原理,只要知道符號表 TEXT 段的起始地址,加上偏移量(0x5990)就能獲得崩潰地址對應符號表中的地址, 符號表 TEXT 段的起始地址可經過如下命令得到。 那麼崩潰地址(0x1022cd990)對應符號表中的地址爲:0x100005990 =0x0000000100000000+0x5990 2) 地址重映射 獲取符號表地址後,在 debug-info 章節中查找包含該地址的 DIE(Debug Information Entry)單元就能獲知該符號地址對應的函數名稱(name)、 函數所在的文件路徑(decl file)和函數所在行數(decl line),以下圖所示。 上述步驟解析出了函數相關信息, 下面進一步獲取該地址對應的準確行數, 這須要藉助debug_line章節, debug_line 章節以文件爲單位,準確記錄了文件中的每一行對應的符號表地址, 0x100005990 對應 AppDelegate.m 的第 20 行。 3) 手動解析 crashlog 當有完整的 crashlog 文件和對應的 dSYM 文件時,以上過程能夠由 Xcode 自動完成。但對於用戶反饋的 crash, 須要用戶手動複製本地的 crashlog 文件,而一般 crashlog 文本較長,完整複製其實比較麻煩,那麼此時能夠只複製崩潰線程的 crash 信息,並經過手動解析。手動解析 crash 可使用 dwarfdump、 atos 工具, 命令以下。spa

  • 方法一

  • 方法二

  • 方法三

方法2、三都使用了atos解析,區別是方法三不須要獲取符號表地址, 其後倒數第一個地址爲運行時堆棧地址,倒數第二個地址爲進程起始地址。 手動解析另外一個應用場景是,若開發人員爲了跟進某一偶現問題在日誌中記錄的是運行時的二進制地址,那麼能夠經過對應的 dSYM 文件手動解析出調用函數明文。命令行

4.常見問題

  1. 如何找到crashlog 對應的 dSYM 文件?

打開終端,使用如下命令獲取 dSYM 文件對應的 uuid, 並與crashlog文件Binary Image後面的字符對比,若是字符徹底相同,就說明 dSYM文件與crashlog對應。 另外可使用mdfind命令去尋找指定uuid的dSYM文件,以下,uuid需大寫並轉化成格式,以下圖 mdfind "com_apple_xcode_dsym_uuids == D5644244-F2C4-3C96-BD63-EF0F4DA518FA" 線程

  1. 如何手動生成 dSYM 文件?

若是在編譯以前忘記在 buildsetting 中選中生成 dSYM文件,然而 app 又發生了崩潰,那麼能夠經過 app 的可執行文件再手動生成 dSYM 文件。 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil /Users/ranjingfu/Desktop/testxcConfig/testxcConfig.app/testxcConfig -o out.dSYM 值得注意的是,只有可執行文件爲 debug 模式產物時,才能使用上述方式手動抽取調試符號表文件(dSYM)release模式沒法抽取。 由於debug產物會保存調試信息,而release產物不會, dSYM文件就是從調試信息中抽取出來的。debug

解析後的崩潰日誌實例

相關文章
相關標籤/搜索