發程序的過程當中無論咱們已經如何當心,老是會在不經意間遇到程序閃退。腦補一下當你在一羣人面前自信的拿着你的App作功能預演的時候,流暢的操做被無情地Crash打斷。聯想起老羅在發佈Smartisan OS的時候說了,他準備了10個手機,若是一臺有問題,就換一臺,若是10臺後掛了他就不作手機了。好了不閒扯了,今天就跟你們一塊兒聊聊iOS Crash文件的組成以及經常使用的分析工具。html
有一個WWDC 2010的視頻推薦你們抽空看看,視頻名稱「Understanding Crash Reports on iPhone OS」,該視頻詳細講解了Crash文件的結構。固然若是你沒時間看的話,不妨閱讀如下這篇文章。ios
1、Crash文件結構數組
當程序運行Crash的時候,系統會把運行的最後時刻的運行信息記錄下來,存儲到一個文件中,也就是咱們所說的Crash文件。iOS的Crash日誌一般由如下6各部分組成。網絡
一、Process Information(進程信息)架構
Incident Idnetifier-崩潰報告的惟一標識符,不一樣的Crashapp
CrashReporter Key-設備標識相對應的惟一鍵值(並不是真正的設備的UDID,蘋果爲了保護用戶隱私iOS6之後已經沒法獲取)。一般同一個設備上同一版本的App發生Crash時,該值都是同樣的。ide
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 Information
Date/Time-Crash發生的時間,可讀的字符串
OS Version-系統版本,()內的數字表明的時Bulid號
Report Version-Crash日誌的格式,目前基本上都是104,不一樣的version裏面包含的字段可能有不一樣
三、Exception(很是重要)
Exception Type-異常類型
Exception Subtype-異常子類型
Crashed Thread-發生異常的線程號
四、Thread Backtrace
發生Crash的線程的Crash調用棧,從上到下分別表明調用順序,最上面的一個表示拋出異常的位置,依次往下能夠看到API的調用順序。上圖的信息代表本次Crash出現xxxViewController的323行,出錯的函數調用爲orderCountLoadFailed。
五、Thread State
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
緊接着下面會有一段描述:
1
2
|
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
1
|
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前面也提到過,程序無響應用戶強制關閉
4、獲取Crash的途徑
一、本機
經過xCode鏈接測試機器,直接在Device中便可讀取到該機器上發生的全部Crash log。
二、itunes connect
經過itunes connect後臺獲取到用戶上報的Crash日誌。
三、第三方的Crash收集系統
有不少優秀的第三方Crash收集系統大大的方便了咱們收集Crash,甚至還帶了符號化Crash日誌的功能。比較經常使用的有Crashlytics,Flurry等。
5、附錄
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日誌變成咱們可讀的格式。