blob: ef009da0ed963e15e0581b85a4a1a0fa9b2cd0fa [file] [log] [blame]
Colin Crossf45fa6b2012-03-26 12:38:26 -07001/*
2 * Command that dumps interesting system state to the log.
3 *
4 */
5
6#define LOG_TAG "dumpsys"
7
8#include <utils/Log.h>
9#include <binder/Parcel.h>
10#include <binder/ProcessState.h>
11#include <binder/IServiceManager.h>
Mathias Agopian002e1e52013-05-06 20:20:50 -070012#include <binder/TextOutput.h>
Colin Crossf45fa6b2012-03-26 12:38:26 -070013#include <utils/Vector.h>
14
15#include <getopt.h>
16#include <stdlib.h>
17#include <stdio.h>
18#include <string.h>
19#include <unistd.h>
20#include <sys/time.h>
21
22using namespace android;
23
24static int sort_func(const String16* lhs, const String16* rhs)
25{
26 return lhs->compare(*rhs);
27}
28
Felipe Lemebbfd2b82016-02-03 11:16:27 -080029static void usage() {
30 fprintf(stderr,
31 "usage: dumpsys\n"
32 " To dump all services.\n"
33 "or:\n"
Felipe Leme859aef62016-02-03 12:17:10 -080034 " dumpsys [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
Felipe Lemebbfd2b82016-02-03 11:16:27 -080035 " --help: shows this help\n"
36 " -l: only list services, do not dump them\n"
Felipe Leme859aef62016-02-03 12:17:10 -080037 " --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
38 " SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
39}
40
41bool IsSkipped(const Vector<String16>& skipped, const String16& service) {
42 for (const auto& candidate : skipped) {
43 if (candidate == service) {
44 return true;
45 }
46 }
47 return false;
Felipe Lemebbfd2b82016-02-03 11:16:27 -080048}
49
Colin Crossf45fa6b2012-03-26 12:38:26 -070050int main(int argc, char* const argv[])
51{
JP Abgrall3e03d3f2012-05-11 14:14:09 -070052 signal(SIGPIPE, SIG_IGN);
Colin Crossf45fa6b2012-03-26 12:38:26 -070053 sp<IServiceManager> sm = defaultServiceManager();
54 fflush(stdout);
55 if (sm == NULL) {
Felipe Lemebbfd2b82016-02-03 11:16:27 -080056 ALOGE("Unable to get default service manager!");
Colin Crossf45fa6b2012-03-26 12:38:26 -070057 aerr << "dumpsys: Unable to get default service manager!" << endl;
58 return 20;
59 }
60
61 Vector<String16> services;
62 Vector<String16> args;
Felipe Leme859aef62016-02-03 12:17:10 -080063 Vector<String16> skippedServices;
keunyoungcaad5552013-06-13 15:08:51 -070064 bool showListOnly = false;
Felipe Lemebbfd2b82016-02-03 11:16:27 -080065 if (argc == 2) {
Felipe Leme859aef62016-02-03 12:17:10 -080066 // 1 argument: check for special cases (-l or --help)
Felipe Lemebbfd2b82016-02-03 11:16:27 -080067 if (strcmp(argv[1], "--help") == 0) {
68 usage();
69 return 0;
70 }
71 if (strcmp(argv[1], "-l") == 0) {
72 showListOnly = true;
73 }
keunyoungcaad5552013-06-13 15:08:51 -070074 }
Felipe Leme859aef62016-02-03 12:17:10 -080075 if (argc == 3) {
76 // 2 arguments: check for special cases (--skip SERVICES)
77 if (strcmp(argv[1], "--skip") == 0) {
78 char* token = strtok(argv[2], ",");
79 while (token != NULL) {
80 skippedServices.add(String16(token));
81 token = strtok(NULL, ",");
82 }
83 }
84 }
85 bool dumpAll = argc == 1;
86 if (dumpAll || !skippedServices.empty() || showListOnly) {
87 // gets all services
Colin Crossf45fa6b2012-03-26 12:38:26 -070088 services = sm->listServices();
89 services.sort(sort_func);
90 args.add(String16("-a"));
91 } else {
Felipe Leme859aef62016-02-03 12:17:10 -080092 // gets a specific service:
93 // first check if its name is not a special argument...
94 if (strcmp(argv[1], "--skip") == 0 || strcmp(argv[1], "-l") == 0) {
95 usage();
96 return -1;
97 }
98 // ...then gets its arguments
Colin Crossf45fa6b2012-03-26 12:38:26 -070099 services.add(String16(argv[1]));
100 for (int i=2; i<argc; i++) {
101 args.add(String16(argv[i]));
102 }
103 }
104
105 const size_t N = services.size();
106
107 if (N > 1) {
108 // first print a list of the current services
109 aout << "Currently running services:" << endl;
Felipe Lemebbfd2b82016-02-03 11:16:27 -0800110
Colin Crossf45fa6b2012-03-26 12:38:26 -0700111 for (size_t i=0; i<N; i++) {
112 sp<IBinder> service = sm->checkService(services[i]);
113 if (service != NULL) {
Felipe Leme859aef62016-02-03 12:17:10 -0800114 bool skipped = IsSkipped(skippedServices, services[i]);
115 aout << " " << services[i] << (skipped ? " (skipped)" : "") << endl;
Colin Crossf45fa6b2012-03-26 12:38:26 -0700116 }
117 }
118 }
119
keunyoungcaad5552013-06-13 15:08:51 -0700120 if (showListOnly) {
121 return 0;
122 }
123
Colin Crossf45fa6b2012-03-26 12:38:26 -0700124 for (size_t i=0; i<N; i++) {
Felipe Leme859aef62016-02-03 12:17:10 -0800125 if (IsSkipped(skippedServices, services[i])) continue;
126
Colin Crossf45fa6b2012-03-26 12:38:26 -0700127 sp<IBinder> service = sm->checkService(services[i]);
128 if (service != NULL) {
129 if (N > 1) {
130 aout << "------------------------------------------------------------"
131 "-------------------" << endl;
132 aout << "DUMP OF SERVICE " << services[i] << ":" << endl;
133 }
134 int err = service->dump(STDOUT_FILENO, args);
135 if (err != 0) {
136 aerr << "Error dumping service info: (" << strerror(err)
137 << ") " << services[i] << endl;
138 }
139 } else {
140 aerr << "Can't find service: " << services[i] << endl;
141 }
142 }
143
144 return 0;
145}