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