dumpsys.cpp revision 343175a5ffeba6d1714336913a81b3029df73dbb
1f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross/*
2343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * Copyright (C) 2009 The Android Open Source Project
3f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross *
4343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * Licensed under the Apache License, Version 2.0 (the "License");
5343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * you may not use this file except in compliance with the License.
6343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * You may obtain a copy of the License at
7343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme *
8343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme *      http://www.apache.org/licenses/LICENSE-2.0
9343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme *
10343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * Unless required by applicable law or agreed to in writing, software
11343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * distributed under the License is distributed on an "AS IS" BASIS,
12343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * See the License for the specific language governing permissions and
14343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme * limitations under the License.
15f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross */
16f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
174b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <algorithm>
184b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <chrono>
194b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <thread>
204b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
214b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <android-base/file.h>
222f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal#include <android-base/stringprintf.h>
234b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <android-base/unique_fd.h>
24f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <binder/Parcel.h>
25f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <binder/ProcessState.h>
26002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <binder/TextOutput.h>
274b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <utils/Log.h>
28f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <utils/Vector.h>
29f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
304b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <fcntl.h>
31f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <getopt.h>
32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h>
334b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <stdlib.h>
34f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h>
354b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/poll.h>
364b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/socket.h>
37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h>
384b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/types.h>
394b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <unistd.h>
40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
41343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme#include "dumpsys.h"
42343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme
43f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossusing namespace android;
442f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawalusing android::base::StringPrintf;
454b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gaousing android::base::unique_fd;
464b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gaousing android::base::WriteFully;
47f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
48f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic int sort_func(const String16* lhs, const String16* rhs)
49f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross{
50f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    return lhs->compare(*rhs);
51f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
52f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
53bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Lemestatic void usage() {
54bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme    fprintf(stderr,
55bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        "usage: dumpsys\n"
56bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "         To dump all services.\n"
57bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "or:\n"
588b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            "       dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n"
59bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "         --help: shows this help\n"
60bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            "         -l: only list services, do not dump them\n"
618b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            "         -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n"
62859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            "         --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n"
63859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            "         SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n");
64859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme}
65859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme
66343175a5ffeba6d1714336913a81b3029df73dbbFelipe Lemestatic bool IsSkipped(const Vector<String16>& skipped, const String16& service) {
67859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    for (const auto& candidate : skipped) {
68859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        if (candidate == service) {
69859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            return true;
70859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        }
71859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    }
72859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    return false;
73bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme}
74bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme
75343175a5ffeba6d1714336913a81b3029df73dbbFelipe Lemeint Dumpsys::main(int argc, char* const argv[]) {
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
88343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme    // Must reset optind, otherwise subsequent calls will fail (wouldn't happen on main.cpp, but
89343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme    // happens on test cases).
90343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme    optind = 1;
918b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    while (1) {
928b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        int c;
938b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        int optionIndex = 0;
948b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
958b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        c = getopt_long(argc, argv, "+t:l", longOptions, &optionIndex);
968b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
978b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        if (c == -1) {
988b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
99bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        }
1008b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1018b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        switch (c) {
1028b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        case 0:
1038b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            if (!strcmp(longOptions[optionIndex].name, "skip")) {
1048b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                skipServices = true;
1058b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            } else if (!strcmp(longOptions[optionIndex].name, "help")) {
1068b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                usage();
1078b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                return 0;
1088b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            }
1098b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
1108b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1118b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        case 't':
1128b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            {
1138b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                char *endptr;
1148b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                timeoutArg = strtol(optarg, &endptr, 10);
1158b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                if (*endptr != '\0' || timeoutArg <= 0) {
1168b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                    fprintf(stderr, "Error: invalid timeout number: '%s'\n", optarg);
1178b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                    return -1;
1188b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                }
1198b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            }
1208b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
1218b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1228b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        case 'l':
123bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme            showListOnly = true;
1248b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            break;
1258b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1268b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        default:
1278b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            fprintf(stderr, "\n");
1288b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            usage();
1298b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            return -1;
130bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme        }
131caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    }
1328b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1338b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    for (int i = optind; i < argc; i++) {
1348b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        if (skipServices) {
1358b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            skippedServices.add(String16(argv[i]));
1368b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        } else {
1378b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            if (i == optind) {
1388b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                services.add(String16(argv[i]));
1398b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            } else {
1408b78b758a8b5b831c48562233df055c22e2541afThierry Strudel                args.add(String16(argv[i]));
141859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme            }
142859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        }
143859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme    }
1448b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
1458b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    if ((skipServices && skippedServices.empty()) ||
1468b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            (showListOnly && (!services.empty() || !skippedServices.empty()))) {
1478b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        usage();
1488b78b758a8b5b831c48562233df055c22e2541afThierry Strudel        return -1;
1498b78b758a8b5b831c48562233df055c22e2541afThierry Strudel    }
1508b78b758a8b5b831c48562233df055c22e2541afThierry Strudel
151159a8323064d8550218bf31465e51cc5a5d14926Thierry Strudel    if (services.empty() || showListOnly) {
152859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme        // gets all services
153343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme        services = sm_->listServices();
154f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        services.sort(sort_func);
155f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        args.add(String16("-a"));
156f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
157f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
158f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    const size_t N = services.size();
159f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
160f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    if (N > 1) {
161f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        // first print a list of the current services
162f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        aout << "Currently running services:" << endl;
163bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme
164f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        for (size_t i=0; i<N; i++) {
165343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme            sp<IBinder> service = sm_->checkService(services[i]);
166343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme
167343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme            if (service != nullptr) {
168859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme                bool skipped = IsSkipped(skippedServices, services[i]);
169859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme                aout << "  " << services[i] << (skipped ? " (skipped)" : "") << endl;
170f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
171f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
172f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
173f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
174caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    if (showListOnly) {
175caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung        return 0;
176caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung    }
177caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung
1784b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao    for (size_t i = 0; i < N; i++) {
1794b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao        String16 service_name = std::move(services[i]);
1804b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao        if (IsSkipped(skippedServices, service_name)) continue;
181859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme
182343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme        sp<IBinder> service = sm_->checkService(service_name);
183343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme        if (service != nullptr) {
1844b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            int sfd[2];
1854b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
18649f0a0cddbcad9be1d408425ee608ca925c6885bJosh Gao            if (pipe(sfd) != 0) {
18749f0a0cddbcad9be1d408425ee608ca925c6885bJosh Gao                aerr << "Failed to create pipe to dump service info for " << service_name
1884b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                     << ": " << strerror(errno) << endl;
1894b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                continue;
1904b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            }
1914b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
1924b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            unique_fd local_end(sfd[0]);
1934b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            unique_fd remote_end(sfd[1]);
1944b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            sfd[0] = sfd[1] = -1;
1954b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
196f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            if (N > 1) {
197f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                aout << "------------------------------------------------------------"
198f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross                        "-------------------" << endl;
1994b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                aout << "DUMP OF SERVICE " << service_name << ":" << endl;
200f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
2014b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2024b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            // dump blocks until completion, so spawn a thread..
2034b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable {
2044b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                int err = service->dump(remote_end.get(), args);
2054b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2064b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // It'd be nice to be able to close the remote end of the socketpair before the dump
2074b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // call returns, to terminate our reads if the other end closes their copy of the
2084b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // file descriptor, but then hangs for some reason. There doesn't seem to be a good
2094b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // way to do this, though.
2109656be18407d6efb0537afdbc7dcb5f0965c74fcJosh Gao                remote_end.reset();
2114b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2124b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (err != 0) {
2134b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Error dumping service info: (" << strerror(err) << ") " << service_name
2144b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << endl;
2154b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2164b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            });
2174b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2188b78b758a8b5b831c48562233df055c22e2541afThierry Strudel            auto timeout = std::chrono::seconds(timeoutArg);
2192f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            auto start = std::chrono::steady_clock::now();
2202f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            auto end = start + timeout;
2214b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2224b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            struct pollfd pfd = {
2234b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                .fd = local_end.get(),
2244b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                .events = POLLIN
2254b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            };
2264b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2274b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            bool timed_out = false;
2284b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            bool error = false;
2294b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            while (true) {
2304b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                // Wrap this in a lambda so that TEMP_FAILURE_RETRY recalculates the timeout.
2314b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                auto time_left_ms = [end]() {
2324b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    auto now = std::chrono::steady_clock::now();
2334b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now);
2344b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    return std::max(diff.count(), 0ll);
2354b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                };
2364b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2374b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms()));
2384b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (rc < 0) {
2394b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Error in poll while dumping service " << service_name << " : "
2404b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << strerror(errno) << endl;
2414b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    error = true;
2424b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2434b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                } else if (rc == 0) {
2444b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    timed_out = true;
2454b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2464b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2474b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2484b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                char buf[4096];
2494b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                rc = TEMP_FAILURE_RETRY(read(local_end.get(), buf, sizeof(buf)));
2504b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (rc < 0) {
2514b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Failed to read while dumping service " << service_name << ": "
2524b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << strerror(errno) << endl;
2534b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    error = true;
2544b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2554b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                } else if (rc == 0) {
2564b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    // EOF.
2574b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2584b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2594b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2604b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                if (!WriteFully(STDOUT_FILENO, buf, rc)) {
2614b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    aerr << "Failed to write while dumping service " << service_name << ": "
2624b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                         << strerror(errno) << endl;
2634b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    error = true;
2644b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                    break;
2654b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                }
2664b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            }
2674b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2684b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            if (timed_out) {
269343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme                aout << endl
270343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme                     << "*** SERVICE '" << service_name << "' DUMP TIMEOUT (" << timeoutArg
271343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme                     << "s) EXPIRED ***" << endl
272343175a5ffeba6d1714336913a81b3029df73dbbFelipe Leme                     << endl;
2734b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            }
2744b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao
2754b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            if (timed_out || error) {
2764b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                dump_thread.detach();
2774b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            } else {
2784b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao                dump_thread.join();
279f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross            }
2802f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal
2812f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            if (N > 1) {
2822f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal              std::chrono::duration<double> elapsed_seconds =
2832f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal                  std::chrono::steady_clock::now() - start;
284bca287d28450d4cc23382174c86de3c84e6a0b8fmukesh agrawal              aout << StringPrintf("--------- %.3fs ", elapsed_seconds.count()).c_str()
285bca287d28450d4cc23382174c86de3c84e6a0b8fmukesh agrawal                   << "was the duration of dumpsys " << service_name << endl;
2862f1eb1c16d6061ba4f79ecf67d08827bf74bed27mukesh agrawal            }
287f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        } else {
2884b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao            aerr << "Can't find service: " << service_name << endl;
289f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross        }
290f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    }
291f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross
292f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross    return 0;
293f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross}
294