android系统调试工具之dumpsys

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
cpuinfoCPUdumpsys 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函数。

更多精彩内容请关注“麻辣软硬件”公众号,谢谢!
在这里插入图片描述

  • 2
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值