Android dumpsys介绍

03-20 1176阅读

文章目录

  • 一、需求
  • 二、环境
  • 三、相关概念
    • 3.1 dumpsys
    • 3.2 Binder
    • 3.3 管道
    • 四、dumpsys指令的使用
      • 4.1 dumpsys使用
      • 4.2 dumpsys指令语法
      • 五、详细设计
        • 5.1 dumpsys流程图
        • 5.2 dumpsys查看电池信息
          • 5.2.1 dumpsys battery指令
          • 5.2.2 service->dump打印函数
          • 5.3 dumpsys源码分析
            • 5.3.1 dumpsys服务编译
            • 5.3.2 dumpsys入口函数
            • 5.3.3 dumpsys服务打印
              • 5.3.3.1 dumpsys解析参数
              • 5.3.3.2 skippedServices列表构造
              • 5.3.3.3 获取支持服务列表
              • 5.3.3.4 打印支持服务列表
              • 5.3.3.5 打印目标服务
              • 六、dumpsys的应用
                • 6.1 dumpsys常用指令
                • 七、参考资料

                  一、需求

                  1. 了解dumpsys原理,助于我们进一步了解Android系统的设计
                  2. 帮助我们分析问题,定位系统状态
                  3. 设计新功能的需要

                  二、环境

                  1. 版本:Android 12
                  2. 平台:SL8541E SPRD

                  三、相关概念

                  3.1 dumpsys

                          dumpsys 是一种在 Android 设备上运行的工具,可提供有关系统服务的信息。可以使用 Android 调试桥 (adb) 从命令行调用 dumpsys,获取在连接的设备上运行的所有系统服务的诊断输出。

                  3.2 Binder

                          Binder是Android提供的一套进程间相互通信框架。用来实现多进程间发送消息,同步和共享内存。

                  Android dumpsys介绍

                  3.3 管道

                          管道是一种IPC通信方式,分为有名管道和无名管道,无论是有名管道还是无名管道其原理都是在内核开辟一块缓存空间,这段缓存空间的操作是通过文件读写方式进行的。

                  有名管道与无名管道:

                          有名管道: 有名管道的通信可以通过管道名进行通信,进程间不需要有关系。

                          无名管道: 无名管道就是匿名管道,匿名管道通信的进程必须是父子进程。

                  管道为分半双工和全双工:

                          半双工: 半双工管道是单向通信,进程1只能向管道写数据,进程2只能从管道读取数据。只有一个代表读或者写的FD(文件描述符)。

                          全双工: 全双工管道是双向通信,有两个文件描述符,代表读和写。

                  Android dumpsys介绍

                  四、dumpsys指令的使用

                  4.1 dumpsys使用

                  如下为执行"adb shell dumpsys"指令,控制台打印的内容,其使用如下:

                  dumpsys执行

                  4.2 dumpsys指令语法

                  (1)使用 dumpsys 的一般语法如下:

                  adb shell dumpsys [-t timeout] [--help | -l | --skip services | service [arguments] | -c | -h]
                  

                  (2)如需获取所连接设备的所有系统服务的诊断输出,请运行 adb shell dumpsys。不过,这样输出的信息比您通常想要的信息多得多。若要使输出更加可控,您可以通过在命令中添加相应服务来指定要检查的服务。例如,下面的命令会提供输入组件(如触摸屏或内置键盘)的系统数据:

                  adb shell dumpsys input
                  

                  (3)如需查看可与 dumpsys 配合使用的系统服务的完整列表,请使用以下命令:

                  adb shell dumpsys -l
                  

                  (4)命令行选项如下:

                  选项说明
                  -t timeout指定超时期限(秒)。如果未指定,默认值为 10 秒。
                  –help输出 dumpsys 工具的帮助文本。
                  -l输出可与 dumpsys 配合使用的系统服务的完整列表。
                  –skip services指定您不希望包含在输出中的 services。
                  service [arguments]指定您希望输出的 service。某些服务可能允许您传递可选 arguments。如需了解这些可选参数,请将 -h 选项与服务一起传递:
                  adb shell dumpsys procstats -h
                  -c指定某些服务时,附加此选项能以计算机可读的格式输出数据。
                  -h对于某些服务,附加此选项可查看该服务的帮助文本和其他选项。

                  五、详细设计

                  5.1 dumpsys流程图

                  Android dumpsys介绍

                  5.2 dumpsys查看电池信息

                  5.2.1 dumpsys battery指令

                  Android dumpsys介绍

                  5.2.2 service->dump打印函数

                  @frameworks\base\services\core\java\com\android\server\BatteryService.java
                  private final class BinderService extends Binder {
                      @Override protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
                          if (!DumpUtils.checkDumpPermission(mContext, TAG, pw)) return;
                              if (args.length > 0 && "--proto".equals(args[0])) {
                                  dumpProto(fd);
                              } else {
                                  dumpInternal(fd, pw, args);
                              }
                          }
                      ...
                  }
                  private void dumpInternal(FileDescriptor fd, PrintWriter pw, String[] args) {
                      synchronized (mLock) {
                          if (args == null || args.length == 0 || "-a".equals(args[0])) {
                              pw.println("Current Battery Service state:");
                              if (mUpdatesStopped) {
                                  pw.println("  (UPDATES STOPPED -- use 'reset' to restart)");
                              }
                              pw.println("  AC powered: " + mHealthInfo.chargerAcOnline);
                              pw.println("  USB powered: " + mHealthInfo.chargerUsbOnline);
                              pw.println("  Wireless powered: " + mHealthInfo.chargerWirelessOnline);
                              pw.println("  Max charging current: " + mHealthInfo.maxChargingCurrent);
                              pw.println("  Max charging voltage: " + mHealthInfo.maxChargingVoltage);
                              pw.println("  Charge counter: " + mHealthInfo.batteryChargeCounter);
                              pw.println("  status: " + mHealthInfo.batteryStatus);
                              pw.println("  health: " + mHealthInfo.batteryHealth);
                              pw.println("  present: " + mHealthInfo.batteryPresent);
                              pw.println("  level: " + mHealthInfo.batteryLevel);
                              pw.println("  scale: " + BATTERY_SCALE);
                              pw.println("  voltage: " + mHealthInfo.batteryVoltage);
                              pw.println("  temperature: " + mHealthInfo.batteryTemperature);
                              pw.println("  technology: " + mHealthInfo.batteryTechnology);
                          } else {
                              Shell shell = new Shell();
                              shell.exec(mBinderService, null, fd, null, args, null, new ResultReceiver(null));
                          }
                      }
                  }
                  

                  5.3 dumpsys源码分析

                  5.3.1 dumpsys服务编译

                          dumpsys是个二进制可执行程序,其通过bp进行编译,并最终打包到system分区(system/bin/dumpsys)。

                  @frameworks\native\cmds\dumpsys\android.bp
                  cc_binary {
                      name: "dumpsys",
                      defaults: ["dumpsys_defaults"],
                      srcs: [
                          "main.cpp",
                      ],
                  }
                  

                  5.3.2 dumpsys入口函数

                          我们通过执行adb指令 “adb shell dumpsys”,可以启动dumpsys服务,其对应的入口函数如下:

                  @frameworks\native\cmds\dumpsys\main.cpp
                  int main(int argc, char* const argv[]) {
                      signal(SIGPIPE, SIG_IGN);
                      sp sm = defaultServiceManager();//获取SM对象
                      fflush(stdout);
                      if (sm == nullptr) {
                          ALOGE("Unable to get default service manager!");
                          std::cerr 
                      ...
                      while (1) {
                          ...
                          c = getopt_long(argc, argv, "+t:T:l", longOptions, &optionIndex);//获取指令参数
                          ...
                          switch (c) {
                          case 0://长参数
                              if (!strcmp(longOptions[optionIndex].name, "skip")) {//跳过某些服务打印
                                  skipServices = true;
                              } else if (!strcmp(longOptions[optionIndex].name, "proto")) {
                                  asProto = true;
                              } else if (!strcmp(longOptions[optionIndex].name, "help")) {//指令帮助
                                  usage();
                                  return 0;
                              } else if (!strcmp(longOptions[optionIndex].name, "priority")) {
                                  ...
                              } else if (!strcmp(longOptions[optionIndex].name, "pid")) {//只显示服务的pid
                                  type = Type::PID;
                              } else if (!strcmp(longOptions[optionIndex].name, "thread")) {//仅显示进程使用情况
                                  type = Type::THREAD;
                              }
                              break;
                          case 't'://超时时间设置,默认10秒
                              ...
                              break;
                          case 'T'://超时时间设置,默认10秒
                              ...
                              break;
                          case 'l'://显示支持的服务列表
                              showListOnly = true;
                              break;
                          default://其他参数
                              fprintf(stderr, "\n");
                              usage();
                              return -1;
                          }
                      }
                      ...
                  }
                  
                  h55.3.3.2 skippedServices列表构造/h5 p        dumpsys内部构造了skippedServices集合,用于记录需要忽略的服务。/p pre class="brush:python;toolbar:false"@frameworks\native\cmds\dumpsys\dumpsys.cpp int Dumpsys::main(int argc, char* const argv[]) { ... for (int i = optind; i 1 || showListOnly) { // first print a list of the current services std::cout sp//创建管道,用于读取service端数据 ... } ... redirectFd_ = unique_fd(sfd[0]); unique_fd remote_end(sfd[1]); sfd[0] = sfd[1] = -1; // dump blocks until completion, so spawn a thread.. activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable {//创建线程 status_t err = 0; switch (type) { case Type::DUMP: err = service-dump(remote_end.get(), args);//调用dump函数 break; ... } ... }); return OK; }
VPS购买请点击我

文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。

目录[+]