dumpsys.cpp revision bca287d28450d4cc23382174c86de3c84e6a0b8f
1f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/*
2f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross * Command that dumps interesting system state to the log.
3f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
4f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross */
5f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
6f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#define LOG_TAG "dumpsys"
7f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
84b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <algorithm>
94b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <chrono>
104b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <thread>
114b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
124b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <android-base/file.h>
132f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal#include <android-base/stringprintf.h>
144b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <android-base/unique_fd.h>
154b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <binder/IServiceManager.h>
16f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <binder/Parcel.h>
17f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <binder/ProcessState.h>
18002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <binder/TextOutput.h>
194b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <utils/Log.h>
20f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <utils/Vector.h>
21f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
224b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <fcntl.h>
23f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <getopt.h>
24f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h>
254b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <stdlib.h>
26f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h>
274b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/poll.h>
284b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/socket.h>
29f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h>
304b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/types.h>
314b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <unistd.h>
32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
33f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossusing namespace android;
342f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawalusing android::base::StringPrintf;
354b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gaousing android::base::unique_fd;
364b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gaousing android::base::WriteFully;
37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
38f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic int sort_func(const String16* lhs, const String16* rhs)
39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross{
40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    return lhs->compare(*rhs);
41f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
42f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
43bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Lemestatic void usage() {
44bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme    fprintf(stderr,
45bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        "usage: dumpsys\n"
46bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "         To dump all services.\n"
47bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "or:\n"
488b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            "       dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
49bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "         --help: shows this help\n"
50bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "         -l: only list services, do not dump them\n"
518b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
52859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
53859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
54859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme}
55859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme
56859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Lemebool IsSkipped(const Vector<String16>& skipped, const String16& service) {
57859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    for (const auto& candidate : skipped) {
58859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        if (candidate == service) {
59859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            return true;
60859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        }
61859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    }
62859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    return false;
63bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme}
64bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme
65f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char* const argv[])
66f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross{
673e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall    signal(SIGPIPE, SIG_IGN);
68f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    sp<IServiceManager> sm = defaultServiceManager();
69f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    fflush(stdout);
70f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (sm == NULL) {
71bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        ALOGE("Unable to get default service manager!");
72f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        aerr << "dumpsys: Unable to get default service manager!" << endl;
73f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        return 20;
74f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
75f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
76f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    Vector<String16> services;
77f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    Vector<String16> args;
78859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    Vector<String16> skippedServices;
79caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    bool showListOnly = false;
808b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    bool skipServices = false;
818b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    int timeoutArg = 10;
828b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    static struct option longOptions[] = {
838b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        {"skip", no_argument, 0,  0 },
848b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        {"help", no_argument, 0,  0 },
858b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        {     0,           0, 0,  0 }
868b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    };
878b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
888b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    while (1) {
898b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        int c;
908b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        int optionIndex = 0;
918b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
928b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        c = getopt_long(argc, argv, "+t:l", longOptions, &optionIndex);
938b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
948b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        if (c == -1) {
958b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
96bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        }
978b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
988b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        switch (c) {
998b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        case 0:
1008b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            if (!strcmp(longOptions[optionIndex].name, "skip")) {
1018b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                skipServices = true;
1028b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            } else if (!strcmp(longOptions[optionIndex].name, "help")) {
1038b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                usage();
1048b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                return 0;
1058b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            }
1068b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
1078b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1088b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        case 't':
1098b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            {
1108b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                char *endptr;
1118b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                timeoutArg = strtol(optarg, &endptr, 10);
1128b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                if (*endptr != '\0' || timeoutArg <= 0) {
1138b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                    fprintf(stderr, "Error: invalid timeout number: '%s'\n", optarg);
1148b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                    return -1;
1158b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                }
1168b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            }
1178b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
1188b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1198b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        case 'l':
120bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            showListOnly = true;
1218b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
1228b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1238b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        default:
1248b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            fprintf(stderr, "\n");
1258b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            usage();
1268b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            return -1;
127bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        }
128caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    }
1298b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1308b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    for (int i = optind; i < argc; i++) {
1318b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        if (skipServices) {
1328b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            skippedServices.add(String16(argv[i]));
1338b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        } else {
1348b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            if (i == optind) {
1358b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                services.add(String16(argv[i]));
1368b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            } else {
1378b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                args.add(String16(argv[i]));
138859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            }
139859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        }
140859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    }
1418b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1428b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    if ((skipServices && skippedServices.empty()) ||
1438b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            (showListOnly && (!services.empty() || !skippedServices.empty()))) {
1448b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        usage();
1458b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        return -1;
1468b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    }
1478b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
148159a8323064d8550218bf31465e51cc5a5d14926Thierry Strudel    if (services.empty() || showListOnly) {
149859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        // gets all services
150f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        services = sm->listServices();
151f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        services.sort(sort_func);
152f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        args.add(String16("-a"));
153f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
154f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
155f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    const size_t N = services.size();
156f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
157f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (N > 1) {
158f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        // first print a list of the current services
159f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        aout << "Currently running services:" << endl;
160bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme
161f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        for (size_t i=0; i<N; i++) {
162f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            sp<IBinder> service = sm->checkService(services[i]);
163f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            if (service != NULL) {
164859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme                bool skipped = IsSkipped(skippedServices, services[i]);
165859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme                aout << "  " << services[i] << (skipped ? " (skipped)" : "") << endl;
166f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
167f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
168f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
169f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
170caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    if (showListOnly) {
171caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung        return 0;
172caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    }
173caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung
1744b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao    for (size_t i = 0; i < N; i++) {
1754b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao        String16 service_name = std::move(services[i]);
1764b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao        if (IsSkipped(skippedServices, service_name)) continue;
177859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme
1784b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao        sp<IBinder> service = sm->checkService(service_name);
179f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        if (service != NULL) {
1804b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            int sfd[2];
1814b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
18249f0a0cddbcad9be1d408425ee608ca925c6885bJosh Gao            if (pipe(sfd) != 0) {
18349f0a0cddbcad9be1d408425ee608ca925c6885bJosh Gao                aerr << "Failed to create pipe to dump service info for " << service_name
1844b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                     << ": " << strerror(errno) << endl;
1854b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                continue;
1864b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            }
1874b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
1884b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            unique_fd local_end(sfd[0]);
1894b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            unique_fd remote_end(sfd[1]);
1904b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            sfd[0] = sfd[1] = -1;
1914b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
192f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            if (N > 1) {
193f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                aout << "------------------------------------------------------------"
194f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                        "-------------------" << endl;
1954b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                aout << "DUMP OF SERVICE " << service_name << ":" << endl;
196f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
1974b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
1984b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            // dump blocks until completion, so spawn a thread..
1994b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable {
2004b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                int err = service->dump(remote_end.get(), args);
2014b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2024b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // It'd be nice to be able to close the remote end of the socketpair before the dump
2034b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // call returns, to terminate our reads if the other end closes their copy of the
2044b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // file descriptor, but then hangs for some reason. There doesn't seem to be a good
2054b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // way to do this, though.
2064b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                remote_end.clear();
2074b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2084b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (err != 0) {
2094b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Error dumping service info: (" << strerror(err) << ") " << service_name
2104b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << endl;
2114b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2124b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            });
2134b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2148b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            auto timeout = std::chrono::seconds(timeoutArg);
2152f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            auto start = std::chrono::steady_clock::now();
2162f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            auto end = start + timeout;
2174b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2184b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            struct pollfd pfd = {
2194b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                .fd = local_end.get(),
2204b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                .events = POLLIN
2214b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            };
2224b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2234b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            bool timed_out = false;
2244b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            bool error = false;
2254b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            while (true) {
2264b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // Wrap this in a lambda so that TEMP_FAILURE_RETRY recalculates the timeout.
2274b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                auto time_left_ms = [end]() {
2284b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    auto now = std::chrono::steady_clock::now();
2294b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
2304b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    return std::max(diff.count(), 0ll);
2314b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                };
2324b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2334b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
2344b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (rc < 0) {
2354b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Error in poll while dumping service " << service_name << " : "
2364b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << strerror(errno) << endl;
2374b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    error = true;
2384b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2394b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                } else if (rc == 0) {
2404b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    timed_out = true;
2414b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2424b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2434b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2444b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                char buf[4096];
2454b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                rc = TEMP_FAILURE_RETRY(read(local_end.get(), buf, sizeof(buf)));
2464b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (rc < 0) {
2474b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Failed to read while dumping service " << service_name << ": "
2484b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << strerror(errno) << endl;
2494b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    error = true;
2504b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2514b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                } else if (rc == 0) {
2524b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    // EOF.
2534b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2544b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2554b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2564b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (!WriteFully(STDOUT_FILENO, buf, rc)) {
2574b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Failed to write while dumping service " << service_name << ": "
2584b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << strerror(errno) << endl;
2594b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    error = true;
2604b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2614b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2624b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            }
2634b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2644b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            if (timed_out) {
2654b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                aout << endl << "*** SERVICE DUMP TIMEOUT EXPIRED ***" << endl << endl;
2664b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            }
2674b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2684b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            if (timed_out || error) {
2694b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                dump_thread.detach();
2704b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            } else {
2714b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                dump_thread.join();
272f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
2732f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal
2742f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            if (N > 1) {
2752f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal              std::chrono::duration<double> elapsed_seconds =
2762f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal                  std::chrono::steady_clock::now() - start;
277bca287d28450d4cc23382174c86de3c84e6a0b8fmukesh agrawal              aout << StringPrintf("--------- %.3fs ", elapsed_seconds.count()).c_str()
278bca287d28450d4cc23382174c86de3c84e6a0b8fmukesh agrawal                   << "was the duration of dumpsys " << service_name << endl;
2792f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            }
280f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        } else {
2814b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            aerr << "Can't find service: " << service_name << endl;
282f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
283f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
284f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
285f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    return 0;
286f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
287