博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
adb bugreport 原理
阅读量:4147 次
发布时间:2019-05-25

本文共 10654 字,大约阅读时间需要 35 分钟。

0.文章学习

1.使用场景

使用 adb bugreport 可以导出功耗分析所需文件,然后通过 进行更加详细的分析

adb bugreport > Bugreport.zipadb bugreport > Bugreport.txt

adb bugreport - return all information from the device that should be included in a bug report.

" bugreport [PATH]\n"    "     write bugreport to given PATH [default=bugreport.zip];\n"    "     if PATH is a directory, the bug report is saved in that directory.\n"    "     devices that don't support zipped bug reports output to stdout.\n"

这里主要想知道 bugreport 的数据从哪里导出

2. bugreport 数据来源

2.1 adb bugreport 命令下发的接收点

system/core/adb/commandline.cpp

命令行接收事件查看

#include "bugreport.h"int adb_commandline(int argc, const char** argv) {    ...    } else if (!strcmp(argv[0], "bugreport")) {    Bugreport bugreport;    return bugreport.DoIt(argc, argv);    ....

2.2 bugreport.DoIt(argc, argv)

system/core/adb/bugreport.cpp

int Bugreport::DoIt(int argc, const char** argv) {    ...    return SendShellCommand(bugz_command, false, &bugz_callback);}

2.3 命令下发执行文件

对应系统目录下的可执行文件

/system/bin # ls -al

-rwxr-xr-x  1 root   shell      10264 2018-05-31 15:18 bugreport-rwxr-xr-x  1 root   shell      10264 2018-05-31 15:18 bugreportz

frameworks\native\cmds\bugreport\bugreport.cpp

2.4 读取bugreport信息

其实bugreport就是 dumpstate,具体文件在手机系统目录 system/bin/dumpstate,dumpstate是可执行文件

  • cmd 窗口
Sufadi:/system/bin # ls dumpstate -allls dumpstate -all-rwxr-xr-x 1 root shell 207136 2018-05-31 15:18 dumpstate
  • 具体源码
// This program will trigger the dumpstate service to start a call to// dumpstate, then connect to the dumpstate local client to read the// output. All of the dumpstate output is written to stdout, including// any errors encountered while reading/writing the output.int main() {  ...  // Start the dumpstate service. 启动 dumpstate service  // 其实bugreport就是 dumpstate   property_set("ctl.start", "dumpstate");  ...  while (1) {    ...    char buffer[65536];    ssize_t bytes_read = TEMP_FAILURE_RETRY(read(s, buffer, sizeof(buffer)));    do {      bytes_written = TEMP_FAILURE_RETRY(write(STDOUT_FILENO,                                               buffer + bytes_read - bytes_to_send,                                               bytes_to_send));      if (bytes_written == -1) {        printf("Failed to write data to stdout: read %zd, trying to send %zd (%s)\n",               bytes_read, bytes_to_send, strerror(errno));        return 1;      }      bytes_to_send -= bytes_written;    } while (bytes_written != 0 && bytes_to_send > 0);  }  close(s);  return 0;}

2.5 dumpstate 的实现及其数据来源

frameworks\native\cmds\dumpstate\dumpstate.cpp

  • 1.系统属性
  • 2./proc和/sys节点文件
  • 3.执行shell命令获得相关输出
  • 4.logcat输出
  • 5.Android Framework Services信息基本使用dumpsys命令通过binder调用服务中的dump函数获得信息
static void dumpstate() {    DurationReporter duration_reporter("DUMPSTATE");    dump_dev_files("TRUSTY VERSION", "/sys/bus/platform/drivers/trusty", "trusty_version");    RunCommand("UPTIME", {
"uptime"}); DumpBlockStatFiles(); dump_emmc_ecsd("/d/mmc0/mmc0:0001/ext_csd"); DumpFile("MEMORY INFO", "/proc/meminfo"); RunCommand("CPU INFO", {
"top", "-b", "-n", "1", "-H", "-s", "6", "-o", "pid,tid,user,pr,ni,%cpu,s,virt,res,pcy,cmd,name"}); RunCommand("PROCRANK", {
"procrank"}, AS_ROOT_20); DumpFile("VIRTUAL MEMORY STATS", "/proc/vmstat"); DumpFile("VMALLOC INFO", "/proc/vmallocinfo"); DumpFile("SLAB INFO", "/proc/slabinfo"); DumpFile("ZONEINFO", "/proc/zoneinfo"); DumpFile("PAGETYPEINFO", "/proc/pagetypeinfo"); DumpFile("BUDDYINFO", "/proc/buddyinfo"); DumpFile("FRAGMENTATION INFO", "/d/extfrag/unusable_index"); DumpFile("KERNEL WAKE SOURCES", "/d/wakeup_sources"); DumpFile("KERNEL CPUFREQ", "/sys/devices/system/cpu/cpu0/cpufreq/stats/time_in_state"); DumpFile("KERNEL SYNC", "/d/sync"); RunCommand("PROCESSES AND THREADS", {
"ps", "-A", "-T", "-Z", "-O", "pri,nice,rtprio,sched,pcy"}); RunCommand("LIBRANK", {
"librank"}, CommandOptions::AS_ROOT); if (ds.IsZipping()) { RunCommand( "HARDWARE HALS", {
"lshal", std::string("--debug=") + kLsHalDebugPath}, CommandOptions::AS_ROOT); ds.AddZipEntry("lshal-debug.txt", kLsHalDebugPath); unlink(kLsHalDebugPath.c_str()); } else { RunCommand( "HARDWARE HALS", {
"lshal", "--debug"}, CommandOptions::AS_ROOT); } RunCommand("PRINTENV", {
"printenv"}); RunCommand("NETSTAT", {
"netstat", "-nW"}); struct stat s; if (stat("/proc/modules", &s) != 0) { MYLOGD("Skipping 'lsmod' because /proc/modules does not exist\n"); } else { RunCommand("LSMOD", {
"lsmod"}); } do_dmesg(); RunCommand("LIST OF OPEN FILES", {
"lsof"}, CommandOptions::AS_ROOT); for_each_pid(do_showmap, "SMAPS OF ALL PROCESSES"); for_each_tid(show_wchan, "BLOCKED PROCESS WAIT-CHANNELS"); for_each_pid(show_showtime, "PROCESS TIMES (pid cmd user system iowait+percentage)"); /* Dump Bluetooth HCI logs */ ds.AddDir("/data/misc/bluetooth/logs", true); if (!ds.do_early_screenshot_) { MYLOGI("taking late screenshot\n"); ds.TakeScreenshot(); } DoLogcat(); AddAnrTraceFiles(); // NOTE: tombstones are always added as separate entries in the zip archive // and are not interspersed with the main report. const bool tombstones_dumped = AddDumps(tombstone_data->begin(), tombstone_data->end(), "TOMBSTONE", true /* add_to_zip */); if (!tombstones_dumped) { printf("*** NO TOMBSTONES to dump in %s\n\n", TOMBSTONE_DIR.c_str()); } DumpPacketStats(); DoKmsg(); DumpIpAddrAndRules(); dump_route_tables(); RunCommand("ARP CACHE", {
"ip", "-4", "neigh", "show"}); RunCommand("IPv6 ND CACHE", {
"ip", "-6", "neigh", "show"}); RunCommand("MULTICAST ADDRESSES", {
"ip", "maddr"}); RunDumpsys("NETWORK DIAGNOSTICS", {
"connectivity", "--diag"}, CommandOptions::WithTimeout(10).Build()); RunCommand("SYSTEM PROPERTIES", {
"getprop"}); RunCommand("VOLD DUMP", {
"vdc", "dump"}); RunCommand("SECURE CONTAINERS", {
"vdc", "asec", "list"}); RunCommand("STORAGED TASKIOINFO", {
"storaged", "-u"}, CommandOptions::WithTimeout(10).Build()); RunCommand("FILESYSTEMS & FREE SPACE", {
"df"}); RunCommand("LAST RADIO LOG", {
"parse_radio_log", "/proc/last_radio_log"}); printf("------ BACKLIGHTS ------\n"); printf("LCD brightness="); DumpFile("", "/sys/class/leds/lcd-backlight/brightness"); printf("Button brightness="); DumpFile("", "/sys/class/leds/button-backlight/brightness"); printf("Keyboard brightness="); DumpFile("", "/sys/class/leds/keyboard-backlight/brightness"); printf("ALS mode="); DumpFile("", "/sys/class/leds/lcd-backlight/als"); printf("LCD driver registers:\n"); DumpFile("", "/sys/class/leds/lcd-backlight/registers"); printf("\n"); /* Binder state is expensive to look at as it uses a lot of memory. */ DumpFile("BINDER FAILED TRANSACTION LOG", "/sys/kernel/debug/binder/failed_transaction_log"); DumpFile("BINDER TRANSACTION LOG", "/sys/kernel/debug/binder/transaction_log"); DumpFile("BINDER TRANSACTIONS", "/sys/kernel/debug/binder/transactions"); DumpFile("BINDER STATS", "/sys/kernel/debug/binder/stats"); DumpFile("BINDER STATE", "/sys/kernel/debug/binder/state"); ds.DumpstateBoard(); /* Migrate the ril_dumpstate to a device specific dumpstate? */ int rilDumpstateTimeout = android::base::GetIntProperty("ril.dumpstate.timeout", 0); if (rilDumpstateTimeout > 0) { // su does not exist on user builds, so try running without it. // This way any implementations of vril-dump that do not require // root can run on user builds. CommandOptions::CommandOptionsBuilder options = CommandOptions::WithTimeout(rilDumpstateTimeout); if (!PropertiesHelper::IsUserBuild()) { options.AsRoot(); } RunCommand("DUMP VENDOR RIL LOGS", {
"vril-dump"}, options.Build()); } printf("========================================================\n"); printf("== Android Framework Services\n"); printf("========================================================\n"); RunDumpsys("DUMPSYS", {
"--skip", "meminfo", "cpuinfo"}, CommandOptions::WithTimeout(90).Build(), 10); printf("========================================================\n"); printf("== Checkins\n"); printf("========================================================\n"); RunDumpsys("CHECKIN BATTERYSTATS", {
"batterystats", "-c"}); RunDumpsys("CHECKIN MEMINFO", {
"meminfo", "--checkin"}); RunDumpsys("CHECKIN NETSTATS", {
"netstats", "--checkin"}); RunDumpsys("CHECKIN PROCSTATS", {
"procstats", "-c"}); RunDumpsys("CHECKIN USAGESTATS", {
"usagestats", "-c"}); RunDumpsys("CHECKIN PACKAGE", {
"package", "--checkin"}); printf("========================================================\n"); printf("== Running Application Activities\n"); printf("========================================================\n"); RunDumpsys("APP ACTIVITIES", {
"activity", "-v", "all"}); printf("========================================================\n"); printf("== Running Application Services\n"); printf("========================================================\n"); RunDumpsys("APP SERVICES", {
"activity", "service", "all"}); printf("========================================================\n"); printf("== Running Application Providers\n"); printf("========================================================\n"); RunDumpsys("APP PROVIDERS", {
"activity", "provider", "all"}); printf("========================================================\n"); printf("== Dropbox crashes\n"); printf("========================================================\n"); RunDumpsys("DROPBOX SYSTEM SERVER CRASHES", {
"dropbox", "-p", "system_server_crash"}); RunDumpsys("DROPBOX SYSTEM APP CRASHES", {
"dropbox", "-p", "system_app_crash"}); printf("========================================================\n"); printf("== Final progress (pid %d): %d/%d (estimated %d)\n", ds.pid_, ds.progress_->Get(), ds.progress_->GetMax(), ds.progress_->GetInitialMax()); printf("========================================================\n"); printf("== dumpstate: done (id %d)\n", ds.id_); printf("========================================================\n");}

上述例如

- 查看电池信息
RunDumpsys(“CHECKIN BATTERYSTATS”, {“batterystats”, “-c”});

  • 查看kernal的唤醒源
    DumpFile(“KERNEL WAKE SOURCES”, “/d/wakeup_sources”);

3. bugreport 数据展示

从bugreport导出手机数据,通过battery-historian解析原始数据进行多维度分析功耗异常

Bugreport

你可能感兴趣的文章
OpenCV gpu模块样例注释:video_reader.cpp
查看>>
就在昨天,全球 42 亿 IPv4 地址宣告耗尽!
查看>>
Mysql复制表以及复制数据库
查看>>
Linux分区方案
查看>>
如何使用 systemd 中的定时器
查看>>
git命令速查表
查看>>
linux进程监控和自动重启的简单实现
查看>>
OpenFeign学习(三):OpenFeign配置生成代理对象
查看>>
OpenFeign学习(四):OpenFeign的方法同步请求执行
查看>>
OpenFeign学习(六):OpenFign进行表单提交参数或传输文件
查看>>
Ribbon 学习(二):Spring Cloud Ribbon 加载配置原理
查看>>
Ribbon 学习(三):RestTemplate 请求负载流程解析
查看>>
深入理解HashMap
查看>>
XML生成(一):DOM生成XML
查看>>
XML生成(三):JDOM生成
查看>>
Ubuntu Could not open lock file /var/lib/dpkg/lock - open (13:Permission denied)
查看>>
collect2: ld returned 1 exit status
查看>>
C#入门
查看>>
C#中ColorDialog需点两次确定才会退出的问题
查看>>
数据库
查看>>