dumpsys.cpp revision 159a8323064d8550218bf31465e51cc5a5d14926
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> 134b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <android-base/unique_fd.h> 144b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <binder/IServiceManager.h> 15f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <binder/Parcel.h> 16f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <binder/ProcessState.h> 17002e1e58dfe19dd3e49a59c6827cbf51573941a2Mathias Agopian#include <binder/TextOutput.h> 184b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <utils/Log.h> 19f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <utils/Vector.h> 20f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 214b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <fcntl.h> 22f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <getopt.h> 23f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <stdio.h> 244b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <stdlib.h> 25f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <string.h> 264b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/poll.h> 274b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/socket.h> 28f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross#include <sys/time.h> 294b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <sys/types.h> 304b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao#include <unistd.h> 31f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 32f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossusing namespace android; 334b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gaousing android::base::unique_fd; 344b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gaousing android::base::WriteFully; 35f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 36f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossstatic int sort_func(const String16* lhs, const String16* rhs) 37f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross{ 38f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return lhs->compare(*rhs); 39f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 40f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 41bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Lemestatic void usage() { 42bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme fprintf(stderr, 43bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme "usage: dumpsys\n" 44bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme " To dump all services.\n" 45bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme "or:\n" 468b78b758a8b5b831c48562233df055c22e2541afThierry Strudel " dumpsys [-t TIMEOUT] [--help | -l | --skip SERVICES | SERVICE [ARGS]]\n" 47bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme " --help: shows this help\n" 48bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme " -l: only list services, do not dump them\n" 498b78b758a8b5b831c48562233df055c22e2541afThierry Strudel " -t TIMEOUT: TIMEOUT to use in seconds instead of default 10 seconds\n" 50859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme " --skip SERVICES: dumps all services but SERVICES (comma-separated list)\n" 51859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme " SERVICE [ARGS]: dumps only service SERVICE, optionally passing ARGS to it\n"); 52859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme} 53859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme 54859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Lemebool IsSkipped(const Vector<String16>& skipped, const String16& service) { 55859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme for (const auto& candidate : skipped) { 56859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme if (candidate == service) { 57859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme return true; 58859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme } 59859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme } 60859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme return false; 61bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme} 62bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme 63f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Crossint main(int argc, char* const argv[]) 64f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross{ 653e03d3fb6a4cb93f5f978f9d2eed7b7cc62a06a6JP Abgrall signal(SIGPIPE, SIG_IGN); 66f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross sp<IServiceManager> sm = defaultServiceManager(); 67f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross fflush(stdout); 68f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (sm == NULL) { 69bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme ALOGE("Unable to get default service manager!"); 70f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross aerr << "dumpsys: Unable to get default service manager!" << endl; 71f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return 20; 72f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 73f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 74f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross Vector<String16> services; 75f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross Vector<String16> args; 76859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme Vector<String16> skippedServices; 77caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung bool showListOnly = false; 788b78b758a8b5b831c48562233df055c22e2541afThierry Strudel bool skipServices = false; 798b78b758a8b5b831c48562233df055c22e2541afThierry Strudel int timeoutArg = 10; 808b78b758a8b5b831c48562233df055c22e2541afThierry Strudel static struct option longOptions[] = { 818b78b758a8b5b831c48562233df055c22e2541afThierry Strudel {"skip", no_argument, 0, 0 }, 828b78b758a8b5b831c48562233df055c22e2541afThierry Strudel {"help", no_argument, 0, 0 }, 838b78b758a8b5b831c48562233df055c22e2541afThierry Strudel { 0, 0, 0, 0 } 848b78b758a8b5b831c48562233df055c22e2541afThierry Strudel }; 858b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 868b78b758a8b5b831c48562233df055c22e2541afThierry Strudel while (1) { 878b78b758a8b5b831c48562233df055c22e2541afThierry Strudel int c; 888b78b758a8b5b831c48562233df055c22e2541afThierry Strudel int optionIndex = 0; 898b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 908b78b758a8b5b831c48562233df055c22e2541afThierry Strudel c = getopt_long(argc, argv, "+t:l", longOptions, &optionIndex); 918b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 928b78b758a8b5b831c48562233df055c22e2541afThierry Strudel if (c == -1) { 938b78b758a8b5b831c48562233df055c22e2541afThierry Strudel break; 94bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme } 958b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 968b78b758a8b5b831c48562233df055c22e2541afThierry Strudel switch (c) { 978b78b758a8b5b831c48562233df055c22e2541afThierry Strudel case 0: 988b78b758a8b5b831c48562233df055c22e2541afThierry Strudel if (!strcmp(longOptions[optionIndex].name, "skip")) { 998b78b758a8b5b831c48562233df055c22e2541afThierry Strudel skipServices = true; 1008b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } else if (!strcmp(longOptions[optionIndex].name, "help")) { 1018b78b758a8b5b831c48562233df055c22e2541afThierry Strudel usage(); 1028b78b758a8b5b831c48562233df055c22e2541afThierry Strudel return 0; 1038b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } 1048b78b758a8b5b831c48562233df055c22e2541afThierry Strudel break; 1058b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 1068b78b758a8b5b831c48562233df055c22e2541afThierry Strudel case 't': 1078b78b758a8b5b831c48562233df055c22e2541afThierry Strudel { 1088b78b758a8b5b831c48562233df055c22e2541afThierry Strudel char *endptr; 1098b78b758a8b5b831c48562233df055c22e2541afThierry Strudel timeoutArg = strtol(optarg, &endptr, 10); 1108b78b758a8b5b831c48562233df055c22e2541afThierry Strudel if (*endptr != '\0' || timeoutArg <= 0) { 1118b78b758a8b5b831c48562233df055c22e2541afThierry Strudel fprintf(stderr, "Error: invalid timeout number: '%s'\n", optarg); 1128b78b758a8b5b831c48562233df055c22e2541afThierry Strudel return -1; 1138b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } 1148b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } 1158b78b758a8b5b831c48562233df055c22e2541afThierry Strudel break; 1168b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 1178b78b758a8b5b831c48562233df055c22e2541afThierry Strudel case 'l': 118bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme showListOnly = true; 1198b78b758a8b5b831c48562233df055c22e2541afThierry Strudel break; 1208b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 1218b78b758a8b5b831c48562233df055c22e2541afThierry Strudel default: 1228b78b758a8b5b831c48562233df055c22e2541afThierry Strudel fprintf(stderr, "\n"); 1238b78b758a8b5b831c48562233df055c22e2541afThierry Strudel usage(); 1248b78b758a8b5b831c48562233df055c22e2541afThierry Strudel return -1; 125bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme } 126caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung } 1278b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 1288b78b758a8b5b831c48562233df055c22e2541afThierry Strudel for (int i = optind; i < argc; i++) { 1298b78b758a8b5b831c48562233df055c22e2541afThierry Strudel if (skipServices) { 1308b78b758a8b5b831c48562233df055c22e2541afThierry Strudel skippedServices.add(String16(argv[i])); 1318b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } else { 1328b78b758a8b5b831c48562233df055c22e2541afThierry Strudel if (i == optind) { 1338b78b758a8b5b831c48562233df055c22e2541afThierry Strudel services.add(String16(argv[i])); 1348b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } else { 1358b78b758a8b5b831c48562233df055c22e2541afThierry Strudel args.add(String16(argv[i])); 136859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme } 137859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme } 138859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme } 1398b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 1408b78b758a8b5b831c48562233df055c22e2541afThierry Strudel if ((skipServices && skippedServices.empty()) || 1418b78b758a8b5b831c48562233df055c22e2541afThierry Strudel (showListOnly && (!services.empty() || !skippedServices.empty()))) { 1428b78b758a8b5b831c48562233df055c22e2541afThierry Strudel usage(); 1438b78b758a8b5b831c48562233df055c22e2541afThierry Strudel return -1; 1448b78b758a8b5b831c48562233df055c22e2541afThierry Strudel } 1458b78b758a8b5b831c48562233df055c22e2541afThierry Strudel 146159a8323064d8550218bf31465e51cc5a5d14926Thierry Strudel if (services.empty() || showListOnly) { 147859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme // gets all services 148f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross services = sm->listServices(); 149f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross services.sort(sort_func); 150f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross args.add(String16("-a")); 151f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 152f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 153f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross const size_t N = services.size(); 154f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 155f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (N > 1) { 156f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross // first print a list of the current services 157f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross aout << "Currently running services:" << endl; 158bbfd2b89434e57cb0720d59383b5bf5339492028Felipe Leme 159f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross for (size_t i=0; i<N; i++) { 160f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross sp<IBinder> service = sm->checkService(services[i]); 161f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (service != NULL) { 162859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme bool skipped = IsSkipped(skippedServices, services[i]); 163859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme aout << " " << services[i] << (skipped ? " (skipped)" : "") << endl; 164f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 165f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 166f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 167f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 168caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung if (showListOnly) { 169caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung return 0; 170caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung } 171caad555f3efaf77941c4eacd4f6c84eb22d14f6dkeunyoung 1724b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao for (size_t i = 0; i < N; i++) { 1734b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao String16 service_name = std::move(services[i]); 1744b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (IsSkipped(skippedServices, service_name)) continue; 175859aef6a32ba03aae8e487078deb469a3ff84e6bFelipe Leme 1764b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao sp<IBinder> service = sm->checkService(service_name); 177f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (service != NULL) { 1784b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao int sfd[2]; 1794b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 18049f0a0cddbcad9be1d408425ee608ca925c6885bJosh Gao if (pipe(sfd) != 0) { 18149f0a0cddbcad9be1d408425ee608ca925c6885bJosh Gao aerr << "Failed to create pipe to dump service info for " << service_name 1824b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao << ": " << strerror(errno) << endl; 1834b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao continue; 1844b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 1854b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 1864b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao unique_fd local_end(sfd[0]); 1874b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao unique_fd remote_end(sfd[1]); 1884b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao sfd[0] = sfd[1] = -1; 1894b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 190f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross if (N > 1) { 191f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross aout << "------------------------------------------------------------" 192f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross "-------------------" << endl; 1934b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aout << "DUMP OF SERVICE " << service_name << ":" << endl; 194f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 1954b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 1964b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // dump blocks until completion, so spawn a thread.. 1974b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao std::thread dump_thread([=, remote_end { std::move(remote_end) }]() mutable { 1984b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao int err = service->dump(remote_end.get(), args); 1994b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2004b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // It'd be nice to be able to close the remote end of the socketpair before the dump 2014b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // call returns, to terminate our reads if the other end closes their copy of the 2024b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // file descriptor, but then hangs for some reason. There doesn't seem to be a good 2034b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // way to do this, though. 2044b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao remote_end.clear(); 2054b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2064b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (err != 0) { 2074b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aerr << "Error dumping service info: (" << strerror(err) << ") " << service_name 2084b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao << endl; 2094b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 2104b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao }); 2114b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2128b78b758a8b5b831c48562233df055c22e2541afThierry Strudel auto timeout = std::chrono::seconds(timeoutArg); 2134b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao auto end = std::chrono::steady_clock::now() + timeout; 2144b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2154b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao struct pollfd pfd = { 2164b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao .fd = local_end.get(), 2174b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao .events = POLLIN 2184b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao }; 2194b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2204b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao bool timed_out = false; 2214b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao bool error = false; 2224b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao while (true) { 2234b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // Wrap this in a lambda so that TEMP_FAILURE_RETRY recalculates the timeout. 2244b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao auto time_left_ms = [end]() { 2254b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao auto now = std::chrono::steady_clock::now(); 2264b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(end - now); 2274b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao return std::max(diff.count(), 0ll); 2284b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao }; 2294b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2304b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao int rc = TEMP_FAILURE_RETRY(poll(&pfd, 1, time_left_ms())); 2314b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (rc < 0) { 2324b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aerr << "Error in poll while dumping service " << service_name << " : " 2334b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao << strerror(errno) << endl; 2344b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao error = true; 2354b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao break; 2364b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } else if (rc == 0) { 2374b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao timed_out = true; 2384b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao break; 2394b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 2404b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2414b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao char buf[4096]; 2424b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao rc = TEMP_FAILURE_RETRY(read(local_end.get(), buf, sizeof(buf))); 2434b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (rc < 0) { 2444b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aerr << "Failed to read while dumping service " << service_name << ": " 2454b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao << strerror(errno) << endl; 2464b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao error = true; 2474b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao break; 2484b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } else if (rc == 0) { 2494b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao // EOF. 2504b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao break; 2514b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 2524b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2534b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (!WriteFully(STDOUT_FILENO, buf, rc)) { 2544b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aerr << "Failed to write while dumping service " << service_name << ": " 2554b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao << strerror(errno) << endl; 2564b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao error = true; 2574b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao break; 2584b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 2594b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 2604b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2614b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (timed_out) { 2624b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aout << endl << "*** SERVICE DUMP TIMEOUT EXPIRED ***" << endl << endl; 2634b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } 2644b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao 2654b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao if (timed_out || error) { 2664b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao dump_thread.detach(); 2674b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao } else { 2684b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao dump_thread.join(); 269f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 270f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } else { 2714b8f6f9adb8ee1a06b145c8dc83a672f8d0ac80fJosh Gao aerr << "Can't find service: " << service_name << endl; 272f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 273f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross } 274f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross 275f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross return 0; 276f45fa6b2853cc32385375a0b63ee39ad6a968869Colin Cross} 277