Swift app中的Crash捕獲與處理
阿新 • • 發佈:2017-07-02
數據 read 代碼 選擇 symbol 系統調用 code 機制 邏輯
1. 為什麽會Crash
常見的Crash原因有:訪問已經被釋放的內存,數組越界,使用!解包值為nil的變量。當遇到這些情況時,說明應用已經遇到了很嚴重的非預期錯誤,無法再繼續運行。操作系統檢測到這些非法操作時會向應用發送對應的信號,而應用對這些信號的默認處理是直接讓應用退出(已信號值作為退出碼)。這樣就出現了我們看到的Crash,閃退。
具體的信號種類和信號機制見Unix Signal
2. 如何捕獲和處理Crash
在swift3.0中,我們可以通過如下調用來註冊對特定信號的處理邏輯。
signal(SIGINT, {s in print(s);})
在處理函數中我們一般做如下操作:
- 獲取調用棧信息
- 相關邏輯處理(比如保存調用棧到文件或數據庫)
- 恢復信號處理函數到默認設置
- 調用exit退出應用
3. 獲取調用棧信息
分析Crash最有價值的信息就是調用棧。在Swift 3.0中我們可以調用Thread.callStackSymbols來獲取Crash的調用棧信息。(以前是通過backtrace和backtrace_symbols系統調用來獲取)
需要說明的是Thread.callStackSymbols返回的調用棧也包含了從crash觸發代碼到調用Thread.callStackSymbols之間的調用棧信息,可根據需要選擇是否去除。
基於以上技術點,我分別基於OC和Swift實現了兩套CrashHandler,以及示例程序。代碼見:https://github.com/lbwxly/CrashHandler
Swift app中的Crash捕獲與處理