iOS崩潰解析&原理介紹

1. 為什么崩潰日志需要解析

如圖所示是崩潰日志線(xiàn)程回溯信息,其中的調(diào)用堆棧都是二進(jìn)制地址,而不是可讀的函數(shù)名稱(chēng)因此需要對(duì)崩潰日志進(jìn)行解析,解析成可以理解的函數(shù)調(diào)用堆棧。


image

2.生成dSYM符號(hào)文件

crashlog 解析需要調(diào)試符號(hào)表文件 dSYM(debugging symbols), dSYM 文件實(shí)際上是從Mach-O 文件抽取調(diào)試信息得到的文件目錄。在編譯工程時(shí), debug 模式會(huì)默認(rèn)選中生成dSYM文件, 該配置可在 Build Setting|Build Option 中更改。 dSYM文件生成比較耗時(shí),如果不需要進(jìn)行 crashlog 解析,可以選擇不生成。

image

2.1 Debug下可以在DeriveData的目錄下獲取到dSYM文件

image

2.2 打包的時(shí)候可以在生成的.achive目錄下找到對(duì)應(yīng)的dSYM文件

image

2 解析方法

2.1 Xcode 解析

crashlogdSYM 文件和可執(zhí)行文件放在同一目錄下,然后將 crashlog 拖拽至 Devicelog中,右鍵 Re-symbolicate Log 就能解析。

image

image

2.2 使用 symbolicatecrash 命令行解析

  • 1.首先找到symbolicatecrash的路徑
    image

    通常symbolicatecrash的路徑為/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
  • 2.命令行解析
    首先將崩潰日志,dSYM以及symbolicatecrash復(fù)制出來(lái)放到同一個(gè)文件夾,然后cd到當(dāng)前文件夾
    ,運(yùn)行如下命令解析./symbolicatecrash temp.crash testxcConfig.app.dSYM > result.log
    image
  • 3.首次運(yùn)行需要先運(yùn)行命令export DEVELOPER_DIR="/Applications/XCode.app/Contents/Developer"

3.解析原理

dSYM 文件介紹

image

其中真正保存保存數(shù)據(jù)的是 DWARF 文件, DWARF(Debuging With Arbitrary Format)是ELF 和 Mach-O 等文件格式中用來(lái)存儲(chǔ)和處理調(diào)試信息的標(biāo)準(zhǔn)格式。 DWARF 中的數(shù)據(jù)是高度 壓 縮 的 , 可以通過(guò)dwarfdump命令提取可讀信息,比如提取關(guān)鍵的調(diào)試信息.debug_info、.debug_line。
注釋?zhuān)?ELF、Mach-O用于存儲(chǔ)二進(jìn)制文件、可執(zhí)行文件、目標(biāo)代碼和共享庫(kù)的格式文件。
image

解析流程

  1. 計(jì)算崩潰地址對(duì)應(yīng)符號(hào)表中的地址
    以某 crashlog 文件為例,如下圖所示。是一個(gè)Exception類(lèi)型的異常,從下至上依次為該線(xiàn)程的調(diào)用堆棧,右邊紅色框第一列為運(yùn)行時(shí)的堆棧地址,第二列為進(jìn)程運(yùn)行時(shí)的起始地址(testxcConfig 所有行起始地址都相同),第三列為運(yùn)行時(shí)的偏移地址。
    image

    運(yùn)行時(shí)堆棧地址=運(yùn)行時(shí)起始地址+偏移地址,以第 4 行為例。0x1022cd990=0x1022c8000 + 0x5990(22928),以上地址均為 app 發(fā)生崩潰時(shí)的運(yùn)行地址,根據(jù)虛擬內(nèi)存偏移地址不變的原理,只要知道符號(hào)表 TEXT 段的起始地址,加上偏移量(0x5990)就能得到崩潰地址對(duì)應(yīng)符號(hào)表中的地址, 符號(hào)表 TEXT 段的起始地址可通過(guò)以下命令獲得。
    image

    那么崩潰地址(0x1022cd990)對(duì)應(yīng)符號(hào)表中的地址為:0x100005990 =0x0000000100000000+0x5990
  2. 地址重映射
    獲取符號(hào)表地址后,在 debug-info 章節(jié)中查找包含該地址的 DIE(Debug Information Entry)單元就能獲知該符號(hào)地址對(duì)應(yīng)的函數(shù)名稱(chēng)(name)、 函數(shù)所在的文件路徑(decl file)和函數(shù)所在行數(shù)(decl line),如下圖所示。
    image

    上述步驟解析出了函數(shù)相關(guān)信息, 下面進(jìn)一步獲取該地址對(duì)應(yīng)的準(zhǔn)確行數(shù), 這需要借助debug_line章節(jié), debug_line 章節(jié)以文件為單位,準(zhǔn)確記錄了文件中的每一行對(duì)應(yīng)的符號(hào)表地址, 0x100005990 對(duì)應(yīng) AppDelegate.m 的第 20 行。
    image
  3. 手動(dòng)解析 crashlog
    當(dāng)有完整的 crashlog 文件和對(duì)應(yīng)的 dSYM 文件時(shí),以上過(guò)程可以由 Xcode 自動(dòng)完成。但對(duì)于用戶(hù)反饋的 crash, 需要用戶(hù)手動(dòng)復(fù)制本地的crashlog 文件,而通常crashlog 文本較長(zhǎng),完整復(fù)制其實(shí)比較麻煩,那么此時(shí)可以只復(fù)制崩潰線(xiàn)程的 crash 信息,并通過(guò)手動(dòng)解析。手動(dòng)解析 crash 可以使用 dwarfdump、 atos 工具, 命令如下。
  • 方法一


    image
  • 方法二


    image
  • 方法三
    image

    方法二、三都使用了atos解析,區(qū)別是方法三不需要獲取符號(hào)表地址, 其后倒數(shù)第一個(gè)地址為運(yùn)行時(shí)堆棧地址,倒數(shù)第二個(gè)地址為進(jìn)程起始地址。
    手動(dòng)解析另一個(gè)應(yīng)用場(chǎng)景是,若開(kāi)發(fā)人員為了跟進(jìn)某一偶現(xiàn)問(wèn)題在日志中記錄的是運(yùn)行時(shí)的二進(jìn)制地址,那么可以通過(guò)對(duì)應(yīng)的 dSYM 文件手動(dòng)解析出調(diào)用函數(shù)明文。

4.常見(jiàn)問(wèn)題

  1. 如何找到crashlog 對(duì)應(yīng)的 dSYM 文件?
    打開(kāi)終端,使用以下命令獲取 dSYM 文件對(duì)應(yīng)的 uuid, 并與crashlog文件Binary Image后面的字符對(duì)比,如果字符完全相同,就說(shuō)明 dSYM文件與crashlog對(duì)應(yīng)。

    image

    image

    另外可以使用mdfind命令去尋找指定uuid的dSYM文件,如下,uuid需大寫(xiě)并轉(zhuǎn)化成格式,如下圖
    mdfind "com_apple_xcode_dsym_uuids == D5644244-F2C4-3C96-BD63-EF0F4DA518FA"
    image

  2. 如何手動(dòng)生成 dSYM 文件?
    如果在編譯之前忘記在 buildsetting 中選中生成 dSYM文件,然而 app 又發(fā)生了崩潰,那么可以通過(guò) app 的可執(zhí)行文件再手動(dòng)生成 dSYM 文件。
    /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil /Users/ranjingfu/Desktop/testxcConfig/testxcConfig.app/testxcConfig -o out.dSYM

    image

    值得注意的是,只有可執(zhí)行文件為 debug 模式產(chǎn)物時(shí),才能使用上述方式手動(dòng)抽取調(diào)試符號(hào)表文件(dSYM), release模式無(wú)法抽取。 因?yàn)?code>debug產(chǎn)物會(huì)保存調(diào)試信息,而release產(chǎn)物不會(huì), dSYM文件就是從調(diào)試信息中抽取出來(lái)的。

解析后的崩潰日志實(shí)例

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 前言 iOS崩潰是讓iOS開(kāi)發(fā)人員比較頭痛的事情,app崩潰了,說(shuō)明代碼寫(xiě)的有問(wèn)題,這時(shí)如何快速定位到崩潰的地方很...
    lp_lp閱讀 5,086評(píng)論 0 16
  • iOS Crash 流程化:一般的 Crash 日志解析方法TL;DR一、手動(dòng)解析 Crash 日志1、需要的相關(guān)...
    Vinc閱讀 5,913評(píng)論 0 7
  • iOS Crash 流程化:一般的 Crash 日志解析方法TL;DR一、手動(dòng)解析 Crash 日志1、需要的相關(guān)...
    iOS亮子閱讀 1,004評(píng)論 0 3
  • 最近一段時(shí)間,在iOS開(kāi)發(fā)調(diào)試過(guò)程中以及上線(xiàn)之后,程序經(jīng)常會(huì)出現(xiàn)崩潰的問(wèn)題。簡(jiǎn)單的崩潰還好說(shuō),復(fù)雜的崩潰就需要我們...
    f9dd77add98e閱讀 20,290評(píng)論 12 74
  • 推薦指數(shù): 6.0 書(shū)籍主旨關(guān)鍵詞:特權(quán)、焦點(diǎn)、注意力、語(yǔ)言聯(lián)想、情景聯(lián)想 觀點(diǎn): 1.統(tǒng)計(jì)學(xué)現(xiàn)在叫數(shù)據(jù)分析,社會(huì)...
    Jenaral閱讀 6,023評(píng)論 0 5

友情鏈接更多精彩內(nèi)容