Exploring the Android system: dumpsys command to obtain system service details

Estimated read time 8 min read

dumpsys is an executable file in the Android system . Its main function is to dump some information of the current Android system, such as Activity, package, etc. It is a very effective tool for analyzing Android device problems, checking running status, usage, etc. You can obtain various system information and status, such as the PSS value of the process, and analyze the RAM usage of the process.

The syntax of dumpsys provides a flexible way to obtain and analyze information about various services in the Android system. The basic syntax structure is as follows:

adb shell dumpsys [-t timeout] [--help | -l | --skipservices | service[arguments] | -c | -h]
  • [-t timeout]: Optional parameter used to specify the timeout for command execution (in seconds). The default is 10 seconds.
  • [--help | -l | --skipservices | service[arguments] | -c | -h]: Command line options for customizing the output and behavior of dumpsys.
    • --help: Print instructions for using dumpsys.
    • -l: List all system services supported by dumpsys.
    • --skipservices: Specify the service list that does not need to be printed.
    • service[arguments]:Specify the specific service to query and its optional parameters. Details of a specific service can be obtained by specifying the service name.
    • -c: Output information in a machine-friendly format (usually key-value pairs), which may be useful for automated script parsing, but may not be very user-friendly for human reading.
    • -h: Used after the specified service to print what parameters the service supports or how to use the service.
% adb shell dumpsys -l
Currently running services:
DisplayFeatureControl
DockObserver
MiuiBackup
MiuiCarService
MiuiInit
MiuiWifiService
ProcessManager
SchedBoostService
SlaveWifiService
SurfaceFlinger
accessibility
account
activity
activity_task
adb

If dumpsys does not add any parameters, it will output detailed information about all system services, and the output content is very large. When actually solving specific problems, we usually only focus on the output of some specific system services. We only need to use the service name as a parameter of the dumpsys command to output only the information of the specific service. For example, if you want to output disk usage statistics, you can use the system service name diskstats as a parameter.

 % adb shell dumpsys diskstats
Latency: 1ms [512B Data Write]
Recent Disk Write Speed (kB/s) = 45546
Data-Free: 53243072K / 113006560K total = 47% free
Cache-Free: 53243072K / 113006560K total = 47% free
System-Free: 0K / 5192648K total = 0% free
File-based Encryption: true
App Size: 16656406016
App Data Size: 33915740160
App Cache Size: 2662189568
Photos Size: 77041664
Videos Size: 17559552
Audio Size: 38887424
Downloads Size: 0
System Size: 128000000000
Other Size: 9238536192

working principle

dumpsys is based on the service management and inter-process communication mechanism of the Android system. Obtain information about all registered services in the system by calling the ServiceManager service at the bottom of the Android system. ServiceManager is a core service in the Android system, responsible for managing all services in the system and providing a unified registration, discovery and communication mechanism.

When dumpsys is called, it interacts with ServiceManager through the Binder inter-process communication (IPC) framework. Binder is a set of inter-process communication framework provided by Android, allowing efficient communication and data exchange between different processes. Through Binder, dumpsys can request ServiceManager to provide a list of all registered services in the current system, as well as detailed information about each service.

ServiceManager will respond to dumpsys’ request and return status information of all services in the system. Including service name, status, runtime statistics, etc. After dumpsys receives this information, it will parse and organize it and display it in a readable way.

int main(int argc, charconst argv[])
{
    ...
    // 1. 首先获取 servicemanager
    sp<IServiceManager> sm = defaultServiceManager();
    ...
    // 2. 进行命令行参数解析
    bool showListOnly = false;
    if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
        // 2.1 当参数仅为 "-l" 时,设置只罗列出所有的服务名
        showListOnly = true;
    }
    if ((argc == 1) || showListOnly) {
        // 2.2 当不带任何参数时,则附加 "-a" 参数,表示输出所有系统服务信息
        services = sm->listServices();
        services.sort(sort_func);
        args.add(String16("-a"));
    } else {
        // 2.3 当带了一个参数时,表示仅输出指定的系统服务信息
        services.add(String16(argv[1]));
        for (int i=2; i<argc; i++) {
            args.add(String16(argv[i]));
        }
    }

    // 3. 罗列出services这个数组中的服务名称,到这一步为止,都还只是在dumpsys本身的逻辑中转悠
    const size_t N = services.size();
    if (N > 1) {
        aout << "Currently running services:" << endl;    
        for (size_t i=0; i<N; i++) {
            sp<IBinder> service = sm->checkService(services[i]);
            if (service != NULL) {
                aout << "  " << services[i] << endl;
            }
        }
    }
    if (showListOnly) {
        return 0;
    }

    // 4. 输出services这个数组中所包含系统服务的详细信息
    for (size_t i=0; i<N; i++) {
        sp<IBinder> service = sm->checkService(services[i]);
        if (service != NULL) {
            ...
            // 4.1 调用service的dump方法,来输出service的具体信息
            int err = service->dump(STDOUT_FILENO, args);
            ...
        }
        ...
    }
    return 0;
}
  1. Get servicemanager, all system services will be registered with servicemanager
  2. Parse command line parameters and set the subsequent execution instruction sequence according to different parameters.
  3. Simply list the system service names that need to be output.
  4. Call the dump() method of a specific system service to complete the output of system service details.

Taking the above adb shell dumpsys diskstats command as an example, the dump() method is finally called to complete the output:

protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    // 1. 权限检查
    mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);

    // 2. 生成一个大小为512B的临时文件
    byte[] junk = new byte[512];
    for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
    File tmp = new File(Environment.getDataDirectory(), "system/perftest.tmp");

    // 3. 将512B的临时文件写入磁盘,目的是为了快速的测试写磁盘的延迟
    long before = SystemClock.uptimeMillis();
    ...
    fos = new FileOutputStream(tmp);
    fos.write(junk);
    ...
    long after = SystemClock.uptimeMillis();
    ...
    pw.print("Latency: ");
    pw.print(after - before);
    pw.println("ms [512B Data Write]");
    ...
    // 4. 输出Data, Cache和System这几个分区的磁盘使用信息
    reportFreeSpace(Environment.getDataDirectory(), "Data", pw);
    reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw);
    reportFreeSpace(new File("/system"), "System", pw);
    ....
}

You May Also Like

More From Author

+ There are no comments

Add yours