8.1、概述及應用場景
安卓bugreport主要用於分析手機的狀態。其包含:main log,kernel log,cpuinfo等信息。bugreport是一個可執行文件,編譯后的路徑為system/bin/bugreport,源碼位於framework/native/cmds/bugreport。其核心在於啟動dumpsys服務。bugreport同dumpstate服務建立socket通信(建立連接20次,超時3min無數據等容錯)。連接之后,將接收到的數據定向到文件中。
因此我們看到的bugreport數據均來自dumpstate。
- print_header(string):讀取了需要顯示的prop如fingerprint,build type等等。
- dump_systrace():將systemtrace.txt文件加入到bugreport.zip中。
- dump_raft():將raftlog.txt文件加入到bugreport.zip中。
8.2、bugreport流程梳理
- 提高dumpsate進程的優先級,防止被OOM Killer殺死
- 參數解析(adb shell dumpstate -h)
- (打開vibrator,在執行bugreport時,先震動一下提醒)
- 通過dump_traces()來完成收集虛擬機和native進程的stack traces
- 通過get_tombstone_fds來獲取tombstone文件描述符
- 開始執行切換到非root用戶和組,在這之前的執行都處於root權限
- 執行dumpstate()主要過程都在這里執行
- 再次通過震動以提醒dump操作執行完成
- 發送廣播,告知ActivityManager已完成bugreport操作
8.3、小結
bugreport通過socket與dumpstate服務建立通信,在dumpstate.cpp中的dumpstate()方法完成核心功能。分別輸出:current log、 last log、 vm trace、 dumpsys、 system info
其詳細內容主要有:系統build及運行時長等信息、 內存和CPU進程的信息、 kernel log、 system log、 radio log、 event log等等。實際來說,bugreport中顯示的大部分為信息,都有對應的命令方式可以獲取。bugreport只是作為一個在不打擾用戶的前提下執行的一套命令集合。
8.4、bugreport的解析方法
有以下兩種辦法可以更加方便地解析bugreport。
- 推薦使用Sony開源的一款checkbugreport的工具來解析成一個html文件。
安裝java環境
在cmd 窗口中執行 java -jar {path}/checkbugreport.jar {path}/bugreport.log
解析好的文件在bugreport log文件夾中會生成 bugreport_out的文件夾,打開index.html即可以查看。
- 推薦google的開源工具:https://github.com/google/battery-historian。
這個工具需要FQ,借助google解析,本地搭建環境也不復雜,看情況有時間出教程。
8.5、Dumpsys sensorservices解析
作為一個sensor工程師,這是一個必備的技能。
Dumpsys sensorservices用於查看當前設備sensor的使用情況。可通過_adb shell dumpsys sensorservice_獲取。開頭提供了Active sensors的信息:
Active sensors:
BMI120 Accelerometer (handle=0x00000001, connections=3)
stk3x3x alsprx (handle=0x00000008, connections=1)
Step Counter (handle=0x00000015, connections=3)
Step Detector -Wakeup Secondary (handle=0x00000021, connections=1)
Socket Buffer size = 984 events
WakeLock Status: not held
Mode : NORMAL
其中有加速度計、光線距離感應器、步進計數器、步進探測器等。
8 active connections
Connection Number: 0
Operating Mode: NORMAL //對應到前面的Mode
com.tencent.mm.plugin.sport.model.g | WakeLockRefCount 0 | uid 10161 | cache size 0 | max cache size 0
//這里只能顯示uid,並不能顯示pid,通過uid,可以在/data/system/package.list看到對應的package name
Step Counter 0x00000015 | status: active | pending flush events 0
Connection Number: 1
Operating Mode: NORMAL
android.view.OrientationEventListener | WakeLockRefCount 0 | uid 10160 | cache size 0 | max cache size 0
BMI120 Accelerometer 0x00000001 | status: active | pending flush events 0
Connection Number: 2
Operating Mode: NORMAL
有些情況下,兩個APP的uid是一樣的,這時就需要pid來進行區分,想要看到app運行的pid信息,需要在sensorservice中增加一些code才可以。打開_frameworks\native\services\sensorservice\SensorService.h_
增加如下內容:
uid_t mUid;
pid_t mPid; //Debug
在_frameworks\native\services\sensorservice\SensorService.cpp_文件中添加:
SensorService::SensorEventConnection::SensorEventConnection(
mChannel = new BitTube(mService->mSocketBufferSize);
mPid = IPCThreadState::self()->getCallingPid(); //Debug
...)
SensorService::SensorEventConnection::Dump(String8& result){
result.appendFormat("\t WakeLockRefCount %d pid %d | uid %d | ..., mPid, mUid");
}
增加上面的內容以后就可以在sensorservice中打印出pid信息。
Previous Registrations:
14:50:16 + 0x00000001 pid= 3580 uid=10160 package=android.view.OrientationEventListener samplingPeriod=200000us batchingPeriod=0us
14:50:16 + 0x00000001 pid= 3580 uid=10160 package=android.view.OrientationEventListener samplingPeriod=200000us batchingPeriod=0us
14:50:16 - 0x00000001 pid= 3580 uid=10160 package=android.view.OrientationEventListener
14:50:16 + 0x00000001 pid= 3580 uid=10160 package=android.view.OrientationEventListener samplingPeriod=200000us batchingPeriod=0us
14:48:27 + 0x00000015 pid= 5314 uid=10161 package=com.tencent.mm.plugin.sport.model.g samplingPeriod=600000us batchingPeriod=0us
14:48:21 + 0x00000015 pid= 3390 uid=10161 package=com.tencent.mm.plugin.sport.model.c samplingPeriod=600000us batchingPeriod=0us
14:48:18 + 0x00000021 pid= 4975 uid= 1000 package=com.xiaomi.joyose.stepsprovider.StepsService samplingPeriod=200000us batchingPeriod=300000000us
14:48:18 - 0x00000007 pid= 2480 uid= 1000 package=miui.util.ProximitySensorWrapper
14:48:17 + 0x00000015 pid= 3251 uid=10160 package=com.tencent.mobileqq.msf.core.ad samplingPeriod=200000us batchingPeriod=360000000us
14:48:14 + 0x00000001 pid= 2288 uid= 1000 package=com.android.server.policy.WindowOrientationListener samplingPeriod=66667us batchingPeriod=100000us
14:48:14 + 0x00000007 pid= 2480 uid= 1000 package=miui.util.ProximitySensorWrapper samplingPeriod=0us batchingPeriod=0us
14:48:11 + 0x00000008 pid= 2288 uid= 1000 package=hidl_client_pid_880 samplingPeriod=500000us batchingPeriod=0us
--------- 0.035s was the duration of dumpsys sensorservice, ending at: 2019-02-11 14:58:37
最后會打印出一些最近的注冊信息,可以清晰地看到相關服務的啟動時間、pid、uid、采樣時間以及批處理時間。整個dumpsys sensorservices也就宣告結束。
