iOS 堆棧符號解析最佳實踐

Yol36P 8年前發布 | 8K 次閱讀 Xcode iOS開發 移動開發

本文介紹了如何解析 iOS 的 crash 堆棧,分別使用了  symbolicatecrash  來自動解析整個堆棧,以及使用  atos  來解析單個地址的符號。在 iOS 開發中,解決 crash 問題是比較常見的工作。其中能夠解析出符號當然是定位問題的開始。實際工作中,也有看到很多人其實會卡在解析符號這里,遇到這種情況,可以按照本文中的做法解決。

使用 symbolicatecrash 解析堆棧

symbolicatecrash  是 Xcode 自帶的 crash 符號解析工具,可以自動搜索本地符號表,解析整個 crash 堆棧。

確認 Xcode 環境

首先,需要確認 Xcode 的環境,執行以下代碼,獲取當前 Xcode 的目錄。

/usr/bin/xcode-select -print-path

結果應該是:

/Applications/Xcode.app/Contents/Developer/

如果結果不是上述的路徑,則指定一下路徑:

sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer/

準備好解析堆棧符號的工具:symbolicatecrash

需要先找到 symbolicatecrash 所在的路徑,以  Xcode 7.3  版本為例,執行:

find /Applications/Xcode.app -name symbolicatecrash -type f

將會返回:

/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash

可以做一個快捷方式:

alias symbolicatecrash='/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash'

需要先配置好  DEVELOPER_DIR ,否則會報錯。如下:

export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer/

開始解析

準備好 dSYM 文件和 app 文件,可以存放在任何位置,只要 mac 系統的 spotlight 能夠找到就行。
接著執行

symbolicatecrash xxx.crash

就可以解析符號了。

找不到符號的解決方法

首先,需要確認一下符號表是不是正確的。可以通過以下方式看看符號文件和堆棧是否是對應的 (判斷 uuid 是否相同):

dwarfdump --uuid MyApp.app/MyApp
dwarfdump --uuid xxx.app.dSYM/Contents/Resources/DWARF/Resources/MyApp
grep "0x.*com.wison.xxx .*<" NoSymbolsTestxxx.crash

如果不一樣,那么說明崩潰堆棧和符號文件對應不上,很可能是搞錯版本,或者打包的時候有問題導致符號文件生成不正確。

如果輸出一樣的 uuid,那么就是對應的,此時 

symbolicatecrash

應該可以正常解析符號。

 

如果還是不能正確解析,那么很可能是 mdfind 自動查找的問題。

 

Xcode 找符號文件的時候,是通過 mdfind 來找的,比如:

 

mdfind 'com_apple_xcode_dsym_uuids = *'

該命令會把當前環境下的所有符號文件找出來。
如果你的符號文件不在此列表中,說明 mdfind 找不到我們的符號,

那么就在執行  symbolicatecrash  的時候顯式指定dSYM文件的路徑:

symbolicatecrash xxx.crash xxx.dSYM/Contents/Resources/DWARF/MyApp

如果還是不能解析,試一試把 App 文件也指定:

symbolicatecrash xxx.crash xxx.dSYM/Contents/Resources/DWARF/MyApp MyApp.app/MyApp

使用 atos 解析單個符號

有時候我們需要解析單個地址的符號,比如  lr  寄存器的地址對應的符號,就需要用到  atos
用法如下:

 atos  -arch [armv7 or arm64] -o [BinaryFile or dSYMFile] -l loadAddress address

其中

-arch

指定二進制的架構,比如 armv7,armv7s,arm64 等等。

-o

指定符號文件,可以是 dSYM 文件,也可以是包含了符號表的可執行文件。

-l

是加載地址,由于 Xcode 默認打開 PIE 選項,所以加載地址每次都不一樣,所以需要指定,可以在 crash 堆棧的 Binary Image 那段看到應用的加載地址。

 

最后一個參數是需要解析符號的地址。

 

 

來自:http://mp.weixin.qq.com/s?__biz=MzI1MTA1MzM2Nw==&mid=2649796873&idx=1&sn=277473e13b99b6488609181df7b3b9ff&chksm=f1fcc551c68b4c47f95a6519c0a863c9c6fb29f278903c1b8c5bb036bf26783fb9431c9d6461&scene=0

 

 本文由用戶 Yol36P 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!