當app出現線上奔潰,該如何辦?
1.如何追蹤app崩潰率,如何解決線上閃退
當iOS設備上的App應用閃退時,操作系統會生成一個crash日誌,保存在設備上。crash日誌上有很多有用的信息,比如每個正在執行線程的完整堆棧跟蹤信息和內存映像,這樣就能夠通過解析這些信息進而定位crash發生時的代碼邏輯,從而找到App閃退的原因。通常來說,crash產生來源於兩種問題:違反iOS系統規則導致的crash和App代碼邏輯BUG導致的crash,下面分別對他們進行分析。
違反iOS系統規則產生crash的三種類型:
(1) 內存報警閃退
當iOS檢測到內存過低時,它的VM系統會發出低內存警告通知,嘗試回收一些內存;如果情況沒有得到足夠的改善,iOS會終止後臺應用以回收更多內存;最後,如果內存還是不足,那麽正在運行的應用可能會被終止掉。在Debug模式下,可以主動將客戶端執行的動作邏輯寫入一個log文件中,這樣程序童鞋可以將內存預警的邏輯寫入該log文件,當發生如下截圖中的內存報警時,就是提醒當前客戶端性能內存吃緊,可以通過Instruments工具中的Allocations 和 Leaks模塊庫來發現內存分配問題和內存泄漏問題。
(2) 響應超時
當應用程序對一些特定的事件(比如啟動、掛起、恢復、結束)響應不及時,蘋果的Watchdog機制會把應用程序幹掉,並生成一份相應的crash日誌。這些事件與下列UIApplicationDelegate方法相對應,當遇到Watchdog日誌時,可以檢查上圖中的幾個方法是否有比較重的阻塞UI的動作。
application:didFinishLaunchingWithOptions: applicationWillResignActive: applicationDidEnterBackground: applicationWillEnterForeground: applicationDidBecomeActive: applicationWillTerminate:
(3) 用戶強制退出
一看到“用戶強制退出”,首先可能想到的雙擊Home鍵,然後關閉應用程序。不過這種場景一般是不會產生crash日誌的,因為雙擊Home鍵後,所有的應用程序都處於後臺狀態,而iOS隨時都有可能關閉後臺進程,當應用阻塞界面並停止響應時這種場景才會產生crash日誌。這裏指的“用戶強制退出”場景,是稍微比較復雜點的操作:先按住電源鍵,直到出現“滑動關機”的界面時,再按住Home鍵,這時候當前應用程序會被終止掉,並且產生一份相應事件的crash日誌。
應用邏輯的Bug
大多數閃退崩潰日誌的產生都是因為應用中的Bug,這種Bug的錯誤種類有很多,比如:
-
SEGV:(Segmentation Violation,段違例),無效內存地址,比如空指針,未初始化指針,棧溢出等;
-
SIGABRT:收到Abort信號,可能自身調用abort()或者收到外部發送過來的信號;
-
SIGBUS:總線錯誤。與SIGSEGV不同的是,SIGSEGV訪問的是無效地址(比如虛存映射不到物理內存),而SIGBUS訪問的是有效地址,但總線訪問異常(比如地址對齊問題);
-
SIGILL:嘗試執行非法的指令,可能不被識別或者沒有權限;
-
SIGFPE:Floating Point Error,數學計算相關問題(可能不限於浮點計算),比如除零操作;
-
SIGPIPE:管道另一端沒有進程接手數據;
常見的崩潰原因基本都是代碼邏輯問題或資源問題,比如數組越界,訪問野指針或者資源不存在,或資源大小寫錯誤等。
crash的收集
如果是在windows上你可以通過itools或pp助手等輔助工具查看系統產生的歷史crash日誌,然後再根據app來查看。如果是在Mac 系統上,只需要打開xcode->windows->devices,選擇device logs進行查看,如下圖,這些crash文件都可以導出來,然後再單獨對這個crash文件做處理分析。
看日誌
市場上已有的商業軟件提供crash收集服務,這些軟件基本都提供了日誌存儲,日誌符號化解析和服務端可視化管理等服務:
-
Crashlytics (www.crashlytics.com)
-
Crittercism (www.crittercism.com)
-
Bugsense (www.bugsense.com)
-
HockeyApp (www.hockeyapp.net)
-
Flurry(www.flurry.com)
開源的軟件也可以拿來收集crash日誌,比如Razor,QuincyKit(git鏈接)等,這些軟件收集crash的原理其實大同小異,都是根據系統產生的crash日誌進行了一次提取或封裝,然後將封裝後的crash文件上傳到對應的服務端進行解析處理。很多商業軟件都采用了Plcrashreporter這個開源工具來上傳和解析crash,比如HockeyApp,Flurry和crittercism等。
crash信息
由於自己的crash信息太長,找了一張示例:
1)crash標識是應用進程產生crash時的一些標識信息,它描述了該crash的唯一標識(E838FEFB-ECF6-498C-8B35-D40F0F9FEAE4),所發生的硬件設備類型(iphone3,1代表iphone4),以及App進程相關的信息等;
2)基本信息描述的是crash發生的時間和系統版本;
3)異常類型描述的是crash發生時拋出的異常類型和錯誤碼;
4)線程回溯描述了crash發生時所有線程的回溯信息,每個線程在每一幀對應的函數調用信息(這裏由於空間限制沒有全部列出);
5)二進制映像是指crash發生時已加載的二進制文件。以上就是一份crash日誌包含的所有信息,接下來就需要根據這些信息去解析定位導致crash發生的代碼邏輯, 這就需要用到符號化解析的過程(洋名叫:symbolication)。
解決線上閃退
首先保證,發布前充分測試。發布後依然有閃退現象,查看崩潰日誌,及時修復並發布。
當app出現線上奔潰,該如何辦?