iOS開發之Crash日志獲取與分析

當在非調試狀態下,我們用真機測試app,crash或者說閃退是一件很常見的事,最讓我們開發人員頭疼的是,自己在開發過程中總是不會遇到crash,安裝到別人的設備,就出現了閃退崩潰現象。這種偶現的、概率比較低的閃退是最令人頭疼。
這時iOS crash log 派上用場了,程序的大多數crash都會記錄在用戶的手機中,獲取crash log的方法有兩種:

  • 用戶把設備連接到電腦上,打開xcode-window,選中Devices-當前連接設備-Device Log,就可以查看所有當前設備的crash log,這個時候打開每一份crash的時候,發現這些文件的部分地址都會被轉換成,類名,方法名和行號等。設備上的日志只用剛剛查看過都會被同步到organizer種,在LIBRARY下的Device Log可以查看。
  • 如果你的應用已經上架,那么開發者可以通過iTunes Connect(Manage Your Applications - View Details - Crash Reports)獲取用戶的crash日志。不過這并不是100%有效的,而且大多數開發者并不依賴于此,因為這需要用戶設備同意上傳相關信息,詳情可參見iOS: Providing Apple with diagnostics and usage information摘要。

當上面方法都不行時,就是說在Devices看不到logs時,那就用下面的方法來獲取crash日志文件
設備連接iTune,選擇設備和mac同步文件,然后保存在手機里的crash日志文件將會同步到電腦,目錄在
~/Library/Logs/CrashReporter/MobileDevice/xxx的 iPhone
如下圖,就是所有的crash文件:

Paste_Image.png

打開crash日志文件,你會有點蒙圈,因為全都是十六進制的數據

Paste_Image.png

常見的Exception Type & Exception Code
1、Exception Type
1)EXC_BAD_ACCESS
此類型的Excpetion是我們最長碰到的Crash,通常用于訪問了不改訪問的內存導致。一般EXC_BAD_ACCESS后面的"()"還會帶有補充信息。
SIGSEGV: 通常由于重復釋放對象導致,這種類型在切換了ARC以后應該已經很少見到了。
**SIGABRT: ** 收到Abort信號退出,通常Foundation庫中的容器為了保護狀態正常會做一些檢測,例如插入nil到數組中等會遇到此類錯誤。
SEGV:(Segmentation Violation),代表無效內存地址,比如空指針,未初始化指針,棧溢出等;
SIGBUS:總線錯誤,與 SIGSEGV 不同的是,SIGSEGV 訪問的是無效地址,而 SIGBUS 訪問的是有效地址,但總線訪問異常(如地址對齊問題)
SIGILL:嘗試執行非法的指令,可能不被識別或者沒有權限
2)EXC_BAD_INSTRUCTION
此類異常通常由于線程執行非法指令導致
3)EXC_ARITHMETIC
除零錯誤會拋出此類異常
2、Exception Code
**0xbaaaaaad **此種類型的log意味著該Crash log并非一個真正的Crash,它僅僅只是包含了整個系統某一時刻的運行狀態。通常可以通過同時按Home鍵和音量鍵,可能由于用戶不小心觸發
0xbad22222當VOIP程序在后臺太過頻繁的激活時,系統可能會終止此類程序
0x8badf00d這個前面已經介紹了,程序啟動或者恢復時間過長被watch dog終止
0xc00010ff程序執行大量耗費CPU和GPU的運算,導致設備過熱,觸發系統過熱保護被系統終止
0xdead10cc程序退到后臺時還占用系統資源,如通訊錄被系統終止
0xdeadfa11前面也提到過,程序無響應用戶強制關閉

其實,crash log里關鍵的信息就在backtrace,對linux有一定了解的相信對backtrace是有所了解的,其實Linux下常常利用backtrace追蹤函數調用堆棧以及定位段錯誤

那關鍵的來了,把Backtrace的十六進制數據轉成我們能看懂的文字,這個過程我們稱之為符號化,那么我們就一步一步講解

  • 1.上述獲取到log后,我們首先找到相對應的.dSYM文件,在哪呢?就在這個目錄里: ~/Library/Developer/Xcode/Archives/
  • 2.進入這個目錄后,可能會有多個archive文件,找到對應時間的,然后右鍵顯示包內容,可以看到,xxx.app.dSYM文件,如下圖:
Paste_Image.png
  • 3.然后再找到上述圖片Products/Applications/xxx.app文件
  • 4.將上面crash log文件,xxx.app.dSYM和xxx.app文件拷貝到同一個文件里

怎么確定.dSYM和.app文件是同一個編譯出來的呢?
打開終端,使用命令查看兩個文件的uuid是否一致,一致則表示.dSYM文件和.app文件是相匹配的,命令如下:
dwarfdump --uuid xxx.app/xxx
dwarfdump --uuid xxx.app.dSYM/ (xxx為app name

  • 5.然后使用命令行工具symbolicatecrash來符號化crash log

怎么找到symbolicatecrash呢?
其實symbolicatecrash工具是Xcode自帶的一個命令行工具,找它,當然是去xcode的安裝目錄咯
先到xcode安裝去,一層一層往下走 /Applications/Xcode.app/Contents/SharedFrameworks
這里偷個懶不去找symbolicatecrash在哪個目錄了,直接輸入查找命令來找find ./ -name "symbolicatecrash",如下圖

Paste_Image.png

到這個目錄去,把這個工具拷貝到和上述文件同一個目錄
sudo cp symbolicatecrash ~/Desktop/xxxxx/xxx

然后就開始符號化,執行命令:
./symbolicatecrash appName-2016-10-26-201420.crash appName.app.dSYM/ > xxxxx.log
(如果執行命令出現錯誤:Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash,請設置環境變量:export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer;)
打開日志文件,你會發現,backtrace就變成我們可以讀懂的代碼方法和精準定位到了哪一行了,哈哈

Paste_Image.png

太好用了,這樣就遇到偶現的閃退,我們就可以比較輕松的定位問題,最快的定位問題,最好解決問題。

總結

總結一下,整個過程就是,獲取crash log -》找到相匹配的 app文件 -》 獲取symbolicatecrash工具 -》 符號化crash文件。希望這個對大家有所幫助。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • iOS開發中,經常遇到App在開發及測試時不會有問題,但是裝在別人的設備中會出現各種不定時的莫名的 crash,因...
    咖咖嘻閱讀 6,191評論 3 21
  • LLVM簡介 XCode4.0以后,LLVM是構架編譯器(compiler)的框架系統,以C++編寫而成,用于優化...
    苦工閱讀 9,813評論 1 16
  • 本文就捕獲iOS Crash、Crash日志組成、Crash日志符號化、異常信息解讀、常見的Crash五部分介紹。...
    xukuangbo_閱讀 1,597評論 0 0
  • 北方有美人 煢煢孑立 轉發錦鯉交好運 多肉的中秋
    HeyJewel1018閱讀 324評論 0 0
  • 婚喪嫁娶,迎來送往,生活中到處離不開酒,有酒的地方就有酒鬼。 酒鬼是一些可愛的人,他們的言行舉止,脫離了日常生活軌...
    牛頭馬蟻閱讀 1,470評論 2 1