91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS崩潰堆棧信息的符號化怎么用

發布時間:2021-12-24 15:59:35 來源:億速云 閱讀:131 作者:小新 欄目:移動開發

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

對iOS崩潰符號化的使用和技巧:

一.場景

       當我們收集iOS的崩潰信息時,獲取到的崩潰堆棧一般是如下的形式,全是十六進制的內存地址形式:

        iOS崩潰堆棧信息的符號化怎么用

       這樣的格式我們很難看出實際含義,無法定位問題代碼,只有將它們轉化為可讀的形式才有意義:

        iOS崩潰堆棧信息的符號化怎么用

       如上所示,我們一眼就能看明白,這次崩潰發生在ViewController.m文件的68行,對應的方法是rangeException。那么這樣的符號化又是如何實現的呢?

       我們知道,開發者在使用Xcode開發調試App時,一旦遇到崩潰問題,開發者可以直接使用Xcode的調試器定位分析崩潰堆棧。但如果App發布上線,用戶的手機發生了崩潰,我們就只能通過分析系統記錄的崩潰日志來定位問題,在這份崩潰日志文件中,會指出App出錯的函數內存地址,關鍵的問題,崩潰日志中只有地址,類似 0x2312e92f這種,這看起來豈不是相當頭疼,那怎么辦呢?

       幸好有dSYM文件的存在,它是幫助苦逼的碼農有效定位bug問題的重要途徑。崩潰堆棧里的函數地址可以借助dSYM文件來找到具體的文件名、函數名和行號信息的。實際上,在使用Xcode的Organizer查看崩潰日志時,就是根據本地存儲的.dSYM文件進行了符號化的操作。

二.Xcode符號化工具

       Xcode本身也提供了幾個工具來幫助開發者執行函數地址符號化的操作

       1、symbolicatecrash

       symbolicatecrash是一個將堆棧地址符號化的腳本,輸入參數是蘋果官方格式的崩潰日志及本地的.dSYM文件,
       執行方式如下:
       Symbolicatecrash + 崩潰日志 + APP對應的.dSYM文件 + > + 輸出到的文件,
       但使用symbolicatecrash工具有很大的限制
       (1)只能分析官方格式的崩潰日志,需要從具體的設備中導出,獲取和操作都不是很方便
       (2)符號化的結果也是沒有具體的行號信息的,也經常會出現符號化失敗的情況。
       實際上, Xcode的Organizer內置了symbolicatecrash工具,所以開發者才可以直接看到符號化的崩潰堆棧日志。

       2、atos

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

三.堆棧符號化原理

       那么,如果我們自己來符號化堆棧,又該怎么實現呢?這里需要處理兩種符號,包括用戶符號和系統符號。

       1、用戶堆棧的符號化

       符號化的依據來自dSYM文件, dSYM文件也是Mach-o格式,我們按照Mach-o格式一步一步解析即可。

       iOS崩潰堆棧信息的符號化怎么用

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

       iOS崩潰堆棧信息的符號化怎么用

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

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

        LC_SYMTAB信息

        iOS崩潰堆棧信息的符號化怎么用

         定位地址: 偏移4096 + 64(0x1040),得到函數符號信息模塊”Symbols”,把函數符號解析出來,比如第一個函數: “-[DKDLicenseAgreeementModel isAuthorize]”對應的內存地址:模塊地址+43856

         iOS崩潰堆棧信息的符號化怎么用
 
       “__debug_line”模塊

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

       iOS崩潰堆棧信息的符號化怎么用

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

       iOS崩潰堆棧信息的符號化怎么用

       解析出來的結果如下:

       iOS崩潰堆棧信息的符號化怎么用

       第一列是起始內存地址,第二列是結束內存地址,第三列是對應的函數名、文件名、行號信息,這樣我們捕獲到任意的崩潰信息后,都可以很輕松的還原了。
 
       上面解析出來的Object-C符號倒沒什么問題,但如果是C++或者Swift的符號就還需要特殊處理

       Swift符號:

       Swift函數會進行命名重整(name mangling),所以從dSYM中解析出來的原始符號是不太直觀的

          iOS崩潰堆棧信息的符號化怎么用

        我們使用”swift-demangle”來還原:swift-demangle –simplified originName,結果如下:

          iOS崩潰堆棧信息的符號化怎么用
 
        C++符號:

        C++函數也會進行命名重整(name mangling),所以從dSYM中解析出來的原始符號如下:

          iOS崩潰堆棧信息的符號化怎么用

        我們使用”c++filt ”來還原: c++filt originName,結果如下:

          iOS崩潰堆棧信息的符號化怎么用
 
        2、系統堆棧的符號化

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

        解析后:
         iOS崩潰堆棧信息的符號化怎么用

        Apple沒有提供系統庫符號表的下載功能,我們可以通過真機來獲取
       當把開發機連到MAC時,會首先把該機型的符號拷貝到電腦上。

        iOS崩潰堆棧信息的符號化怎么用

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

        iOS崩潰堆棧信息的符號化怎么用

       但這樣有個缺陷,那就是你真機的iOS版本不會足夠多,包含所有版本,所以系統符號會有缺失,另一個辦法就是下載各種iOS固件,從固件中去解析。

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

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

ios
AI

郁南县| 松滋市| 罗甸县| 融水| 常州市| 根河市| 伊吾县| 惠来县| 翼城县| 马尔康县| 平度市| 筠连县| 邳州市| 镇远县| 洛隆县| 桂东县| 平安县| 额敏县| 五原县| 和顺县| 名山县| 刚察县| 白水县| 武川县| 桦甸市| 柏乡县| 四川省| 庆城县| 义马市| 平乡县| 阿坝| 将乐县| 措勤县| 龙海市| 海原县| 宜阳县| 西吉县| 永吉县| 内乡县| 兴文县| 当雄县|