1. 程式人生 > >當app出現線上奔潰,該如何辦?

當app出現線上奔潰,該如何辦?

cati 存儲 phone logs 全部 警告 device 自己的 調用

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出現線上奔潰,該如何辦?