溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

iOS崩潰堆棧信息的符號(hào)化怎么用

發(fā)布時(shí)間:2021-12-24 15:59:35 來(lái)源:億速云 閱讀:131 作者:小新 欄目:移動(dòng)開(kāi)發(fā)

小編給大家分享一下iOS崩潰堆棧信息的符號(hào)化怎么用,希望大家閱讀完這篇文章之后都有所收獲,下面讓我們一起去探討吧!

對(duì)iOS崩潰符號(hào)化的使用和技巧:

一.場(chǎng)景

       當(dāng)我們收集iOS的崩潰信息時(shí),獲取到的崩潰堆棧一般是如下的形式,全是十六進(jìn)制的內(nèi)存地址形式:

        iOS崩潰堆棧信息的符號(hào)化怎么用

       這樣的格式我們很難看出實(shí)際含義,無(wú)法定位問(wèn)題代碼,只有將它們轉(zhuǎn)化為可讀的形式才有意義:

        iOS崩潰堆棧信息的符號(hào)化怎么用

       如上所示,我們一眼就能看明白,這次崩潰發(fā)生在ViewController.m文件的68行,對(duì)應(yīng)的方法是rangeException。那么這樣的符號(hào)化又是如何實(shí)現(xiàn)的呢?

       我們知道,開(kāi)發(fā)者在使用Xcode開(kāi)發(fā)調(diào)試App時(shí),一旦遇到崩潰問(wèn)題,開(kāi)發(fā)者可以直接使用Xcode的調(diào)試器定位分析崩潰堆棧。但如果App發(fā)布上線,用戶的手機(jī)發(fā)生了崩潰,我們就只能通過(guò)分析系統(tǒng)記錄的崩潰日志來(lái)定位問(wèn)題,在這份崩潰日志文件中,會(huì)指出App出錯(cuò)的函數(shù)內(nèi)存地址,關(guān)鍵的問(wèn)題,崩潰日志中只有地址,類似 0x2312e92f這種,這看起來(lái)豈不是相當(dāng)頭疼,那怎么辦呢?

       幸好有dSYM文件的存在,它是幫助苦逼的碼農(nóng)有效定位bug問(wèn)題的重要途徑。崩潰堆棧里的函數(shù)地址可以借助dSYM文件來(lái)找到具體的文件名、函數(shù)名和行號(hào)信息的。實(shí)際上,在使用Xcode的Organizer查看崩潰日志時(shí),就是根據(jù)本地存儲(chǔ)的.dSYM文件進(jìn)行了符號(hào)化的操作。

二.Xcode符號(hào)化工具

       Xcode本身也提供了幾個(gè)工具來(lái)幫助開(kāi)發(fā)者執(zhí)行函數(shù)地址符號(hào)化的操作

       1、symbolicatecrash

       symbolicatecrash是一個(gè)將堆棧地址符號(hào)化的腳本,輸入?yún)?shù)是蘋(píng)果官方格式的崩潰日志及本地的.dSYM文件,
       執(zhí)行方式如下:
       Symbolicatecrash + 崩潰日志 + APP對(duì)應(yīng)的.dSYM文件 + > + 輸出到的文件,
       但使用symbolicatecrash工具有很大的限制
       (1)只能分析官方格式的崩潰日志,需要從具體的設(shè)備中導(dǎo)出,獲取和操作都不是很方便
       (2)符號(hào)化的結(jié)果也是沒(méi)有具體的行號(hào)信息的,也經(jīng)常會(huì)出現(xiàn)符號(hào)化失敗的情況。
       實(shí)際上, Xcode的Organizer內(nèi)置了symbolicatecrash工具,所以開(kāi)發(fā)者才可以直接看到符號(hào)化的崩潰堆棧日志。

       2、atos

       更普遍的情況是,開(kāi)發(fā)者能獲取到錯(cuò)誤堆棧信息,而使用atos工具就是把地址對(duì)應(yīng)的具體符號(hào)信息找到。它是一個(gè)可以把地址轉(zhuǎn)換為函數(shù)名(包括行號(hào))的工具,
       執(zhí)行方式如下:
       atos -o executable -arch architecture -l loadAddress address
       說(shuō)明:
       loadAddress 表示函數(shù)的動(dòng)態(tài)加載地址,對(duì)應(yīng)崩潰地址堆棧中 + 號(hào)前面的地址,即0x00048000
address 表示運(yùn)行時(shí)地址、對(duì)應(yīng)崩潰地址堆棧中第一個(gè)地址,即0x0004fbed  ,實(shí)際上,崩潰地址堆棧中+號(hào)前后的地址相加即是運(yùn)行時(shí)地址,即0x00048000+ 31720= 0x0004fbed
       執(zhí)行命令查詢地址的符號(hào),可以看到如下結(jié)果:
       -[ViewController rangeException:] (in xx)(ViewController.m:68)

三.堆棧符號(hào)化原理

       那么,如果我們自己來(lái)符號(hào)化堆棧,又該怎么實(shí)現(xiàn)呢?這里需要處理兩種符號(hào),包括用戶符號(hào)和系統(tǒng)符號(hào)。

       1、用戶堆棧的符號(hào)化

       符號(hào)化的依據(jù)來(lái)自dSYM文件, dSYM文件也是Mach-o格式,我們按照Mach-o格式一步一步解析即可。

       iOS崩潰堆棧信息的符號(hào)化怎么用

       從圖上我們可以大概的看出Mach-O可以分為3個(gè)部分
       (1)Header
       (2)Segment
       (3)section
       如圖所示,header后面是segment,然后再跟著section,而一個(gè)segment是可以包含多個(gè)section的。
       我們把dSYM文件放入可視化工具:

       iOS崩潰堆棧信息的符號(hào)化怎么用

       該dSYM文件包含armv7和arm64兩種架構(gòu)的符號(hào)表,我們只看armv7(arm64同理),它偏移64,直接定位到64(0x00000040),這里就是上面的Mach Header信息

       iOS崩潰堆棧信息的符號(hào)化怎么用
 
        跟我們符號(hào)表有關(guān)的兩個(gè)地方,一是”LC_SYMTAB”, 二是“LC_SEGMENT(__DWARF)” -> “Section Header(__debug_line)”。

        LC_SYMTAB信息

        iOS崩潰堆棧信息的符號(hào)化怎么用

         定位地址: 偏移4096 + 64(0x1040),得到函數(shù)符號(hào)信息模塊”Symbols”,把函數(shù)符號(hào)解析出來(lái),比如第一個(gè)函數(shù): “-[DKDLicenseAgreeementModel isAuthorize]”對(duì)應(yīng)的內(nèi)存地址:模塊地址+43856

         iOS崩潰堆棧信息的符號(hào)化怎么用
 
       “__debug_line”模塊

      這個(gè)模塊里包含有代碼文件行號(hào)信息,根據(jù)dwarf格式去一個(gè)一個(gè)解析
      首先定位到SEGMENT:LC_SEGMENT(__DWARF),再定位到Section:__debug_line

       iOS崩潰堆棧信息的符號(hào)化怎么用

       它的偏移值:4248608,  4248608+ 64 = 0x40D460,定位到“Section(__DWARF,__debug_line)”
       這里面就是具體的行號(hào)信息,根據(jù)dwarf格式去解析

       iOS崩潰堆棧信息的符號(hào)化怎么用

       解析出來(lái)的結(jié)果如下:

       iOS崩潰堆棧信息的符號(hào)化怎么用

       第一列是起始內(nèi)存地址,第二列是結(jié)束內(nèi)存地址,第三列是對(duì)應(yīng)的函數(shù)名、文件名、行號(hào)信息,這樣我們捕獲到任意的崩潰信息后,都可以很輕松的還原了。
 
       上面解析出來(lái)的Object-C符號(hào)倒沒(méi)什么問(wèn)題,但如果是C++或者Swift的符號(hào)就還需要特殊處理

       Swift符號(hào):

       Swift函數(shù)會(huì)進(jìn)行命名重整(name mangling),所以從dSYM中解析出來(lái)的原始符號(hào)是不太直觀的

          iOS崩潰堆棧信息的符號(hào)化怎么用

        我們使用”swift-demangle”來(lái)還原:swift-demangle –simplified originName,結(jié)果如下:

          iOS崩潰堆棧信息的符號(hào)化怎么用
 
        C++符號(hào):

        C++函數(shù)也會(huì)進(jìn)行命名重整(name mangling),所以從dSYM中解析出來(lái)的原始符號(hào)如下:

          iOS崩潰堆棧信息的符號(hào)化怎么用

        我們使用”c++filt ”來(lái)還原: c++filt originName,結(jié)果如下:

          iOS崩潰堆棧信息的符號(hào)化怎么用
 
        2、系統(tǒng)堆棧的符號(hào)化

        未解析形式:
         iOS崩潰堆棧信息的符號(hào)化怎么用

        解析后:
         iOS崩潰堆棧信息的符號(hào)化怎么用

        Apple沒(méi)有提供系統(tǒng)庫(kù)符號(hào)表的下載功能,我們可以通過(guò)真機(jī)來(lái)獲取
       當(dāng)把開(kāi)發(fā)機(jī)連到MAC時(shí),會(huì)首先把該機(jī)型的符號(hào)拷貝到電腦上。

        iOS崩潰堆棧信息的符號(hào)化怎么用

        “Processing symbol files”做的事情就是把系統(tǒng)符號(hào)拷貝到電腦,拷貝地址:
        ~/Library/Developer/Xcode/iOS DeviceSupport

        iOS崩潰堆棧信息的符號(hào)化怎么用

       但這樣有個(gè)缺陷,那就是你真機(jī)的iOS版本不會(huì)足夠多,包含所有版本,所以系統(tǒng)符號(hào)會(huì)有缺失,另一個(gè)辦法就是下載各種iOS固件,從固件中去解析。

看完了這篇文章,相信你對(duì)“iOS崩潰堆棧信息的符號(hào)化怎么用”有了一定的了解,如果想了解更多相關(guān)知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

ios
AI