1. 程式人生 > >Swift app中的Crash捕獲與處理

Swift app中的Crash捕獲與處理

數據 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捕獲與處理