.crash文件
打開(kāi)Xcode,選擇Window -> Devices(如果是Xcode6以下,則是Window -> Organizer -> Devices)胚股,選擇你自己的機(jī)器带到,然后點(diǎn)擊View Device Logs,這時(shí)候會(huì)打開(kāi)一個(gè)小窗口棘脐,這就是你機(jī)器上至目前為止存的所有app的崩潰信息了。如果是好久沒(méi)看過(guò)這個(gè)信息,打開(kāi)后還要讀取好久才能完全讀完橄镜,總之,找到你的app最后一次崩潰記錄冯乘,右鍵導(dǎo)出洽胶。
.dSYM 文件
dSYM 是保存十六進(jìn)制函數(shù)地址映射信息的中轉(zhuǎn)文件,我們調(diào)試的 symbols 都會(huì)包含在這個(gè)文件中裆馒。每次編譯項(xiàng)目的時(shí)候都會(huì)生成一個(gè)新的 dSYM 文件姊氓,我們應(yīng)該保存每個(gè)正式發(fā)布版本的 dSYM 文件,以備我們更好的調(diào)試問(wèn)題喷好。一般是在我們 Archives 時(shí)保存對(duì)應(yīng)的版本文件的翔横,里面也有對(duì)應(yīng)的?.dSYM?和?.app?文件。路徑為:
~/Library/Developer/Xcode/Archives
.dSYM?文件默認(rèn)在 debug 模式下是不生成的梗搅,我們?nèi)?Build Settings -> Debug Information Format 下禾唁,將?DWARF?修改為?DWARF with dSYM File,再重新編譯下就能生成?.dSYM?文件了无切,直接去項(xiàng)目工程的?Products?目錄下找就行荡短。
symbols 是什么呢?
symbols 就是函數(shù)名或變量名哆键。
找到 symbolicatecrash
symbolicatecrash是 Xcode 自帶的 crash 日志分析工具掘托,我們需要先找到它:
find /Applications/Xcode.app -name symbolicatecrash -type f
接著用真機(jī)打個(gè)包。打好包之后洼哎,不要用 Xcode build烫映,直接用打好的包運(yùn)行我們能導(dǎo)致 crash 的代碼,這樣就生成好?.crash?日志文件了噩峦。
之后锭沟,我們?nèi)?Xcode -> Window -> Devices and Simulators 或者快捷鍵?Command + Shift + 2
找到對(duì)應(yīng)時(shí)間點(diǎn)的 .crash 文件,右擊 Export Log识补。
拿到 .app 文件
.app文件可以使用真機(jī)編譯下族淮,去 項(xiàng)目Products目錄下獲取,也可以去 Archives 目錄下獲取。
符號(hào)解析
利用 dSYM
將.dSYM祝辣、.crash及symbolicatecrash放到同一個(gè)文件下贴妻,執(zhí)行命令:
./symbolicatecrash .crash文件路徑 .dSYM文件路徑 > 名字.crash
利用 app
將.app、.crash及symbolicatecrash放到同一個(gè)文件下蝙斜,執(zhí)行命令:
./symbolicatecrash .crash文件路徑 .app/appName 路徑 > 名字.crash
可能會(huì)報(bào)錯(cuò)誤:
Error:"DEVELOPER_DIR"is not defined at ./symbolicatecrash line 69.
執(zhí)行下命令就行:
exportDEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
然后再重新生成下新的?.crash?文件就行名惩。
使用命令行工具 atos
ymbolicatecrash 可以幫助我們很好的分析 crash 日志,但是有它的局限性 --- 不夠靈活孕荠。我們需要?symbolicatecrash娩鹉、.crash?及?.dSYM?三個(gè)文件才能解析。
相對(duì)于 symbolicatecrash稚伍,?atos?命令更加靈活弯予,特別是你需要對(duì)不同渠道的 crash 文件,寫(xiě)一個(gè)自動(dòng)化的分析腳本的時(shí)候个曙,這個(gè)方法就極其有用锈嫩。
但是這種方式也有個(gè)不方便的地方:一個(gè)線上的 App,用戶使用的版本存在差異垦搬,而每個(gè)版本所對(duì)應(yīng)的?.dSYM?都是不同的呼寸。必須確保?.crash?和?.dSYM?文件是匹配的,才能正確符號(hào)化悼沿,匹配的條件就是它們的 UUID 一致等舔。 在這之前,先介紹下 UUID:
什么是 UUID ?
UUID 是由一組 32 位數(shù)的十六進(jìn)制數(shù)字所構(gòu)成糟趾。每一個(gè)可執(zhí)行程序都有一個(gè) build UUID 唯一標(biāo)識(shí)。.crash日志包含發(fā)生 crash 的這個(gè)應(yīng)用的 build UUID 以及 crash 發(fā)生時(shí)甚牲,應(yīng)用加載的所有庫(kù)文件的 build UUID义郑。
獲取 UUID
.crash UUID
執(zhí)行命令:
grep --after-context=2"Binary Images:"*crash
輸出:
T.crash:Binary Images:T.crash-0x7c000 - 0x87fff DreamDemo armv7? /var/containers/Bundle/Application/DEEBE571-D512-4E8F-B712-ED4D19CE64F9/DreamDemo.app/DreamDemoT.crash-0xa9000 - 0xd4fff dyld armv7s? /usr/lib/dyld
.dSYM UUID
執(zhí)行命令:
dwarfdump --uuid xxxxx.app.dSYM
工具
直接操作atos命令畢竟是有點(diǎn)不方便,GitHub 上有個(gè)工具丈钙,可以輔助我們解析dSYMTools
系統(tǒng)庫(kù)的符號(hào)化解析
用戶/用戶名稱xxx/資源庫(kù)/Developer/Xcode/iOS DeviceSupport
這些庫(kù)的版本都是和?.crash?文件中是對(duì)應(yīng)的
一旦我把這個(gè)?10.2 (14C5077b)?系統(tǒng)的符號(hào)化庫(kù)刪掉非驮,.crash?文件就會(huì)變成這樣:
可以明顯的發(fā)現(xiàn),系統(tǒng)庫(kù)的堆棧變成了一堆地址雏赦。
新版本劫笙,每當(dāng)我們手機(jī)連上 Xcode 時(shí),都會(huì)把當(dāng)前版本的系統(tǒng)符號(hào)庫(kù)自動(dòng)導(dǎo)入到?/用戶/用戶名稱xxx/資源庫(kù)/Developer/Xcode/iOS DeviceSupport?目錄下星岗。但是 iOS 版本那么多填大,之前舊的系統(tǒng)符號(hào)庫(kù)該怎么獲取呢?有人已經(jīng)整理好了?iOS-System-Symbols俏橘,我們只需要根據(jù)?.crash?文件的版本信息允华,下載對(duì)應(yīng)的系統(tǒng)符號(hào)化文件到目錄下即可。
?如何判斷符號(hào)化是否完成
總結(jié)
利用 symbolicatecrash 解析,可以將整個(gè).crash日志堆棧解析靴寂,但是由于依賴symbolicatecrash磷蜀、.crash以及.dSYM三個(gè)文件,或者.app百炬、.crash及symbolicatecrash三個(gè)文件褐隆,導(dǎo)致不太靈活。
利用atos命令只需要.crash和.dSYM剖踊,或者.crash和.app妓灌,知道對(duì)應(yīng)的堆棧地址,就能解析蜜宪,方便自動(dòng)化腳本分析虫埂,但是 crash 堆棧可能需要自己實(shí)現(xiàn)收集圃验。
注意
1掉伏、系統(tǒng)庫(kù)是否包含相應(yīng)符號(hào)解析庫(kù)以及armv7s arm64e(如果是拿到設(shè)備導(dǎo)出crash文件怎么不存在這個(gè)問(wèn)題,因?yàn)閤code會(huì)自動(dòng)復(fù)制相關(guān)符號(hào)解析庫(kù))