1. 程式人生 > >Android如何分析排查ANR

Android如何分析排查ANR

在Android開發中,當程式發生異常時會丟擲異常資訊,先說下三種常見型別:

  • 列表內容KeyDispatchTimeout(谷歌default 5s,MTK平臺上是8s) –主要型別
    按鍵或觸控事件在特定時間內無響應
  • BroadcastTimeout(10s)
    BroadcastReceiver在特定時間內無法處理完成
  • ServiceTimeout(20s) –小概率型別
    Service在特定的時間內無法處理完成

一些典型的ANR 問題場景

1)最常見錯誤,UI執行緒等待其它執行緒釋放某個鎖,導致UI執行緒無法處理使用者輸入;

2)遊戲中每幀動畫都進行了比較耗時的大量計算,導致CPU忙不過來;

3)Web應用中,網路狀態不穩定,而介面在等待網路資料;

4)UI執行緒中進行了一些磁碟IO(包括資料庫、SD卡等等)的操作,在個別裝置上因為硬體損壞等原因阻塞住了;

5)手機被其他App佔用著CPU,自己獲取不到足夠的CPU 時間片,純屬誤傷。

排查分析的思路:

1、通過ANR 日誌定位問題

當ANR發生時,我們往往通過Logcat和traces檔案(目錄/data/anr/)的相關資訊輸出去定位問題。主要包含以下幾方面:

1)基本資訊,包括程序名、程序號、包名、系統build號、ANR 型別等等;

2)CPU使用資訊,包括活躍程序的CPU 平均佔用率、IO情況等等;

3)執行緒堆疊資訊,所屬程序包括髮生ANR的程序、其父程序、最近有活動的3個程序等等。

1.1首先通過Log來獲取異常資訊

android系統會自動幫我們生成一個log日誌輸出檔案,在data/system/dropbox/下,真機測試需要root許可權,模擬器在DDMS下可以檢視。

用這種方法,出現問題,根本不需要斷點除錯 , 直接定位到問題,屢試不爽 。
從LOG可以看出ANR的型別,CPU的使用情況,

一般在如下幾種情況會產生log 。

1,程式異常退出 , uncaused exception
2,程式強制關閉 ,Force Closed (簡稱FC)
3,程式無響應 , Application No Response (簡稱ANR) , 順便,一般主執行緒超過5秒麼有處理就會ANR

步驟:

1.開啟log檔案 , 由於是ANR錯誤,因此搜尋”ANR ” , 為何要加空格呢,你加上和去掉比較一下就知道了 。 可以遮蔽掉不少儲存到anr.log檔案的無效資訊

定位到關鍵的事件資訊如下:

01-15 16:49:02.433 E/ActivityManager( 2466): ANR in com.android.mms (com.android.mms/.ui.SlideshowActivity)
01-15 16:49:02.433 E/ActivityManager( 2466): Reason: keyDispatchingTimedOut
01-15 16:49:02.433 E/ActivityManager( 2466): Load: 0.6 / 0.61 / 0.42
01-15 16:49:02.433 E/ActivityManager( 2466): CPU usage from 1337225ms to 57ms ago:
01-15 16:49:02.433 E/ActivityManager( 2466):   sensorserver_ya: 8% = 0% user + 8% kernel / faults: 40 minor
......
01-15 16:49:02.433 E/ActivityManager( 2466):  -com.android.mms: 0% = 0% user + 0% kernel
01-15 16:49:02.433 E/ActivityManager( 2466):  -flush-179:8: 0% = 0% user + 0% kernel
01-15 16:49:02.433 E/ActivityManager( 2466): TOTAL: 25% = 10% user + 14% kernel + 0% iowait + 0% irq + 0% softirq
01-15 16:49:02.436 I/        ( 2466): dumpmesg > "/data/log/dumpstate_app_anr.log"

我們用自然語言來描述一下日誌,

01-15 16:49:02.433 E/ActivityManager( 2466): ANR in com.android.mms (com.android.mms/.ui.SlideshowActivity)

翻譯:在16:49分2秒433毫秒的時候 ActivityManager (程序號為2466) 發生瞭如下錯誤:com.android.mms包下面的.ui.SlideshowActivity 無響應 。

01-15 16:49:02.433 E/ActivityManager( 2466): Reason: keyDispatchingTimedOut

翻譯:原因 , keyDispatchingTimeOut - 按鍵分配超時

01-15 16:49:02.433 E/ActivityManager( 2466): Load: 0.6 / 0.61 / 0.42

翻譯:5分鐘,10分鐘,15分鐘內的平均負載分別為:0.6 , 0.61 , 0.42

我們大概知道問題是什麼了,問題是在點選按鈕某時候可能處理不過來按鈕事件,導致超時無響應 。但我們不能準確的知道到底問題在哪兒 , 只是猜測 ,比如這個應用程式中,多個IO操作的地方都在主執行緒中,可能引起問題,但不好判斷到底是哪個 ,所以我們目前掌握的資訊還不夠 。
於是我們再分析虛擬機器資訊 ,搜尋“Dalvik Thread”關鍵詞,快速定位到本應用程式的虛擬機器資訊日誌

1.2通過分析trace檔案得到ANR資訊(真機匯出,模擬機在DDMS下檢視)

如果ANR發生,對應的應用會收到SIGQUIT異常終止訊號,dalvik虛擬機器就會自動在/data/anr/目錄下生成trace.txt檔案,將異常資訊寫入到traces檔案中,系統會記錄異常的位置、CPU和記憶體當時的使用情況,通過檢視日誌基本就能判斷問題所在。

接下來用adb shell命令匯出該檔案,通過shell命令就可以了。

adb pull /data/anr/traces.txt d:/ =》意思是將手機上的traces.txt匯出到電腦的d目錄下
或者
1、adb shell
2、cat /data/anr/xxx >/mnt/sdcard/yy/zz.txt
3、exit
4、adb pull /mnt/sdcard/yy/zz.txt d: ,即可將檔案匯出到了d盤。

在發生ANR時,

步驟:
1. 找到ANR關鍵字(大寫匹配)
2. 向上查詢timeout關鍵字,這個時候能找到ANR的原因,如: Application do too much work in main thread 等。
3. 檢視trace 檔案找出出現的最終原因。

測試過程發現ANR的現狀

1、在平常測試中,ANR基本測試不到,因為ANR基本發生在垃圾裝置中,弱網路,頻繁操作。
2、問題不必現,即使看到了問題,定位麻煩:要去data/anr.txt 檔案裡面查詢。必須root,沒有對應關係,分析複雜,匯出檔案就必須依賴手機零距離。
由於anr問題不必現,因此引入以下ANR檢測工具,當anr問題出現時,自動dump手機中的日誌資訊如trace檔案、堆疊資訊
基本原理

檢測到UI主執行緒卡頓時間超過設定的時間,如4s,即dump trace檔案以及堆疊資訊,同時丟擲異常,收集資訊,根據這些檔案資訊即可定位到發生anr的原因

1.3在原始碼中插入ANR檢測工具(BlockCanary、StrictMode)
1.4使用第三方SDK輸出Crach資訊到後臺伺服器:

如騰訊bugly 和umeng