Crash (崩潰)調試跟蹤和Crash Log分析(EXC_BAD_ACCESS 家破、SIGSEGV颜说、SIGABRT、SEGV汰聋、SIGBUS门粪、SIGILL、SIGFPE烹困、SIGIPIPE玄妈、EXC...

前言

在項目開發(fā)中我們總能遇到各種各樣的問題造成Crash崩潰 究其原因一個是我們開發(fā)人員對系統(tǒng)機制理解不夠深刻或者代碼邏輯不夠嚴謹造成的

我們可以少犯錯但不可能不犯錯 ——不知道誰說的系列(:

那么問題發(fā)生后我們應該第一時間定為找到問題再去嘗試解決問題
一般都會經歷這樣一個過程發(fā)現(xiàn)問題 -> 定位問題 -> 解決問題

發(fā)現(xiàn)問題

  • 首先大部分問題其實都應該是程序員自己先發(fā)現(xiàn)的
    每一次提交和改動都應該經過自己嚴謹?shù)目紤]和初步測試保證沒有問題才可以Commit是我們開發(fā)者基本素養(yǎng)
  • 再者如果你們有review機制和測試團隊的話 review組同學是為了代碼質量 測試團隊就是為項目上線之前質量把關的最后一步了 一般測試同學會寫各種測試用例各種場景來check開發(fā)同學寫的項目存在哪些問題或者與需求設計不符的
  • 然后就到了上線了 高并發(fā)多場景的使用 難保會出現(xiàn)一些沒有發(fā)現(xiàn)奇怪的問題 甚至Crash 這就是用戶來發(fā)現(xiàn)問題了 是我們的失職
    在上面任何一個環(huán)節(jié)都肯能出現(xiàn)Crash問題 所以當問題出現(xiàn)后 我們該如何第一時間定位問題 解決問題就尤為重要

定位問題

對于定位問題我們一般又這么幾種方式

一、模擬場景 Debug

一般這種可以知道特定場景并且可以直接真機Debug的問題是最好定位和解決的 一般加個全局斷點就搞定了 也是最簡單最不應該出現(xiàn)的問題


添加全局斷點

二、可以拿到出現(xiàn)Crash問題的手機(需要開啟與開發(fā)者共享崩潰信息 一般都是打開著的)

可以打開手機設置 -> 隱私 -> 分析-> 打開共享iPhone分析 -> 打開與應用開發(fā)者共享
那我們可以通過這種方式查看手機里的Crash log 來幫助我們分析問題
打開Xcode 選擇頂部條上的Window

查看設備Devices

選擇Devices and Simulators 進入
設備信息

選擇View Device Logs 顯示該設備log信息
屏幕快照 2018-10-28 下午4.43.37.png

需要Loading一會兒 我們就可以查看到這臺設備上的一些Crash信息了
上面這張圖看到的是WeChat Crash的堆棧符號化信息 可以看到 EXC_CRASH (SIGKILL) Code 0x8badf00d 應該是被系統(tǒng)watchdog殺掉了 后面再說如何分析符號化信息

三拟蜻、登陸developer開發(fā)者賬號獲取項目版本線上crash信息

Step1:同樣先打開頂部條上的Window 選擇Organizer

屏幕快照 2018-10-28 下午4.53.33.png

Step2:進入Developer開發(fā)項目打包信息看板 選擇Crashes tab
選擇我們線上打包的項目 選擇Release版本查看Crash信息
Tips:如果不是用你的電腦打包的 可以讓打包的同事把.xcarchive給你 雙擊打開就會倒入到這里

Developer看板

Step3:上面這張圖可以看到我們選擇了一個FMDB 數(shù)據庫操作引起的Crash 點進去查看最近兩周發(fā)生了29次Crash 分別發(fā)生在什么類型的設備上 而且有詳細的堆棧信息和方法調用列表
Step4:我們可以把鼠標移動到我們想查看的方法上點擊后面的小箭頭 open crash in project 選擇你的項目去打開直接回定位到項目中的代碼塊 方便快捷直接

Tips:定位的地方可能不準確 需要當前文件跟上線代碼保持一致 才回定位準確

四绎签、集成友盟、Bugly或其他第三方handle了Crash數(shù)據

一般項目中都會集成第三方SDK幫助我們統(tǒng)計數(shù)據和Crash信息
如果你的項目中集成了三方工具來收集Crash信息 可以去三方提供的后臺去查看 會有類似于Xcode的上下文堆棧信息列表 借助于對方的符號化工具定位代碼中的問題也是比較方便的一種方式 在這里就不多說了

Orz...待補充中...

解決問題

符號化信息解讀

建議先看一下官方崩潰信息分析文檔 了解和分析應用程序崩潰報告 你會對Crash信息的獲取和分析有一個比較深刻的理解 下面列舉幾種常見的Crash符號化信息和對應的字段意思

設備信息
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發(fā)生的時間
Launch Time:         2016-05-05 10:42:07.07 +0800    // 進入應用的時間
OS Version:          iOS 9.3.1 (13E238)    // iOS系統(tǒng)的版本
Report Version:      105

如果產品上線之后, 回收集大量的Crash Log日志文件, 可以對Crash文件里面的手機型號,版本號, 手機型號, iOS系統(tǒng)版本,進行分類, 可以獲得更多的信息, 更好的解決bug甚至未知的bug具體原因, 做更好的測試

異常信息

Exception Type:  EXC_CRASH (SIGABRT)   // 異常的類型
Exception Codes: 0x0000000000000000, 0x0000000000000000  // 異常出錯的代碼
Termination Reason: Namespace SPRINGBOARD, Code 0x8badf00d//終止原因
Termination Description: SPRINGBOARD, scene-create watchdog transgression: com.tencent.xin exhausted CPU time allowance of 2.48 seconds |  | ProcessVisibility: Background | ProcessState: Running | WatchdogEvent: scene-create | WatchdogVisibility: Background | WatchdogCPUStatistics: ( | "Elapsed total CPU time (seconds): 10.920 (user 10.920, system 0.000), 65% CPU", | "Elapsed application CPU time (seconds): 5.897, 35% CPU" | )//終斷信息描述
Exception Note:  EXC_CORPSE_NOTIFY  // 異常通知
Triggered by Thread:  0 // 異常發(fā)生的線程(0代表主線程, 其他為主線程)

進程信息
Filtered syslog:
None found

Thread 0 name:  Dispatch queue: com.apple.main-thread
Thread 0 Crashed:
0   CoreFoundation                  0x00000001834153c0 0x183329000 + 967616
1   CoreFoundation                  0x00000001833492e8 0x183329000 + 131816
2   CoreFoundation                  0x00000001833492e8 0x183329000 + 131816
...
6   CoreFoundation                  0x0000000183349274 0x183329000 + 131700
7   Foundation                      0x0000000183dacf90 0x183da1000 + 49040
8   UIKit                           0x000000018d039758 0x18cff8000 + 268120
...
16  UIKit                           0x000000018d14ae58 0x18cff8000 + 1388120
17  UIKit                           0x000000018d1371b4 0x18cff8000 + 1307060
18  WeChat                          0x00000001053c22e4 0x1029e0000 + 43918052
19  WeChat                          0x00000001055106f8 0x1029e0000 + 45287160
20  WeChat                          0x00000001054432b4 0x1029e0000 + 44446388
21  WeChat                          0x0000000104f31c94 0x1029e0000 + 39132308
22  UIKit                           0x000000018d04aee0 0x18cff8000 + 339680
...
28  UIKit                           0x000000018d043770 0x18cff8000 + 309104
29  QuartzCore                      0x00000001875e525c 0x1874c2000 + 1192540
`
Thread 1:
0   libsystem_pthread.dylib         0x0000000183093b04 0x183093000 + 2820

Thread 2 name:  Dispatch queue: NSOperationQueue 0x10dc05910 (QOS: UNSPECIFIED)
Thread 2:
0   libsystem_kernel.dylib          0x0000000182ed3e08 0x182ed3000 + 3592
1   libsystem_kernel.dylib          0x0000000182ed3c80 0x182ed3000 + 3200
2   CoreFoundation                  0x0000000183416e40 0x183329000 + 974400
3   CoreFoundation                  0x0000000183414908 0x183329000 + 964872
4   CoreFoundation                  0x0000000183334da8 0x183329000 + 48552
5   WeChat                          0x00000001058784b4 0x1029e0000 + 48858292
6   CoreFoundation                  0x0000000183476580 0x183329000 + 1365376
7   CoreFoundation                  0x0000000183355748 0x183329000 + 182088

Thread 3:
0   libsystem_kernel.dylib          0x0000000182ef50f4 0x182ed3000 + 139508
1   libsystem_pthread.dylib         0x0000000183097c90 0x183093000 + 19600
2   mars                            0x00000001087969e0 0x1085e8000 + 1763808
3   mars                            0x00000001085f4148 0x1085e8000 + 49480
4   mars                            0x00000001086353fc 0x1085e8000 + 316412
5   libsystem_pthread.dylib         0x0000000183095220 0x183093000 + 8736
6   libsystem_pthread.dylib         0x0000000183095110 0x183093000 + 8464
7   libsystem_pthread.dylib         0x0000000183093b10 0x183093000 + 2832

補充常見的Exception Codes代碼類型

Exception Codes: 常見代碼有以下幾種
0x8badf00d錯誤碼:Watchdog超時酝锅,意為“ate bad food”诡必。
0xdeadfa11錯誤碼:用戶強制退出,意為“dead fall”搔扁。
0xbaaaaaad錯誤碼:用戶按住Home鍵和音量鍵爸舒,獲取當前內存狀態(tài),不代表崩潰稿蹲。
0xbad22222錯誤碼:VoIP應用(因為太頻繁扭勉?)被iOS干掉。
0xc00010ff錯誤碼:因為太燙了被干掉苛聘,意為“cool off”剖效。
0xdead10cc錯誤碼:因為在后臺時仍然占據系統(tǒng)資源(比如通訊錄)被干掉,意為“dead lock”
異常代碼0x8badf00d指示應用程序已終止的iOS 因為看門狗超時發(fā)生焰盗,應用程序時間太長、終止咒林,或對系統(tǒng)時間作出相應熬拒。一個常見的原因是做在主線程上的同步聯(lián)網。無論操作是線程0上垫竞,需要搬到后臺線程澎粟,或處理方式不同,所以它不會阻止在主線程欢瞪。

補充常見的Exception Type異常類型的信息:

1活烙、EXC_BAD_ACCESS:此類型是最常見的crash, 通常用于訪問了不該訪問的內存導致的,一般EXC_BAD_ACCESS后面的()還會帶有補充信息
野指針錯誤形式在Xcode中通常表現(xiàn)為:Thread 1:EXC_BAD_ACCESS(code=EXC_I386_GPFLT)錯誤。因為你訪問了一塊已經不屬于你的內存遣鼓。
2啸盏、SIGSEGV:通常由于重復釋放對象導致, 一般在ARC以后很少見到
3、SIGABRT: 收到Abort信號退出, 通常Foundtion庫中的容器為了保護狀態(tài)正常會做一些檢測, 例如插入nil到數(shù)據中等會遇到此類錯誤.
4骑祟、SEGV(Segmentation Violation):代表無效內存地址, 比如空指針, 未初始化指針, 棧溢出等.
5回懦、SIGBUS:總棧錯誤, 與SIGSEGV不同的是, SIGSEGV訪問的是無效的地址, 而SIGBUS訪問的是有效的地址, 但是總棧訪問異常(如地址對齊問題)
6、SIGILL: 嘗試執(zhí)行非法的指令, 可能不被識別或者沒有權限
7次企、SIGFPE: 數(shù)學計算相關問題, 比如除零操作
8怯晕、SIGIPIPE: 管道另一端沒有進程接手數(shù)據
9、EXC_BAD_INSTRUCTION:此類異常通常由于線程執(zhí)行非法指令導致
10缸棵、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 -

我們可以看到發(fā)生Crash的線程的Crash調用棧, 從上到下分別代表調用順序, 最上面的一個表示拋出異常的位置, 一次往下可以看到API調用順序, 上圖的信息表明本次Crash出現(xiàn)在[NSCondition waitUntilDate:]這個方法中(后面加的數(shù)值 我猜應該是地址偏移量 大概可以找到crash的具體原因(某個文件中的某個方法), 這樣問題就浮出水面了, 方便產品上線后版本迭代, 修改BUG.

使用命令行工具symbolicatecrash

有時候Xcode不能夠很好的符號化crash文件。我們這里介紹如何通過symbolicatecrash來手動符號化crash log。

在處理之前吧凉,請依然將“.app“, “.dSYM”和 ".crash"文件放到同一個目錄下∷沓觯現(xiàn)在打開終端(Terminal)然后輸入如下的命令:
export DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer

然后輸入命令:
/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash appName.crash appName.app > appName.log

現(xiàn)在,符號化的crash log就保存在appName.log中了客燕。
Xcode自帶工具symbolicatecrash解析iOS Crash文件

防止Crash

除了日常代碼習慣良好嚴謹外 攔截存在潛在崩潰危險的方法鸳劳,在攔截的方法里進行相應的處理,也可以防止方法的崩潰

后續(xù)再整理補充 關注我吧 互相學習交流(:~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末患雇,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子宇挫,更是在濱河造成了極大的恐慌苛吱,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件器瘪,死亡現(xiàn)場離奇詭異翠储,居然都是意外死亡,警方通過查閱死者的電腦和手機橡疼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門援所,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人欣除,你說我怎么就攤上這事住拭。” “怎么了历帚?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵废酷,是天一觀的道長。 經常有香客問我抹缕,道長澈蟆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任卓研,我火速辦了婚禮趴俘,結果婚禮上睹簇,老公的妹妹穿的比我還像新娘。我一直安慰自己寥闪,他們只是感情好太惠,可當我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疲憋,像睡著了一般凿渊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上缚柳,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天埃脏,我揣著相機與錄音,去河邊找鬼秋忙。 笑死彩掐,一個胖子當著我的面吹牛,可吹牛的內容都是我干的灰追。 我是一名探鬼主播堵幽,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼弹澎!你這毒婦竟也來了朴下?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤苦蒿,失蹤者是張志新(化名)和其女友劉穎殴胧,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刽肠,經...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年免胃,在試婚紗的時候發(fā)現(xiàn)自己被綠了音五。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡羔沙,死狀恐怖躺涝,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情扼雏,我是刑警寧澤坚嗜,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站诗充,受9級特大地震影響苍蔬,放射性物質發(fā)生泄漏。R本人自食惡果不足惜蝴蜓,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一碟绑、第九天 我趴在偏房一處隱蔽的房頂上張望俺猿。 院中可真熱鬧,春花似錦格仲、人聲如沸押袍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谊惭。三九已至,卻和暖如春侮东,著一層夾襖步出監(jiān)牢的瞬間圈盔,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工苗桂, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留药磺,地道東北人。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓煤伟,卻偏偏與公主長得像癌佩,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子便锨,可洞房花燭夜當晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內容