天天看點

ios 捕抓crash_iOS 崩潰捕獲和分析

ios 捕抓crash_iOS 崩潰捕獲和分析

摘要:

在開發中經常會遇到崩潰,這時候你知道崩潰的檔案存放在哪裡?你有什麼方法來擷取崩潰的日志檔案?崩潰日志擷取到了,你知道如何檢視它嗎?本文将帶着以上的檔案,對崩潰進行分析。

崩潰日志

1.什麼是崩潰日志

iOS 裝置上的應用程式在閃退的時候,作業系統會聲稱一個崩潰日志,儲存在裝置上1

2

3路徑:設定-> 隐私 -> 診斷與用量 -> 診斷與用量資料

在診斷與用量的界面中 有發送和不發送的操作,在這裡如果選擇發送的話,會自動将診斷和用量資料發送到iTunes 來幫助開發者進行崩潰日志的分析

崩潰日志的擷取

1.連接配接裝置擷取崩潰日志

裝置與電腦上的ITunes Stores 同步後,會将崩潰日志儲存在電腦上,崩潰日志儲存在一下位置1

2

3MAC OS X : ~/Library/Logs/CrashReporter/MobileDevice/

然後可以看到你的裝置名稱的檔案夾,然後繼續往下找

2.通過XCode 連接配接來導出崩潰日志

首先将XCode 和電腦連接配接,然後 window-> Devices and Simulators

ios 捕抓crash_iOS 崩潰捕獲和分析

然後進入檢視View Device Logs

ios 捕抓crash_iOS 崩潰捕獲和分析

這時候可以檢視到所有的日志檔案,可以檢視到右邊視窗看到對應的

3.通過iTunes 擷取崩潰日志

通過Itunes Connect 擷取使用者上傳的崩潰日志,登入iTunes Connect 選中APP ,點選可供銷售的APP 在額外資訊中可以檢視到所有iOS 版本下的崩潰日志

崩潰日志的分析

ios 捕抓crash_iOS 崩潰捕獲和分析

這裡我們來分析下對用字段的解析:incident Identifier:崩潰日志的唯一辨別符

CrashReporter Key:是與裝置辨別相對應的唯一鍵值。

Hardware Model:辨別裝置類型

Process :是應用的名稱

Version:APP的版本号

最重要的兩個:

Exception Type:崩潰的類型

Last Exception Backtrace:發生崩潰的時候的堆棧

XCode 會自動符号化代碼,翻譯成明文:

将.crash 檔案反編譯得到明文的crash 檔案首先在桌面建立一個檔案夾 DebugTest

然後将 MyApp.app ,MyApp.app.dYSM 還有 崩潰檔案 .crash 檔案放入到這個檔案夾中

找到Symbolicatecrash 這個檔案,将其拷貝到DebugTest 這個檔案夾中1cd /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources

在終端中運作指令,符号化崩潰日志1

2

3

4

5cd /User/younmae/Desktop/DebugTest

export DEVELOP_DIR = "/Applications/Xcode.app/Contents/Developer"

./Symbolicatecrash -v crashfile MyApp.app.dYSM

然後再打開就看到了符号化後的明文的崩潰日志檔案

注意:建構版本的時候會自動生成dSYM 檔案,但是debug 的時候,是沒有的,需要我們手動開啟,在build Setting 中搜尋debug

ios 捕抓crash_iOS 崩潰捕獲和分析
ios 捕抓crash_iOS 崩潰捕獲和分析

這兩個就可以産生dsym 了

手動捕獲崩潰日志

首先Apple 提供了一個NSSetUncaughtExceptionHandler1

2

3

4

5

6

7

8

9

10

11

12

13-(void)catchCrashLogs{

NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);

}

void UncaughtExceptionHandler(NSException *exception){

if(exception == nil) return;

NSArray *array = [exception callStacksSymbols];

NSString *reason = [exception reason];

NSString *name = [exception name];

}

解決崩潰收集沖突問題

在進行崩潰日志處理的時候,可能會遇到一些沖突的操作:首先因為收集崩潰日志的操作是有些第三方操作也需要實作的,是以這裡我們需要先确定下處理這個沖突的流程

首先先通過 NSGetUncaughtExceptionHandler() 拿到之前日志庫處理exception 的handler ,然後通過 NSSetUncaughtExceptionHandler(),設定自己處理的exception 的hanler ,在自己的handler 處理異常完之後,再将異常塞給之前的hanler

初始化

使用第三方的工具的時候,首先需要先初始化第三方的操作,然後才能初始化我們自己的日志收集工具

擷取第三方的handler 和 設定自己的handler

static NSUncaughtExceptionHandler *_previousHandler;

_perviousHandler = NSGetUncaughtExceptionHandler();

//設定自己處理異常的handler

NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler);

處理自己的異常1

2

3

4

5void UncaughtExceptionHanlder(NSException *exception){

//

取出exception 的 name reason 和 callStacksSymbols 計算出崩潰是的偏移量把這些資訊以字段存儲到本地上

}

将exception 塞給第三方

處理完自己的邏輯後就需要将exception 指派給我們之前儲存的handler ,否則第三方就無法統計崩潰的資料1_previousHandler(exception);

不足和改進

并不是所有的程式崩潰都是可以捕獲的異常,有些時候引起異常的大多數原因:比如說記憶體錯誤,重複是否等錯誤資訊就可能無能為力。這時候需要通過signal 來做處理

參考