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 482c3cd83603a7eefe7efe8c99cbe1c04b54cfe599Steven Morelandstatic int sort_func(const String16* lhs, const String16* rhs) 492c3cd83603a7eefe7efe8c99cbe1c04b54cfe599Steven Moreland{ 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" 582c3cd83603a7eefe7efe8c99cbe1c04b54cfe599Steven Moreland " 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()) || 1462c3cd83603a7eefe7efe8c99cbe1c04b54cfe599Steven Moreland (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