1.Android框架介紹
android分為四個層,從高層到低層分別是應用程序層、應用程序框架層、系統運行庫層和linux核心層。
藍色的代表java程序,黃色的代碼為運行JAVA程序而實現的虛擬機,綠色部分為C/C++語言編寫的程序庫,紅色的代碼內核(linux內核+driver)。在Application Framework之下,由C/C++的程序庫組成,通過JNI完成從JAVA到C的調用。android Oreo增加了HIDL層封裝HAL.具體就不介紹,網上有很多介紹,本文主要介紹anr問題分享。
2.LOG信息分析
以下log 命令相互配合使用,在出現問題時候,使用相關命令查看,幫助自己定位到問題點。
2.1 常用adb命令
adb命令是android非常好用的工具,以提供強大的特性,可以使用Android Shell命令行參數連接到手機本身,并發送基本的 shell 命令。源碼位于system/core/adb。
查詢模擬器/設備實例:
adb devices 得到一系列相關聯的模擬器/設備給特定的模擬器/設備實例發送命令
adb -s如果有多個模擬器/設備實例在運行,在發布adb命令時需要指定一個目標實例。 使用-s 選項的命令。
adb -s emulator-5556 install helloWorld.apk
安裝軟件:
adb install從你的開發電腦上復制一個應用程序,并且將其安裝在一個模擬器/設備實例。
從模擬器/設備中拷入或拷出文件
使用adb pull ,push 命令將文件復制到一個模擬器/設備實例的數據文件或是從數據文件中復制
從模擬器或者設備中復制文件或目錄,使用(如下命令):
adb pull <remote> ?<local>
將文件或目錄復制到模擬器或者設備,使用(如下命令)?
?adb push <local> <remote>
2.2Logcat命令列表
2.3 BugReport
Android為了方便開發人員分析整個系統平臺和某個app在運行一段時間之內的所有信息,專門開發了bugreport工具。記錄android啟動過程的log,以及啟動后的系統狀態,包括進程列表,內存信息,VM信息等等到.它的信息很全,可以得到很多有用信息.這個工具使用起來十分簡單,只要在終端執行(linux或者win):
adb bugreport > bugreport.txt
2.4 結構分析
MEMORY INFO? 獲取該log: 執行cat /proc/meminfo 查看系統內存使用狀態
CPU INFO? 獲取該log :執行top -n 1 -d 1 -m 30 -t ?查看系統CPU使用狀態
PROCRANK? 獲取該log:執行procrank 后輸出的結果,查看一些內存使用狀態
VIRTUAL MEMORY STATS? 獲取該log:執行vmstat 查看虛擬內存分配情況
vmalloc申請的內存則位于vmalloc_start~vmalloc_end之間,與物理地址沒有簡單的轉換關系,雖然在邏輯上 它們也是連續的,但是在物理上它們不要求連續。
VMALLOC INFO? 獲取該log:執行cat /proc/vmallocinfo
2.3 在程序中輸出的Log,用于分析系統的當前狀態
KERNEL LOG? 獲取該log:執行/system/bin/dmesg 顯示Android內核輸出的Log
VM TRACES? 獲取該log:讀取文件/data/anr/traces.txt? 因為每個程序都是在各自的VM中運行的,這個Log是現實各自VM的一些traces
EVENT LOG TAGS? 獲取該log:讀取文件/etc/event-log-tags? EVENT LOG? 獲取該log:執行logcat -b events -v time -d *:v 輸出一些Event的log
RADIO LOG? 獲取該log:執行logcat -b radio -v time -d *:v? 顯示一些無線設備的鏈接狀態,如GSM,PHONE,STK(Satellite Tool Kit)...
NETWORK STATE? 獲取該log:執行/system/bin/netcfg (得到網絡鏈接狀態) 獲取該log:讀取文件/proc/net/route (得到路由狀態) 顯示網絡鏈接和路由
KERNEL WAKELOCKS? 獲取該log:讀取文件/proc/wakelocks? 內核對一些程式和服務喚醒和休眠的一些記錄
2.5 Dumpsys信息
我們知道Android使用ServiceManager服務進程來管理系統所有的服務,在系統啟動時,每個服務必須注冊到ServiceManager進程中,那如何查看系統運行了那些服務呢?ServiceManager提供了listServices接口來羅列出系統注冊的所有服務。
查看系統當前服務運行的狀態值,結合系統源碼分析,可以對比正常狀態和非正常狀態時的相關信息,非常有用。
android提供了dumpsys工具來dump出所有的服務信息,通過以下命令可以查看系統注冊的所有服務:
dumpsys [Option]
? ? ? ? ? ? ? ?SurfaceFlineer 顯示信息
? ? ? ? ? ? ? ?meminfo 顯示內存信息
? ? ? ? ? ? ? ?cpuinfo 顯示CPU信息
? ? ? ? ? ? ? ?batteryinfo 顯示電量信息
? ? ? ? ? ? ? ?account 顯示accounts信息
? ? ? ? ? ? ? ?activity 顯示所有的activities的信息
? ? ? ? ? ? ? window 顯示鍵盤,窗口和它們的關系
? ? ? ? ? ? ? ?wifi 顯示wifi信息
當然,上面只是常用的命令,使用如下命令查看哪些service信息可以dump
$ adb shell dumpsys | grep DUMP
3.內核出錯分析
當內核出錯時(比如訪問非法地址)打印出來的信息被稱為Oops信息。
Oops信息包含以下幾部分內容:
(1)一段文本描述信息。?比如類似“Unable to handle kernel NULL pointer dereference at virtual address 00000000"的信息,他說明了發生的是哪類錯誤。
(2)Oops信息的序號。?比如是第幾次等。這些信息與下面類似,括號內的數據表示序號。
Internal error: Oops: 806 [#1]
3)內核中加載的模塊名稱,也可能沒有,以下面字樣開頭。
Modules linked in:? xxx
(4)發生錯誤的CPU的序號,對于單處理器系統,序號為0,如:
CPU: 0 Not tainted (2.6.22.6 #36)
(5)發生錯誤時CPU的各個寄存器值。
(6)當前進程的名字及進程ID,比如:
Process swapper (pid: 1, stack limit = 0xc0480258)
這并不是說發生錯誤的是這個進程,而是表示發生錯誤時,當前進程是它。錯誤可能發生在內核代碼、驅動程序,也可能就是這個進程的錯誤
4.Traces分析
出現ANR的原因
默認情況下,在android中Activity的最長執行時間是5秒,BroadcastReceiver的最長執行時間則是10秒.超出就會提示應用程序無響應(ANR:Application Not Responding)對話框。
三種常見類型:
1:KeyDispatchTimeout(5 seconds) --主要類型按鍵或觸摸事件在特定時間內無響應
2:BroadcastTimeout(10 seconds)? --BroadcastReceiver在特定時間內無法處理完成
3:ServiceTimeout(20 seconds) -- 系統線程死鎖或死循環,概率很小
Service在特定的時間內無法處理完成,出現Application Not Responding的提示后,系統會將日志LOG,寫到到data\anr\traces.txt文件。
1)一段文本描述信息,比如:
- waiting to lock <0x06607874> (a com.android.server.am.ActivityManagerService) held by thread 79
他說明了被那個線程卡主,也表明本身又被tid=79的線程卡主
2)? - waiting to lock <0x11a1593f> (a java.util.HashMap) held by thread 26
3)? 繼續找tid=26