打開Crash Log 會看到如下的信息:
Incident Identifier: AF4F2C83-8F68-47EF-B5AA-F16B067B5DF413 libdyld.dylib 0x000000018156a8b8 start + 4
以上就是Crash Log 文件的信息(設備的信息, crash信息,異常信息, 線程信息)
1. 設備信息
Incident Identifier: AF4F2C83-8F68-47EF-B5AA-F16B067B5DF4 // crash的ID
CrashReporter Key: 5670de85ee1f0f3c904891536e81ec086ed4b35b // crash 的設備ID
Hardware Model: iPhone8,1 // 手機的型號 (iPhone8,1代表iPhone6s 8,2 代表iPhone6s Plus)
Process: kidneyUser [896] // App的名稱 (該App的進程ID)
Path: /private/var/containers/Bundle/Application/48C71AA1-EB99-49B1-ABD7-2903DBA8E394/kidneyUser.app/kidneyUser // APP 的位置 路徑
Identifier: kidneyDiseaseHospitalUser // bundle ID
Version: 1 (1.0) // APP的版本號
Code Type: ARM-64 (Native) // app的應用架構
Parent Process: launchd [1]
Date/Time: 2016-05-05 10:45:43.43 +0800 // crash發生的時間
Launch Time: 2016-05-05 10:42:07.07 +0800 // 進入應用的時間
OS Version: iOS 9.3.1 (13E238) // iOS系統的版本
Report Version: 105
如果產品上線之後, 回收集大量的Crash Log日志文件, 可以對Crash文件裡面的手機型號,版本號, 手機型號, iOS系統版本,進行分類, 可以獲得更多的信息, 更好的解決bug甚至未知的bug具體原因, 做更好的測試
2.異常信息
Exception Type: EXC_CRASH (SIGABRT) // 異常的類型
Exception Codes: 0x0000000000000000, 0x0000000000000000 // 異常出錯的代碼
Exception Note: EXC_CORPSE_NOTIFY // 異常通知
Triggered by Thread: 0 // 異常發生的線程(0代表主線程, 其他為主線程)
補充常見的Exception Codes代碼類型
Exception Codes: 常見代碼有以下幾種
0x8badf00d錯誤碼:Watchdog超時,意為“ate bad food”。
0xdeadfa11錯誤碼:用戶強制退出,意為“dead fall”。
0xbaaaaaad錯誤碼:用戶按住Home鍵和音量鍵,獲取當前內存狀態,不代表崩潰。
0xbad22222錯誤碼:VoIP應用(因為太頻繁?)被iOS干掉。
0xc00010ff錯誤碼:因為太燙了被干掉,意為“cool off”。
0xdead10cc錯誤碼:因為在後台時仍然占據系統資源(比如通訊錄)被干掉,意為“dead lock”
補充常見的Exception Type異常類型的信息:
1.EXC_BAD_ACCESS:此類型是最常見的crash, 通常用於訪問了不該訪問的內存導致的,一般 EXC_BAD_ACCESS後面的()還會帶有補充信息
SIGSEGV: 通常由於重復釋放對象導致, 一般在ARC以後很少見到
SIGABRT: 收到Abort信號退出, 通常Foundtion庫中的容器為了保護狀態正常會做一些檢測, 例如插入nil到數據中等會遇到此類錯誤.
SEGV(Segmentation Violation): 代表無效內存地址, 比如空指針, 未初始化指針, 棧溢出等.
SIGBUS: 總棧錯誤, 與SIGSEGV不同的是, SIGSEGV訪問的是無效的地址, 而SIGBUS訪問的是有效的地址, 但是總棧訪問異常(如地址對齊問題)
SIGILL: 嘗試執行非法的指令, 可能不被識別或者沒有權限
SIGFPE: 數學計算相關問題, 比如除零操作
SIGIPIPE: 管道另一端沒有進程接手數據
2. EXC_BAD_INSTRUCTION:此類異常通常由於線程執行非法指令導致
3. EXC_ARITHMETIC:除零錯誤會拋出此類異常
Last Exception Backtrace: 最後異常回溯, 一般根據這個代碼就能找到具體的crash問題
下面截取的是微信的crash blog
Thread 0 name: Dispatch queue: com.apple.main-thread
Thread 0:
0 libsystem_kernel.dylib 0x000000018223ff24 __psynch_cvwait + 8
1 libsystem_pthread.dylib 0x000000018230ad20 _pthread_cond_wait + 704
2 Foundation 0x0000000182f9fdf0 -[NSCondition waitUntilDate:] + 344
3 Foundation 0x0000000182f9ce34 -[NSConditionLock lockWhenCondition:beforeDate:] + 256
4 UIKit 0x000000018781dbc4 -[UIKeyboardTaskQueue waitUntilAllTasksAreFinished] + 196
5 UIKit 0x0000000187c05878 -[UIKeyboardImpl setKeyboardInputMode:userInitiated:] + 112
6 UIKit 0x0000000187c0de44 -[UIKeyboardImpl recomputeActiveInputModesWithExtensions:] + 336
7 UIKit 0x000000018781e8f0 -[UIKeyboardImpl setDelegate:force:] + 2292
8 UIKit 0x0000000187817eb0 -[UIPeripheralHost(UIKitInternal) _reloadInputViewsForResponder:] + 1180
9 UIKit 0x00000001878179e4 -[UIResponder(UIResponderInputViewAdditions) reloadInputViews] + 80
10 UIKit 0x0000000187879670 -[UIResponder becomeFirstResponder] + 600
11 UIKit 0x0000000187879a1c -[UIView(Hierarchy) becomeFirstResponder] + 148
12 UIKit 0x0000000187900b34 -[UITextField becomeFirstResponder] + 64
13 UIKit 0x00000001879b1fe4 -[UITextInteractionAssistant(UITextInteractionAssistant_Internal) setFirstResponderIfNecessary] + 256
14 UIKit 0x00000001879b1498 -
我們可以看到發生Crash的線程的Crash調用棧, 從上到下分別代表調用順序, 最上面的一個表示拋出異常的位置, 一次往下可以看到API調用順序, 上圖的信息表明本次Crash出現在[NSCondition waitUntilDate:]這個方法中(後面加的數值 我猜應該是地址偏移量O(∩_∩)O) 大概可以找到crash的具體原因(某個文件中的某個方法), 這樣問題就浮出水面了, 方便產品上線後版本迭代, 修改BUG.