dumpsys 使用与源码

1-dumpsys 使用
命令格式:
adb shell dumpsys activity [options] [WHAT]

option 参数:

options 含义
-a 包括所有可用 Servier 状态
-c 包括 Client 状态,即 App 端情况
-p PACKAGE 限定输出指定包名

WHAT 参数:

WHAT 解释 对应源码
a[ctivities] activity状态 dumpActivitiesLocked()
b[roadcasts] [PACKAGE_NAME] broadcast状态 dumpBroadcastsLocked()
s[ervices] [COMP_SPEC …] service状态 newServiceDumperLocked().dumpLocked
prov[iders] [COMP_SPEC …] content provider状态 dumpProvidersLocked()
p[rocesses] [PACKAGE_NAME] 进程状态 dumpProcessesLocked()
o[om] 内存管理 dumpOomLocked()
i[ntents] [PACKAGE_NAME] pending intent状态 dumpPendingIntentsLocked()
r[ecents] 最近activity dumpRecentsLocked()
perm[issions] URI授权情况 dumpPermissionsLocked()
all 所有activities信息 dumpActivity()
top 顶部activity信息 dumpActivity()
package package相关信息 dump()

重要的服务:

服务名 类名 功能
activity ActivityManagerService AMS相关信息
package PackageManagerService PMS相关信息
window WindowManagerService WMS相关信息
input InputManagerService IMS相关信息
power PowerManagerService PMS相关信息
batterystats BatterystatsService 电池统计信息
battery BatteryService 电池信息
alarm AlarmManagerService 闹钟信息
dropbox DropboxManagerService 调试相关
procstats ProcessStatsService 进程统计
cpuinfo CpuBinder CPU
meminfo MemBinder 内存
gfxinfo GraphicsBinder 图像
dbinfo DbBinder 数据库

其他重要服务:

服务名 功能
SurfaceFlinger 图像相关
appops app使用情况
permission 权限
processinfo 进程服务
batteryproperties 电池相关
audio 查看声音信息
netstats 查看网络统计信息
diskstats 查看空间free状态
jobscheduler 查看任务计划
wifi wifi信息
diskstats 磁盘情况
usagestats 用户使用情况
devicestoragemonitor 设备信息

指令:

adb shell dumpsys activity
adb shell dumpsys activity intents    //主要输出 PendingIntentRecord
adb shell dumpsys activity broadcasts 
adb shell dumpsys activity providers
adb shell dumpsys activity permissions
adb shell dumpsys activity services
adb shell dumpsys activity recents
adb shell dumpsys activity activities
adb shell dumpsys activity processes
adb shell dumpsys activity top
adb shell dumpsys activity oom //查看进程状态
adb shell dumpsys activity activities   //输出任务栈
adb shell dumpsys meminfo  //查询内存情况
adb shell dumpsys package  
adb shell dumpsys window //查询WMS服务相关信息
adb shell dumpsys cpuinfo //查询CPU情况
adb shell dumpsys -l   //可以dump的 service
adb shell service list    //可以看到所有的service
//重要的指令
adb shell dumpsys activity top |grep mResumed=true -C 10
adb shell dumpsys activity s com.example.helloworld  //查询某个App所有service状态
adb shell dumpsys activity a com.example.helloworld  //查询某个App的所有Activity状态
adb shell dumpsys activity p com.example.helloworld  //查询某个App的进程状态

举个例子:
adb shell dumpsys activity p com.example.helloworld

ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)
  All known processes:
  *APP* UID 10070 ProcessRecord{3ab962e 8727:com.example.helloworld/u0a70}
    user #0 uid=10070 gids={50070, 20070, 9997}
    requiredAbi=arm64-v8a instructionSet=null
    dir=/data/app/com.example.helloworld-MVDRQ1v8KVafsDRbTEH_HA==/base.apk publicDir=/data/app/com.example.helloworld-MVDRQ1v8KVafsDRbTEH_HA==/base.apk data=/data/user/0/com.example.helloworld
    packageList={com.example.helloworld}
    compat={560dpi}
    thread=android.app.IApplicationThread$Stub$Proxy@cb84feb
    pid=8727 starting=false
    lastActivityTime=-56s649ms lastPssTime=-38s529ms nextPssTime=+1m21s429ms
    adjSeq=18860 lruSeq=0 lastPss=75MB lastSwapPss=0.00 lastCachedPss=31MB lastCachedSwapPss=0.00
    cached=false empty=false
    oom: max=1001 curRaw=0 setRaw=0 cur=0 set=0
    curSchedGroup=2 setSchedGroup=2 systemNoUi=false trimMemoryLevel=0
    curProcState=2 repProcState=2 pssProcState=2 setProcState=2 lastStateTime=-2h44m52s244ms
    hasShownUi=true pendingUiClean=true hasAboveClient=false treatLikeActivity=false
    reportedInteraction=true time=-56s650ms
    hasClientActivities=false foregroundActivities=true (rep=true)
    lastRequestedGc=-2h47m10s361ms lastLowMemory=-2h47m10s361ms reportLowMemory=false
    Activities:
      - ActivityRecord{a06206e u0 com.example.helloworld/.MainActivity t13}
    Connected Providers:
      - 922a9b5/com.android.providers.settings/.SettingsProvider->8727:com.example.helloworld/u0a70 s1/1 u0/0 +2h47m10s322ms

  UID states:
    UID u0a70: UidRecord{d6525cf u0a70 TOP  procs:1 seq(0,0,0)}

  UID validation:
    UID u0a70: UidRecord{d95d148 u0a70 TOP  procs:0 seq(0,0,0)}

  Process LRU list (sorted by oom_adj, 35 total, non-act at 3, non-svc at 3):
    Proc # 0: fore  T/A/TOP  trm: 0 8727:com.example.helloworld/u0a70 (top-activity)

  PID mappings:
    PID #8727: ProcessRecord{3ab962e 8727:com.example.helloworld/u0a70}
  mPreviousProcessVisibleTime: +6h44m56s167ms
  mConfigWillChange: false
  mDeviceIdleWhitelist=[1000, 1001, 2000, 10008, 10013]
  mDeviceIdleTempWhitelist=[]
  mVrController=[VrState=0x0,VrRenderThreadTid=0]

对应的source code
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java

void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
            int opti, boolean dumpAll, String dumpPackage) {
        boolean needSep = false;
        boolean printedAnything = false;
        int numPers = 0;
        //在dumpsys 指令中,这个数据被dump 出来了
        pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");

        if (dumpAll) {
            final int NP = mProcessNames.getMap().size();
            for (int ip=0; ip procs = mProcessNames.getMap().valueAt(ip);
                final int NA = procs.size();
                for (int ia=0; ia

2-dumpsys 源码介绍
frameworks/native/cmds/dumpsys/Android.bp

cc_defaults {
    name: "dumpsys_defaults",
    cflags: [
        "-Wall",
        "-Werror",
    ],
    srcs: [
        "dumpsys.cpp",
    ],

    shared_libs: [
        "libbase",
        "libutils",
        "liblog",
        "libbinder",
    ],
    clang: true,
}

//
// Static library used in testing and executable
//

cc_library_static {
    name: "libdumpsys",
    defaults: ["dumpsys_defaults"],
    export_include_dirs: ["."],
}

//
// Executable
//
cc_binary {
    name: "dumpsys",
    defaults: ["dumpsys_defaults"],
    srcs: [
        "main.cpp",
    ],
}
subdirs = ["tests"]

main.cpp 可以看出main 就是defaultServiceManager, 根据参数获取对应的service

int main(int argc, char* const argv[]) {
    signal(SIGPIPE, SIG_IGN);
    sp sm = defaultServiceManager();
    fflush(stdout);
    if (sm == nullptr) {
        ALOGE("Unable to get default service manager!");
        aerr << "dumpsys: Unable to get default service manager!" << endl;
        return 20;
    }

    Dumpsys dumpsys(sm.get());
    return dumpsys.main(argc, argv);
}

frameworks/native/cmds/dumpsys/dumpsys.cpp

static int sort_func(const String16* lhs, const String16* rhs)
{
    return lhs->compare(*rhs);
}
//使用说明
static void usage() {
    fprintf(stderr,
        "usage: dumpsys\n"
            "         To dump all services.\n"
            "or:\n"
            "       dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
            "         --help: shows this help\n"
            "         -l: only list services, do not dump them\n"
            "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
            "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
            "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
}

static bool IsSkipped(const Vector& skipped, const String16& service) {
    for (const auto& candidate : skipped) {
        if (candidate == service) {
            return true;
        }
    }
    return false;
}

int Dumpsys::main(int argc, char* const argv[]) {
    Vector services;
    Vector args;
    Vector skippedServices;
    bool showListOnly = false;
    bool skipServices = false;
    int timeoutArg = 10;
    static struct option longOptions[] = {
        {"skip", no_argument, 0,  0 },
        {"help", no_argument, 0,  0 },
        {     0,           0, 0,  0 }
    };

    // Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
    // happens on test cases).
    optind = 1;
    while (1) {
        int c;
        int optionIndex = 0;

        c = getopt_long(argc, argv, "+t:l", longOptions, &optionIndex);

        if (c == -1) {
            break;
        }

        switch (c) {
        case 0:
            if (!strcmp(longOptions[optionIndex].name, "skip")) {
                skipServices = true;   //携带的参数skip
            } else if (!strcmp(longOptions[optionIndex].name, "help")) {
                usage();
                return 0;
            }
            break;

        case 't':
            {
                char *endptr;
                timeoutArg = strtol(optarg, &endptr, 10);
                if (*endptr != '\0' || timeoutArg <= 0) {
                    fprintf(stderr, "Error: invalid timeout number: '%s'\n", optarg);
                    return -1;
                }
            }
            break;

        case 'l':
            showListOnly = true;
            break;

        default:
            fprintf(stderr, "\n");
            usage();
            return -1;
        }
    }

    for (int i = optind; i < argc; i++) {
        if (skipServices) {
            skippedServices.add(String16(argv[i]));
        } else {
            if (i == optind) {
                services.add(String16(argv[i]));   //把service 添加services
            } else {
                args.add(String16(argv[i]));
            }
        }
    }

    if ((skipServices && skippedServices.empty()) ||
            (showListOnly && (!services.empty() || !skippedServices.empty()))) {
        usage();
        return -1;
    }

    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 service = sm_->checkService(services[i]);

            if (service != nullptr) {
                bool skipped = IsSkipped(skippedServices, services[i]);
                aout << "  " << services[i] << (skipped ? " (skipped)" : "") << endl;
            }
        }
    }

    if (showListOnly) {
        return 0;
    }

    for (size_t i = 0; i < N; i++) {
        String16 service_name = std::move(services[i]);
        if (IsSkipped(skippedServices, service_name)) continue;

        sp service = sm_->checkService(service_name);
        if (service != nullptr) {
            int sfd[2];

            if (pipe(sfd) != 0) {
                aerr << "Failed to create pipe to dump service info for " << service_name
                     << ": " << strerror(errno) << endl;
                continue;
            }

            unique_fd local_end(sfd[0]);
            unique_fd remote_end(sfd[1]);
            sfd[0] = sfd[1] = -1;

            if (N > 1) {
                aout << "------------------------------------------------------------"
                        "-------------------" << endl;
                aout << "DUMP OF SERVICE " << service_name << ":" << endl;
            }

            // dump blocks until completion, so spawn a thread..
            std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable {
                //对每个service dump , dump 信息全部都在里面
                int err = service->dump(remote_end.get(), args);

                // It'd be nice to be able to close the remote end of the socketpair before the dump
                // call returns, to terminate our reads if the other end closes their copy of the
                // file descriptor, but then hangs for some reason. There doesn't seem to be a good
                // way to do this, though.
                remote_end.reset();

                if (err != 0) {
                    aerr << "Error dumping service info: (" << strerror(err) << ") " << service_name
                         << endl;
                }
            });
        ........
    }
    return 0;
}

这个指令比较简单,就是getservice dump 信息,关键是要对service 比较熟悉

1-main.cpp中defaultServiceManager()函数用来获取ServiceManager对象,并传递到dumpsys.cpp中。
2-sm_->listServices(),获取系统中所有向ServiceManager中注册过的服务。
3-如果命令加入了--skip SERVICES.则加入到skippedServices中,过滤service_name,最后sm_->checkService(service_name)用来获取指定的service。
4-最后调用service->dump()。这是最核心的方法,主要是service去掉用各自的dump()方法来获取相关dump信息。

REF:
https://developer.android.com/studio/command-line/dumpsys
https://www.jianshu.com/p/436f3c592974

你可能感兴趣的:(dumpsys 使用与源码)