Android驱动笔记(8)——bugreport介绍

8.1、概述及应用场景

 安卓bugreport主要用于分析手机的状态。其包含:main log,kernel log,cpuinfo等信息。bugreport是一个可执行文件,编译后的路径为system/bin/bugreport,源码位于framework/native/cmds/bugreport。其核心在于启动dumpsys服务。bugreport同dumpstate服务建立socket通信(建立连接20次,超时3min无数据等容错)。连接之后,将接收到的数据定向到文件中。
  因此我们看到的bugreport数据均来自dumpstate。

  1. print_header(string):读取了需要显示的prop如fingerprint,build type等等。
  2. dump_systrace():将systemtrace.txt文件加入到bugreport.zip中。
  3. dump_raft():将raftlog.txt文件加入到bugreport.zip中。

8.2、bugreport流程梳理

  1. 提高dumpsate进程的优先级,防止被OOM Killer杀死
  2. 参数解析(adb shell dumpstate -h)
  3. (打开vibrator,在执行bugreport时,先震动一下提醒)
  4. 通过dump_traces()来完成收集虚拟机和native进程的stack traces
  5. 通过get_tombstone_fds来获取tombstone文件描述符
  6. 开始执行切换到非root用户和组,在这之前的执行都处于root权限
  7. 执行dumpstate()主要过程都在这里执行
  8. 再次通过震动以提醒dump操作执行完成
  9. 发送广播,告知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。

  1. 推荐使用Sony开源的一款checkbugreport的工具来解析成一个html文件。

安装java环境
在cmd 窗口中执行 java -jar {path}/checkbugreport.jar {path}/bugreport.log
解析好的文件在bugreport log文件夹中会生成 bugreport_out的文件夹,打开index.html即可以查看。

  1. 推荐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也就宣告结束。

posted @ 2020-04-18 22:35  hansenn  阅读(4353)  评论(0编辑  收藏  举报