最近看到一篇關(guān)于符號化iOS崩潰報告的文章挺好胜榔,決定翻一下家乘,下方鏈接是原文地址:
https://possiblemobile.com/2015/03/symbolicating-your-ios-crash-reports/
開始
你已經(jīng)遞交你的應(yīng)用程序的崩潰報告,但是棧回溯包含了難懂的內(nèi)存地址寻咒。開發(fā)者該怎么辦?簡而言之灰粮,你需要調(diào)試符號來應(yīng)用于堆棧追蹤仔涩,從而使它人類可讀,這個過程我們稱作符號化粘舟。
在開始之前熔脂,我們依照使用Crasher,它提供了一個簡單崩潰報告柑肴,讓你破譯霞揉。
你應(yīng)該有.crash文件。如果沒有晰骑,你可以從iTunes Connect中攫取适秩,或者直接通過Xcode從連接的設(shè)備中攫取(Windows > Devices),或在一個連接的設(shè)備(Settings > Privacy > Diagnostics & Usage),或使用 PLCrashReporter 框架硕舆。你可能已經(jīng)使用了第三方的崩潰報告服務(wù)秽荞,在你配置正確后,它將符號化你的崩潰抚官。
根據(jù)你的應(yīng)用創(chuàng)建是如何配置的扬跋,你需要一個或者全部下面的東西:
0.導致崩潰的應(yīng)用程序構(gòu)建的.app文件。這個包包含了應(yīng)用二進制文件凌节,以及可能包含測試符號钦听。(如果你有一個.ipa文件洒试,你可以把它當做一個.zip文件,通過解壓這個文件把它提取出來)
1.導致崩潰的應(yīng)用程序構(gòu)建的.dSYM文件朴上。這是你的應(yīng)用程序的副產(chǎn)品垒棋,包含調(diào)試符號化。
你需要哪一個? 在 Xcode中痪宰,查找Build Setting里的 "Strip Debug Symbols During Copy"(COPY_PHASE_STRIP)叼架。當允許時,調(diào)試符號將會從你的.app省去衣撬,把它放到了.dSYM文件碉碉。否則你的.app包含這些符號。(默認情況下淮韭, 由于某些不清楚的原因垢粮,調(diào)試符號從釋放的創(chuàng)建中剝離,你可能不應(yīng)該改變這個發(fā)布配置)
但是等等靠粪,什么是調(diào)試符號蜡吧?
為了讓調(diào)試符號變成人類可讀的即程序員給方法命名的名稱,編譯器通過使用它自己的符號來減少這些命名的調(diào)試符號占键,從而使代碼模糊昔善。即使兩次相同代碼創(chuàng)建,你也不能依賴這些符號畔乙。
檢查崩潰
如果通過Xcode的Organizer從設(shè)備中提交崩潰報告君仆,你的崩潰報告可能將會對UIKit和其他iOS框架自動符號化。如果Xcode知道你的創(chuàng)建牲距,他將自動符號化你的崩潰返咱。
如果不是這種情況,你需要自己符號化牍鞠。
使用"Symbolicatecrash"工具來符號化
幸運的是咖摹,蘋果提供給了我們腳本來檢索調(diào)試符號化,將他們應(yīng)用于崩潰報告难述。
對 Xcode 6萤晴,你可以在下面目錄里找到這個工具:
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/Current/Resources/symbolicatecrash
或者如果你使用的是Xcode 5 從下方路徑獲得:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/Current/Resources/symbolicatecrash
為了使用這個工具,你需要用安裝Xcode恰當路徑導出 DEVELOPER_DIR
環(huán)境變量:
export DEVELOPER_DIR="/Applications/Xcode.app/Contents/Developer"
把你的.crash文件.app文件和.dSYM文件放在同一個目錄下然后運行:
symbolicatecrash -v ScaryCrash.crash > Symbolicated.crash
你可能需要顯示應(yīng)用應(yīng)用程序二進制:
symbolicatecrash -v ScaryCrash.crash ./Crasher.app/Crasher > Symbolicated.crash
如果你使用在Crasher例子中發(fā)現(xiàn)的便利腳本胁后,需要冗長的標記:
sh symbolicate6.sh ScaryCrash.crash ./Crasher.app/Crasher > Symbolicated.crash
如果你使用在Crasher例子中發(fā)現(xiàn)的便利腳本店读,需要冗長的標記:
sh symbolicate6.sh ScaryCrash.crash ./Crasher.app/Crasher > Symbolicated.crash
驗證符號化
如果符號化不能工作,仔細檢查你攫取的.dSYM或者.app文件是否正確攀芯。你可以通過交叉引用崩潰的報告中的UUID和應(yīng)用程序二進制中的UUID:
dwarfdump –uuid Crasher.app/Crasher
結(jié)果:
在dSYM文件中:
dwarfdump –uuid Crasher.app.dSYM/Contents/Resources/DWARF/Crasher
結(jié)果:
和你的崩潰報告中的UUID進行比較:
從symbolicatecrash工具冗長的日志里屯断,同樣列出它找出的UUID。
排查 "Symbolicatecrash" 工具
如果你還是困惑,請認真檢查symbolication日志裹纳。symbolication工具嘗試找出你應(yīng)用中與UUID相匹配的相應(yīng)文件以及每個動態(tài)框架,尋找著你的應(yīng)用程序名稱或者UUID 并看出是否匹配紧武。
如果Spotlight不能找到你的.dSYM文件剃氧,你可能碰到這樣一個日志樣例:
或者有一個無效的.dSYM:
或者有任何其他無效的輸入:
在Xcode 6 版本中的symbolicatecrash工具嘗試解決一些再Xcode 5 版本中面臨的Spotlight問題。如果你遇到問題阻星,他可能是Spotlight中一個文件的索引問題朋鞍,嘗試:
mdimport -g /Applications/Xcode.app/Contents/Library/Spotlight/uuid.mdimporter .
使用命令行工具鏈
我們可以深入 和使用開發(fā)者命令行工具鏈來一行行的符號化棧追蹤的內(nèi)存地址。如果你在過去使用這個方法中遇到問題妥箕,那可能是因為在最近幾年.crash文件根式改變了滥酥。
首先,讓我們再看看我們崩潰報考中的棧追蹤:
最左邊的十六進制值畦幢,0x000aeef6,是棧地址坎吻。第二個十六進制值,0xa8000,是應(yīng)用程序的加載地址宇葱。以加號為開始的數(shù)字瘦真,28406,是棧地址和加載地址的差值黍瞧。 0x00aeef6 = 0xa8000 + 0x6EF6
诸尽。你將會發(fā)現(xiàn)在我們的崩潰報告底部的“Binary Images”,它是動態(tài)庫內(nèi)存地址范圍列表印颤。我們的二進制文件的起始地址在堆棧跟蹤加載地址相匹配您机。
下一步,為了更好的測量年局,我們將驗證可執(zhí)行文件包含蹦潰的架構(gòu)际看,不論使用file或者lipo -info命令:
file Crasher.app/Crasher
結(jié)果:
現(xiàn)在我們?nèi)蔽溲b。我們經(jīng)查實atos命令來將我們的地址轉(zhuǎn)換成調(diào)試符號矢否。注意我們?nèi)绾翁峁┘虞d地址仿村,它在我們指定崩潰的架構(gòu)的棧地址后面:
atos -arch armv7 -o Crasher.app/Crasher -l 0xa8000 0x000aeef6
結(jié)果:
就是這樣。如果你有興趣繼續(xù)鉆研兴喂,研讀Mach-O對象文件格式以及Mach-O命令行實用工具蔼囊,也就是otool和lipo命令。
更多閱讀
更多全面的文檔衣迷,請查看:
Technical Note TN2151: Understanding and Analyzing iOS Application Crash Reports
Technical Q&A QA1765: How to Match a Crash Report to a Build
Mach-O Programming Topics
Objc.io on Mach-O Executables