1.概述

dumpsys是android系统里面的一个可执行文件。从名字来看,其主要作用是将当前android系统的一些信息dump出来,如activity、package等。
dumpsys是一个分析android设备问题、查看运行状态、使用情况等十分有效的工具。
查看所有支持的dump选项:

dumpsys -l #此命令会将当前android系统所有运行的服务全部列出来

比如我们想获取当前系统所有的activity信息:

dumpsys activity

2.dumpsys命令

前面介绍了android系统服务查询,dumpsys命令的基本组成方式为: dumpsys serviceName,同时你还可以加如下参数:

-h:对于大多数的服务,可以添加-h看到文本的帮助
-c:对于一些服务,可以添加-c查看数据会更友好 exsample: “dumpsys meminfo -h”: meminfo dump options: [-a] [-d] [-c] [-s] [–oom] [process] -a: include all
available information for each process. -d: include dalvik details.
-c: dump in a compact machine-parseable representation. -s: dump only summary of application memory usage. -S: dump also SwapPss.
–oom: only show processes organized by oom adj. --local: only collect details locally, don’t call process. --package: interpret
process arg as package, dumping all
processes that have loaded that package. --checkin: dump data for a checkin If [process] is specified it can be the name
or pid of a specific process to dump.

下面我们看一些常见的命令组合。

package信息查询

命令格式:dumpsys package [-h] [-f] [–checkin] [cmd] …

参数 说明
-h 打印帮助信息
-f 打印intent filter的信息
–checkin 打印出已经登记的库、系统功能、安装包
cmd 子命令(可以在-h帮助文档中查看有哪些子命令)

子命令举例:

dumpsys package prov[iders]: 获取content providers
dumpsys package p[ackages]: 获取安装包基本信息 dumpsys package s[hared-user]:获取共享用户ID的应用
dumpsys package m[essages]:打印运行时收集的信息 dumpsys package r[esolvers]:获取intentfilter

activity信息查询

命令格式:dumpsys activity [-a] [-c] [-p PACKAGE] [-h] [WHAT] …

参数 说明
-a 包括所有可用的服务器状态
-c 包括客户端状态
-p 限制输出为给定的包,例如:dumpsys activity -p packageName
-h 打印帮助信息
cmd 子命令(可以在-h帮助文档中查看有哪些子命令)

子命令举例:

dumpsys activity a[ctivities]:activity堆栈状态
dumpsys activity r[recents]:最近activity的状态
dumpsys activity o[om]:oom管理
dumpsys activity top:栈顶的activity
dumpsys activity all:所有的activity

网络信息查询

子命令 说明 命令格式
connectivity 网络连接 dumpsys connectivity
netpolicy 网络策略 dumpsys netpolicy
netstats 网络状态 dumpsys netstats
network_management 网络管理 dumpsys network_management

其他常用服务信息查询

子命令 说明 命令格式
meminfo 内存 dumpsys meminfo
cpuinfo CPU dumpsys cpuinfo
gfxinfo 帧率 dumpsys gfxinfo
display 显示 dumpsys display
power 电源 dumpsys power
batterystats 电池状态 dumpsys batterystats
battery 电池 dumpsys battery
alarm 闹钟 dumpsys alarm
location 位置 dumpsys location
battery 电池 dumpsys battery

3.实现逻辑

dumpsys的源码结构其实很简单,只有一个dumpsys.cpp,源码路径:frameworks/native/cmds/dumpsys/dumpsys.cpp

int main(int argc, char* const argv[])
{
    signal(SIGPIPE, SIG_IGN);
    sp<IServiceManager> sm = defaultServiceManager();//get ServiceManager object
    ...
    Vector<String16> services;
    Vector<String16> args;
    Vector<String16> skippedServices;
    ...
    if (services.empty() || showListOnly) {
        // gets all services
        services = sm->listServices();
        services.sort(sort_func);
        args.add(String16("-a"));
    }
    
    const size_t N = services.size();
    if (N > 1) {
        // first print a list of the current services
        aout << "Currently running services:" << endl;
        for (size_t i=0; i<N; i++) {
            sp<IBinder> service = sm->checkService(services[i]);//获取相应的服务
            ......
        }
    }
    for (size_t i = 0; i < N; i++) {
        ......
        sp<IBinder> service = sm->checkService(service_name);
        if (service != NULL) {
            ......
            // dump blocks until completion, so spawn a thread..
            std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable {
                int err = service->dump(remote_end.get(), args);//调用service相应的dump()方法
            });
            ......
        } 
        ......
    }
    return 0;
}

从代码中可以看出:
先通过defaultServiceManager()函数获得ServiceManager对象;然后通过sm->listServices(),获取系统所有向ServiceManager注册过的服务;接下来根据dumpsys传进来的参数通过函数checkService来找到具体的service, 并执行该service的dump方法,达到dump service的目的。

dumpsys cpuinfo实例

dumpsys的实现其实是根据参数来找到某个具体的服务,然后执行其dump方法。我们熟悉的系统服务有ActivityManagerService、PackageManagerService等,而cpuinfo对应的服务是什么呢?

frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java中有下面这段代码:

public void setSystemProcess() {
        try {
            ......
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(this));
            }
            ......
        } 
        ......
    }

在ActivityManagerservice里,通过ServiceManager添加了一个name的cpuinfo的服务叫CpuBinder,这就是就是cpuinfo对应的服务。我们再来看看CpuBinder:

static class CpuBinder extends Binder {
    ActivityManagerService mActivityManagerService;
    CpuBinder(ActivityManagerService activityManagerService) {
        mActivityManagerService = activityManagerService;
    }

    @Override
    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
        if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
                != PackageManager.PERMISSION_GRANTED) {
            pw.println("Permission Denial: can't dump cpuinfo from from pid="
                    + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
                    + " without permission " + android.Manifest.permission.DUMP);
            return;
        }

        synchronized (mActivityManagerService.mProcessCpuTracker) {
            pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
            pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
                    SystemClock.uptimeMillis()));
        }
    }
}

当我们执行dumpsys cpuinfo的时候,其实最后执行的是ProcessCpuTracker中的printCurrentLoad和printCurrentState方法,cpuinfo是一个非常简单的实例,其他子命令的代码实现也不尽相同,但基本套路都是一样的。

4.总结

dumpsys功能之所以如此强大是因为每个service都实现了dump方法,也就是说dumpsys的实现其实是通过serviceManager拿到对应的service信息,然后执行该service的dump函数。

更多精彩内容请关注“麻辣软硬件”公众号,谢谢!
android系统调试工具之dumpsys

相关文章: