天天看點

iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

轉自:http://www.jianshu.com/p/12a2402b29c2

一、crash log的擷取

當你的app 在手機上crash的時候,會在手機上自動生成一個崩潰日志,也就是我們說的Crash Log。

CrashLog的位置位于:

iPhone裝置的

var/mobile/Library/Logs/CrashReporter

我們要擷取的就是裝置中的這個CrashLog。

1、擷取使用者的 crash log

注意。這裡的使用者指的是你的app已經上架到AppStore上後的使用者。

作為開發者,你想要擷取到你的使用者的崩潰日志的話就得通過 iTunes Connect 了。在iTunes Connect 上的 

Manage Your Applications -> View Details -> Crash Reports

這種方式有個前提,就是使用者裝置同意上傳相關資訊,打開了診斷與用量這個選項

設定->隐私->診斷與用量

 (由于筆者還未有app上架,是以這個方法筆者未用過,so 就此打住。 希望有用過的大牛來拍磚或者補充,Thx)

2、擷取測試機的crash log

很多測試人員在測試途中,或者開發者在自測的途中,會遇到APP crash的情況。

一般的bug,一個合格的測試可以給出明确的重制步驟讓開發者清晰地知道bug原因;

也有不少bug,很多時候是偶現的,很可能無法再次重制出來,無法重制出來的bug是開發者頭疼的,測試一般會給出bug的截圖和重制步驟;

而一般crash是比較嚴重的問題了(是以千萬不能當什麼都沒發生過,不然會被打的233),這個時候崩潰日志就尤為重要了,把崩潰日志send給開發人員,如此才能讓開發者快速定位到錯誤的原因和位置。

那麼測試如何拿到crash日志呢?

方法一:連接配接電腦,通過iTools進階選項來擷取崩潰日志(Mac版的找不到進階選項T.T,望賜教補充)
iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

iOS崩潰日志分析_itools.png

方法二:連接配接電腦,去本地目錄找

Mac : ~/Library/Logs/CrashReporter/MobileDevice/<DEVICE_NAME>

Windows : C://Users/<USERNAME>/AppDataRoamingApple/ComputerLogsCrashReporterMobileDevice/<DEVICE_NAME>/

這個時候你會發現一大堆的.crash檔案和.ips檔案

iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

iOS崩潰日志分析_finder.png

方法三:通過Xcode擷取到崩潰日志,方法是Xcode->Window->Devices
iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

iOS崩潰日志分析_devices(1).png

二、Crash Log的符号化

擷取到了.crash或者.ips檔案的時候(憋糾結這兩個檔案有什麼差,改下字尾名就ok),用文本編輯器打開檔案是一堆十六進制的記憶體位址,你會郁悶的發現壓根看不懂。

iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

log(脫敏後有點醜).png

Q:十六進制記憶體位址可以改成看得懂的麼?

A:當然,将這些十六進制位址轉化成方法名稱和行數的過程稱之為Symbolication(符号化)。符号化很簡單,隻要你把你的.crash檔案拉到上面提到過的Xcode的device log裡面,然後幾秒鐘後就會符号化。但是這裡有個前提,就是這個發生crash的版本包必須是你自己的Xcode裡面Archive出來的(這個是蘋果自帶的方法,會自動檢測是否含有比對的.dSYM檔案和應用二進制檔案)。

Q:那如果要是在新電腦上也想符号化怎麼辦?

答案是,隻有相比對的.dSYM檔案和應用二進制檔案就可以符号化。必需完全比對才行。否則,日志将無法被完全符号化。

iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

.dSYM檔案位置在編的.xcarchive的包内容裡面

上圖是.dSYM檔案的位置,應用的二進制檔案就是打的包得.ipa字尾改成.zip,然後解壓後裡面有個.app檔案就是應用的二進制檔案。

将.dSYM檔案與.app檔案 和crash檔案放一個目錄下,然後再用deviceLog方法就可以符号化了。

另外還有另外符号化iOS Crash檔案的3種方法有大牛已經整合得非常好了,給個連結,這裡就不贅述了。

符号化以後是這樣的~

iOS調試之 crash log分析 轉自:http://www.jianshu.com/p/12a2402b29c2 總結

灰色的都是app的名字

這樣看上去就倍兒爽了^_^

三、Crash Log的分析

接下來就讓我們對已經符号化以後的crash檔案進行分析。

網上已有的分類比較多,我這裡直接把我目前一般找crash原因的子產品展示出來,其他的就留待各位自己去研究了,分别是裝置和crash資訊、異常資訊、線程資訊

1、首先是裝置和crash資訊

Incident Identifier: F3573A...E2F244A              //crash的id
CrashReporter Key:   cc2298...es77eeb              //crash的裝置id
Hardware Model:      iPhone7,                     //手機型号
Process:             [AppName] []              //APP的名字[程序的id]
Path:                /private/.../Application...   //APP的位置
Identifier:          com....                       //bundle ID
Version:              ()                    //版本号
Code Type:           ARM- (Native)               //app的應用架構之類不大清楚,^_^
Parent Process:      launchd []

Date/Time:           -- :: +    //crash發生時間
Launch Time:         -- :: +    //進入應用時間
OS Version:          iOS  (B143)                //iOS版本
Report Version:                      

當你有大量的crash檔案的時候,你就可以對crash檔案裡面的 Hardware Model,Version , OS Version等進行分類,就可以獲知到很多資訊,比如說,你會知道crash一般發生原因是因為手機型号,還是App版本,或者還是手機版本的原因。(筆者暫時沒碰過大量的crash檔案,是以隻能紙上談兵了^_^)

2、其次是異常資訊

Exception Type:  EXC_BAD_ACCESS (SIGABRT)                      //異常的類型
Exception Subtype: KERN_INVALID_ADDRESS at   //異常子類型
Triggered by Thread:                      //異常發生的線程(0為主線程,其他為子線程)                

3、線程資訊

Last Exception Backtrace:
   CoreFoundation                     __exceptionPreprocess + 
   libobjc.A.dylib                    objc_exception_throw + 
   CoreFoundation                     +[NSException raise:format:] + 
   [AppName]                             UmengSignalHandler + 
   libsystem_platform.dylib           _sigtramp + 
   [AppName]                             CScopePtr<IAVGAudioLogic>::operator IAVGAudioLogic*<IAVGAudioLogic>() (xprefc.h:)
   [AppName]                             tencent::av::AVRoomMultiImpl::GetAudioLogic() (av_room_multi_impl.h:)
   [AppName]                             tencent::av::AVAudioCtrlImpl::SetAudioOutputMode(int) (av_audio_ctrl_impl.cpp:)
   [AppName]                             -[AVBasicManager changeSpeakerMode:] (AVManager.mm:)
   [AppName]                             -[KTQAVRoom enableSpeakerMode:] (KTQAVRoom.m:)
  [AppName]                             -[KTQAVRoom settingSpeaker:] (KTQAVRoom.m:)
  [AppName]                             -[KTChatView onAudioNotificationReceived:] (KTChatView.m:)                

恩。。。這符号化以後應該可以看懂了吧,這個crash的問題應該是騰訊第三方的一個沖突吧233

一般來說,通過異常資訊和線程資訊就可以找到crash的原因了。

補充一些異常類型資訊
這裡參考了很多資訊,有很多的異常類型,有些沒遇到過,這裡就厚顔摘抄過來了(這裡是原文位址:iOS Crash檔案的解析,再次感謝大牛們的經驗)

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 前面也提到過,程式無響應使用者強制關閉

總結

最後總結一些可能會對各位有用的博文:

1、iOS應用崩潰日志分析(這最後有一個栗子很有意思)

2、擷取 iOS crash log(分析得很詳細)

3、WWDC視訊(2010年的WWDC視訊)

4、官網文檔——Analyzing iOS Application Crash Reports

最最後得PS下:筆者用的是Xcode7.1+iOS9.1

繼續閱讀