標籤:
在iOS開發調試過程中以及上線之後,程式經常會出現崩潰的問題。簡單的崩潰還好說,複雜的崩潰就需要我們通過解析Crash檔案來分析了,解析Crash檔案在iOS開發中是比較常見的。
現在網上有很多關於解析崩潰資訊的部落格,但是大多品質參差不齊,或者有些細節沒有注意到。今天寫一篇部落格總結一下我對崩潰調試的使用和技巧,如果有哪些錯誤或遺漏,還請指點,謝謝!
擷取崩潰資訊
在iOS中擷取崩潰資訊的方式有很多,比較常見的是使用友盟、百度等第三方分析工具,或者自己收集崩潰資訊並上傳公司伺服器。下面列舉一些我們常用的崩潰分析方式:
收集崩潰資訊
蘋果給我們提供了異常處理的類,NSException類。這個類可以建立一個異常對象,也可以通過這個類擷取一個異常對象。
這個類中我們最常用的還是一個擷取崩潰資訊的C函數,我們可以通過這個函數在程式發生異常的時候收集這個異常。
| 12345678910111213 |
// 將系統提供的擷取崩潰資訊函數寫在這個方法中,以保證在程式開始運行就具有擷取崩潰資訊的功能 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 將下面C函數的函數地址當做參數 NSSetUncaughtExceptionHandler(&UncaughtExceptionHandler); return YES; } // 設定一個C函數,用來接收崩潰資訊 void UncaughtExceptionHandler(NSException *exception){ // 可以通過exception對象擷取一些崩潰資訊,我們就是通過這些崩潰資訊來進行解析的,例如下面的symbols數組就是我們的崩潰堆棧。 NSArray *symbols = [exception callStackSymbols]; NSString *reason = [exception reason]; NSString *name = [exception name]; } |
我們也可以通過下面方法擷取崩潰統計的函數指標:
| 1 |
NSUncaughtExceptionHandler *handler = NSGetUncaughtExceptionHandler(); |
dSYM 符號集
進行崩潰分析,首先要弄懂一個概念,就是符號集。
符號集是我們對ipa檔案進行打包之後,和.app檔案同級的尾碼名為.dSYM的檔案,這個檔案必須使用Xcode進行打包才有。
每一個.dSYM檔案都有一個UUID,和.app檔案中的UUID對應,代表著是一個應用。而.dSYM檔案中每一條崩潰資訊也有一個單獨的UUID,用來和程式的UUID進行校對。
我們如果不使用.dSYM檔案擷取到的崩潰資訊都是不準確的。
符號集中儲存著檔案名稱、方法名、行號的資訊,是和可執行檔的16進位函數地址對應的,通過分析崩潰的.Crash檔案可以準確知道具體的崩潰資訊。
我們每次Archive一個包之後,都會隨之產生一個dSYM檔案。每次發布一個版本,我們都需要備份這個檔案,以方便以後的調試。進行崩潰資訊符號化的時候,必須使用當前應用打包的電腦所產生的dSYM檔案,其他電腦產生的檔案可能會導致分析不準確的問題。
Archive
當程式崩潰的時候,我們可以獲得到崩潰的錯誤堆棧,但是這個錯誤堆棧都是0x開頭的16進位地址,需要我們使用Xcode內建的symbolicatecrash工具來將.Crash和.dSYM檔案進行符號化,就可以得到詳細崩潰的資訊。
崩潰分析
命令列解析Crash檔案
通過Mac內建的命令列工具解析Crash檔案需要具備三個檔案
我在解析崩潰資訊的時候,首先在案頭上建立一個Crash檔案夾,然後將.Crash、.dSYM、symbolicatecrash放在這個檔案夾中,這樣進入這個檔案夾下,直接一行命令就解決了。
symbolicatecrash我們可以在下面路徑下可以找到,我用的是Xcode7,其他版本Xcode路徑不一樣,請自行Google。
| 1 |
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash |
然後Window->Organizer->Archives中,選中archive的版本右擊,選擇Show in Finder就可以擷取dSYM檔案了。
dSYM檔案
將.Crash、.dSYM、symbolicatecrash三個檔案都放在我們在案頭建立的Crash檔案夾中。
Crash檔案夾
開啟命令列工具,進入崩潰檔案夾中
cd /Users/username/Desktop/崩潰檔案夾
使用命令解析Crash檔案
./symbolicatecrash ./*.crash ./*.app.dSYM > symbol.crash
如果上面命令不成功,使用命令檢查一下環境變數
xcode-select -print-path
返回結果:
/Applications/Xcode.app/Contents/Developer/
如果不是上面的結果,需要使用下面命令設定一下匯出的環境變數,然後重複上面解析的操作。
export DEVELOPER_DIR=/Applications/XCode.app/Contents/Developer
解析完成後會產生一個新的.Crash檔案,這個檔案中就是崩潰詳細資料。圖中紅色標註的部分就是我們代碼崩潰的部分。
解析完成的結果
注意,以下情況不會有崩潰資訊產生:
通過Xcode查看裝置崩潰資訊
除了上面的系統分析工具來進行分析,如果是我們自己直接使用手機串連崩潰或者崩潰之後串連手機,選擇window-> devices -> 選擇自己的手機 -> view device logs 就可以查看我們的崩潰資訊了。
view device logs
只要手機上的應用是這台電腦安裝打包的,這樣的崩潰資訊系統已經為我們符號化好了,我們只需要進去之後等一會就行(不要相信這裡面的進度重新整理,並不準確),如果還是沒有符號化完畢 ,我們選擇檔案,然後右擊選擇Re-Sysbomlicate就可以。
如果是使用其他電腦進行的打包,我們可以在這裡面將Crash檔案匯出,自己通過命令列的方式進行解析。
使用第三方崩潰分析工具
現在有很多第三方工具都可以進行崩潰統計分析,使用比較多的是友盟崩潰統計,友盟崩潰統計被整合在友盟SDK中,具體用法直接看官方文檔是最好的方法,下面列出友盟崩潰統計文檔地址。
友盟崩潰統計官方文檔
在這裡我並不推薦友盟這個第三方,而是推薦一個更好用的第三方—bugHD。這個第三方和友盟的最大區別就是可以直接將崩潰資訊分析結合dSYM分析好,在web網頁上展現出來,而且還可以統計崩潰數、崩潰裝置、系統版本等。
下面是我公司使用bugHD統計的一些崩潰情況
bugHD
在bugHD伺服器已經幫我們使用dSYM將崩潰符號化完成。我們可以通過點擊某條崩潰,查看詳細崩潰堆棧,以及崩潰裝置分布和系統分布。
詳細分布
蘋果內建崩潰統計工具
蘋果在Xcode中為我們整合了崩潰統計功能,在Window->Organizer->Crashes中可以看到
Crashes
蘋果內建的崩潰統計工具並不推薦用,如果想要使用這個功能,需要使用者在iPhone中進行設定
設定->隱私->診斷與用量->診斷與用量資料(iOS8一下在通用中設定)
選擇自動發送,並與開發人員共用即可
第三方工具惡意覆蓋
崩潰收集統計函數應該只進行一次調用,如果用第三方的話也最好只用一個第三方,這樣我們擷取崩潰統計資訊的途徑也是唯一的。
第三方統計工具並不是用的越多越好,使用多個崩潰收集第三方會導致NSSetUncaughtExceptionHandler()函數指標的惡意覆蓋,導致有些第三方不能收到崩潰資訊。
現在很多第三方崩潰收集工具為了確保自己能最大可能的收集到崩潰資訊,會對NSSetUncaughtExceptionHandler()函數指標的惡意覆蓋。因為這個函數是將函數地址當做參數傳遞,所以只要重複調用就會被覆蓋,這樣就不能保證崩潰收集的穩定性。
我們解析崩潰資訊時,看到崩潰堆棧只有main.m檔案中的崩潰,並且可以確定不是因為main.m檔案中的bug導致的崩潰,就基本可以確定是NSSetUncaughtExceptionHandler()函數指標被惡意覆蓋。
被惡意覆蓋的崩潰堆棧
相關:1.symbolicatecrash 在什麼位置在xocde編譯app的時候會同時產生一個以dsym作為尾碼的檔案,這個檔案會記錄app的crash log,需要通過symbolicatecrash來查看,但是這個工具在xccode4.3的時候改變了存放的位置。 1.給xcode打一個補丁: 命令列運行 /usr/bin/xcode-select -print-path 如果輸出"/Developer"或者其他非"/Applications/Xcode.app/Contents/Developer/"的內容,運行下面的命令:sudo /usr/bin/xcode-select -switch /Applications/Xcode.app/Contents/Developer/ 2.尋找symbolicatecrash:find /Applications/Xcode.app -name symbolicatecrash -type f擷取路徑,我的是Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/symbolicatecrash 在執行symbolicatecrash之前先切換到他的目錄下:cd Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework/Versions/A/Resources/ 4.3之前1.直接find /Developer -name symbolicatecrash -type f 2.切換到目錄下,之後:./symbolicatecrash /somePath/MyCrashLogFile.crash /somePath/MyAppName.app.dSYM
連結:
iOS崩潰調試的使用和技巧總結
symbolicatecrash 在什麼位置
iOS崩潰調試的使用和技巧總結