iOS-----Crash文件分析(一)

開發程序的過程當中無論咱們已經如何當心,老是會在不經意間遇到程序閃退。腦補一下當你在一羣人面前自信的拿着你的App作功能預演的時候,流暢的操做被無情地Crash打斷。聯想起老羅在發佈Smartisan OS的時候說了,他準備了10個手機,若是一臺有問題,就換一臺,若是10臺後掛了他就不作手機了。好了不閒扯了,今天就跟你們一塊兒聊聊iOSCrash文件的組成以及經常使用的分析工具。html

  有一個WWDC 2010的視頻推薦你們抽空看看,視頻名稱「Understanding Crash Reports on iPhone OS」,該視頻詳細講解了Crash文件的結構。固然若是你沒時間看的話,不妨閱讀如下這篇文章。ios

 

1、Crash文件結構數組

當程序運行Crash的時候,系統會把運行的最後時刻的運行信息記錄下來,存儲到一個文件中,也就是咱們所說的Crash文件。iOS的Crash日誌一般由如下6各部分組成。網絡

一、Process Information(進程信息)架構

Incident Idnetifier 崩潰報告的惟一標識符,不一樣的Crash
CrashReporter Key 設備標識相對應的惟一鍵值(並不是真正的設備的UDID,蘋果爲了保護用戶隱私iOS6之後已經沒法獲取)。一般同一個設備上同一版本的App發生Crash時,該值都是同樣的。
Hardware Model 表明發生Crash的設備類型,上圖中的「iPad4,4」表明iPad Air
Process 表明Crash的進程名稱,一般都是咱們的App的名字, []裏面是當時進程的ID
Path 可執行程序在手機上的存儲位置,注意路徑時到XXX.app/XXX,XXX.app實際上是做爲一個Bundle的,真正的可執行文件實際上是Bundle裏面的XXX,感興趣的能夠本身查一下相關資料,有機會我後面也會介紹到
Identifier 你的App的Indentifier,一般爲「com.xxx.yyy」,xxx表明大家公司的域名,yyy表明某一個App
Version 當前App的版本號,由Info.plist中的兩個字段組成,CFBundleShortVersionString and CFBundleVersion
Code Type 當前App的CPU架構
Parent Process 當前進程的父進程,因爲iOS中App一般都是單進程的,通常父進程都是launchd

 

二、Basic Informationapp

Date/Time Crash發生的時間,可讀的字符串
OS Version 系統版本,()內的數字表明的時Bulid號
Report Version Crash日誌的格式,目前基本上都是104,不一樣的version裏面包含的字段可能有不一樣

 

 

 

三、Exception(很是重要)ide

Exception Type 異常類型
Exception Subtype: 異常子類型
Crashed Thread 發生異常的線程號

 

 

 

四、Thread Backtrace函數

發生Crash的線程的Crash調用棧,從上到下分別表明調用順序,最上面的一個表示拋出異常的位置,依次往下能夠看到API的調用順序。上圖的信息代表本次Crash出現xxxViewController的323行,出錯的函數調用爲orderCountLoadFailed。工具

五、Thread Statepost

Crash時發生時刻,線程的狀態,一般咱們根據Crash棧便可獲取到相關信息,這部分通常不用關心。

六、Binary Images

Crash時刻App加載的全部的庫,其中第一行是Crash發生時咱們App可執行文件的信息,能夠看出爲armv7,可執行文件的包得uuid位c0f……cd65,解析Crash的時候dsym文件的uuid必須和這個同樣才能完成Crash的符號化解析。

2、常見的Crash類型

一、Watchdog timeout

Exception Code:0x8badf00d, 不太直觀,能夠讀成「eat bad food」,意思是don‘t block main thread

緊接着下面會有一段描述:

Application Specific Information:

com.xxx.yyy   failed to resume in time

對於此類Crash,咱們應該去審視本身App初始化時作的事情是否正確,是否在主線程請求了網絡,或者其餘耗時的事情卡住了正常初始化流程。

一般系統容許一個App從啓動到能夠相應用戶事件的時間最多爲5S,若是超過了5S,App就會被系統終止掉。在Launch,resume,suspend,quit時都會有相應的時間要求。在Highlight Thread裏面咱們能夠看到被終止時調用到的位置,xxxAppDelegate加上行號。 

PS. 在鏈接Xcode調試時爲了便於調試,系統會暫時禁用掉Watchdog,因此此類問題的發現須要使用正常的啓動模式。

二、User force-quit

Exception Codes: 0xdeadfa11, deadfall

這個強制退出跟咱們平時所說的kill掉後臺任務操做還不太同樣,一般在程序bug形成系統沒法響應時能夠採用長按電源鍵,當屏幕出現關機確認畫面時按下Home鍵便可關閉當前程序。

三、Low Memory termination

跟通常的Crash結構不太同樣,一般有Free pages,Wired Pages,Purgeable pages,largest process 組成,同事會列出當前時刻系統運行全部進程的信息。

關於Memory warning能夠參看我以前寫的一篇文章IOS 內存警告 Memory warning level

App在運行過程當中,系統內存緊張時一般會先發警告,同時把後臺掛起的程序終止掉,最終若是仍是內存不夠的話就會終止掉當前前臺的進程。

當接受到內存警告的過後,咱們應該釋放盡量多的內存,Crash其實也能夠看作是對App的一種保護。

四、Crash due to bugs

由於程序bug致使的Crash一般千奇百怪,很難一律而論。大部分狀況經過Crash日誌就能夠定位出問題,固然也不排除部分疑難雜症看半天都不值問題出在哪兒。這個就只能看功底了,一點點找,老是能發現蛛絲馬跡。是在看不出來時還能夠求助於Google大神,總有人遇到和你同樣的Bug 

3、常見的Exception Type & Exception Code

一、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

除零錯誤會拋出此類異常

二、Exception Code

0xbaaaaaad 此種類型的log意味着該Crash log並不是一個真正的Crash,它僅僅只是包含了整個系統某一時刻的運行狀態。一般能夠經過同時按Home鍵和音量鍵,可能因爲用戶不當心觸發
0xbad22222 當VOIP程序在後臺太過頻繁的激活時,系統可能會終止此類程序
0x8badf00d 這個前面已經介紹了,程序啓動或者恢復時間過長被watch dog終止
0xc00010ff 程序執行大量耗費CPU和GPU的運算,致使設備過熱,觸發系統過熱保護被系統終止
0xdead10cc 程序退到後臺時還佔用系統資源,如通信錄被系統終止
0xdeadfa11 前面也提到過,程序無響應用戶強制關閉

  

3、獲取Crash的途徑

一、本機

經過xCode鏈接測試機器,直接在Device中便可讀取到該機器上發生的全部Crash log。

二、itunes connect

經過itunes connect後臺獲取到用戶上報的Crash日誌。

三、第三方的Crash收集系統

有不少優秀的第三方Crash收集系統大大的方便了咱們收集Crash,甚至還帶了符號化Crash日誌的功能。比較經常使用的有CrashlyticsFlurry等。

4、附錄

Apple官方文檔:Understanding and Analyzing iOS Application Crash Reports

        Technical Note TN2123 CrashReporter

        https://developer.apple.com/library/ios/qa/qa1592/_index.html

WWDC視頻:  Understanding Crash Reports on iPhone OS   

  Crash日誌記錄的時候是將Crash發生時刻,函數的調用棧,以及線程等信息寫入文件。通常都是直接寫的16進制地址,若是不通過符號化的話,基本上很難獲取到有用信息,下一篇咱們將聊一聊Crash日誌的符號化,通俗點講就是讓Crash日誌變成咱們可讀的格式。

相關文章
相關標籤/搜索