Loading cmds/dumpstate/dumpstate.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1082,7 +1082,7 @@ static Dumpstate::RunStatus RunDumpsysTextByPriority(const std::string& title, i std::string path(title); path.append(" - ").append(String8(service).c_str()); size_t bytes_written = 0; status_t status = dumpsys.startDumpThread(service, args); status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args); if (status == OK) { dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority); std::chrono::duration<double> elapsed_seconds; Loading Loading @@ -1154,7 +1154,7 @@ static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priori path.append("_HIGH"); } path.append(kProtoExt); status_t status = dumpsys.startDumpThread(service, args); status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args); if (status == OK) { status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout); bool dumpTerminated = (status == OK); Loading cmds/dumpsys/dumpsys.cpp +35 −13 Original line number Diff line number Diff line Loading @@ -59,12 +59,13 @@ static void usage() { "usage: dumpsys\n" " To dump all services.\n" "or:\n" " dumpsys [-t TIMEOUT] [--priority LEVEL] [--help | -l | --skip SERVICES | " "SERVICE [ARGS]]\n" " dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--help | -l | --skip SERVICES " "| SERVICE [ARGS]]\n" " --help: shows this help\n" " -l: only list services, do not dump them\n" " -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n" " -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n" " --pid: dump PID instead of usual dump\n" " --proto: filter services that support dumping data in proto format. Dumps\n" " will be in proto format.\n" " --priority LEVEL: filter services based on specified priority\n" Loading Loading @@ -120,9 +121,11 @@ int Dumpsys::main(int argc, char* const argv[]) { bool showListOnly = false; bool skipServices = false; bool asProto = false; Type type = Type::DUMP; int timeoutArgMs = 10000; int priorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL; static struct option longOptions[] = {{"priority", required_argument, 0, 0}, static struct option longOptions[] = {{"pid", no_argument, 0, 0}, {"priority", required_argument, 0, 0}, {"proto", no_argument, 0, 0}, {"skip", no_argument, 0, 0}, {"help", no_argument, 0, 0}, Loading Loading @@ -157,6 +160,8 @@ int Dumpsys::main(int argc, char* const argv[]) { usage(); return -1; } } else if (!strcmp(longOptions[optionIndex].name, "pid")) { type = Type::PID; } break; Loading Loading @@ -246,7 +251,7 @@ int Dumpsys::main(int argc, char* const argv[]) { const String16& serviceName = services[i]; if (IsSkipped(skippedServices, serviceName)) continue; if (startDumpThread(serviceName, args) == OK) { if (startDumpThread(type, serviceName, args) == OK) { bool addSeparator = (N > 1); if (addSeparator) { writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags); Loading Loading @@ -313,7 +318,18 @@ void Dumpsys::setServiceArgs(Vector<String16>& args, bool asProto, int priorityF } } status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<String16>& args) { static status_t dumpPidToFd(const sp<IBinder>& service, const unique_fd& fd) { pid_t pid; status_t status = service->getDebugPid(&pid); if (status != OK) { return status; } WriteStringToFd(std::to_string(pid) + "\n", fd.get()); return OK; } status_t Dumpsys::startDumpThread(Type type, const String16& serviceName, const Vector<String16>& args) { sp<IBinder> service = sm_->checkService(serviceName); if (service == nullptr) { aerr << "Can't find service: " << serviceName << endl; Loading @@ -333,16 +349,22 @@ status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<Stri // dump blocks until completion, so spawn a thread.. activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable { int err = service->dump(remote_end.get(), args); status_t err = 0; // It'd be nice to be able to close the remote end of the socketpair before the dump // call returns, to terminate our reads if the other end closes their copy of the // file descriptor, but then hangs for some reason. There doesn't seem to be a good // way to do this, though. remote_end.reset(); switch (type) { case Type::DUMP: err = service->dump(remote_end.get(), args); break; case Type::PID: err = dumpPidToFd(service, remote_end); break; default: aerr << "Unknown dump type" << static_cast<int>(type) << endl; return; } if (err != 0) { aerr << "Error dumping service info: (" << strerror(err) << ") " if (err != OK) { aerr << "Error dumping service info status_t: (" << err << ") " << serviceName << endl; } }); Loading cmds/dumpsys/dumpsys.h +7 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,11 @@ class Dumpsys { */ static void setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags); enum class Type { DUMP, // dump using `dump` function PID, // dump pid of server only }; /** * Starts a thread to connect to a service and get its dump output. The thread redirects * the output to a pipe. Thread must be stopped by a subsequent callto {@code Loading @@ -61,7 +66,8 @@ class Dumpsys { * {@code NAME_NOT_FOUND} service could not be found. * {@code != OK} error */ status_t startDumpThread(const String16& serviceName, const Vector<String16>& args); status_t startDumpThread(Type type, const String16& serviceName, const Vector<String16>& args); /** * Writes a section header to a file descriptor. Loading cmds/dumpsys/tests/dumpsys_test.cpp +23 −2 Original line number Diff line number Diff line Loading @@ -194,7 +194,7 @@ class DumpsysTest : public Test { CaptureStdout(); CaptureStderr(); dump_.setServiceArgs(args, supportsProto, priorityFlags); status_t status = dump_.startDumpThread(serviceName, args); status_t status = dump_.startDumpThread(Dumpsys::Type::DUMP, serviceName, args); EXPECT_THAT(status, Eq(0)); status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false, elapsedDuration, bytesWritten); Loading Loading @@ -539,6 +539,27 @@ TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) { AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); } // Tests 'dumpsys --pid' TEST_F(DumpsysTest, ListAllServicesWithPid) { ExpectListServices({"Locksmith", "Valet"}); ExpectCheckService("Locksmith"); ExpectCheckService("Valet"); CallMain({"--pid"}); AssertRunningServices({"Locksmith", "Valet"}); AssertOutputContains(std::to_string(getpid())); } // Tests 'dumpsys --pid service_name' TEST_F(DumpsysTest, ListServiceWithPid) { ExpectCheckService("Locksmith"); CallMain({"--pid", "Locksmith"}); AssertOutput(std::to_string(getpid()) + "\n"); } TEST_F(DumpsysTest, GetBytesWritten) { const char* serviceName = "service2"; const char* dumpContents = "dump1"; Loading Loading
cmds/dumpstate/dumpstate.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1082,7 +1082,7 @@ static Dumpstate::RunStatus RunDumpsysTextByPriority(const std::string& title, i std::string path(title); path.append(" - ").append(String8(service).c_str()); size_t bytes_written = 0; status_t status = dumpsys.startDumpThread(service, args); status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args); if (status == OK) { dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority); std::chrono::duration<double> elapsed_seconds; Loading Loading @@ -1154,7 +1154,7 @@ static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priori path.append("_HIGH"); } path.append(kProtoExt); status_t status = dumpsys.startDumpThread(service, args); status_t status = dumpsys.startDumpThread(Dumpsys::Type::DUMP, service, args); if (status == OK) { status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout); bool dumpTerminated = (status == OK); Loading
cmds/dumpsys/dumpsys.cpp +35 −13 Original line number Diff line number Diff line Loading @@ -59,12 +59,13 @@ static void usage() { "usage: dumpsys\n" " To dump all services.\n" "or:\n" " dumpsys [-t TIMEOUT] [--priority LEVEL] [--help | -l | --skip SERVICES | " "SERVICE [ARGS]]\n" " dumpsys [-t TIMEOUT] [--priority LEVEL] [--pid] [--help | -l | --skip SERVICES " "| SERVICE [ARGS]]\n" " --help: shows this help\n" " -l: only list services, do not dump them\n" " -t TIMEOUT_SEC: TIMEOUT to use in seconds instead of default 10 seconds\n" " -T TIMEOUT_MS: TIMEOUT to use in milliseconds instead of default 10 seconds\n" " --pid: dump PID instead of usual dump\n" " --proto: filter services that support dumping data in proto format. Dumps\n" " will be in proto format.\n" " --priority LEVEL: filter services based on specified priority\n" Loading Loading @@ -120,9 +121,11 @@ int Dumpsys::main(int argc, char* const argv[]) { bool showListOnly = false; bool skipServices = false; bool asProto = false; Type type = Type::DUMP; int timeoutArgMs = 10000; int priorityFlags = IServiceManager::DUMP_FLAG_PRIORITY_ALL; static struct option longOptions[] = {{"priority", required_argument, 0, 0}, static struct option longOptions[] = {{"pid", no_argument, 0, 0}, {"priority", required_argument, 0, 0}, {"proto", no_argument, 0, 0}, {"skip", no_argument, 0, 0}, {"help", no_argument, 0, 0}, Loading Loading @@ -157,6 +160,8 @@ int Dumpsys::main(int argc, char* const argv[]) { usage(); return -1; } } else if (!strcmp(longOptions[optionIndex].name, "pid")) { type = Type::PID; } break; Loading Loading @@ -246,7 +251,7 @@ int Dumpsys::main(int argc, char* const argv[]) { const String16& serviceName = services[i]; if (IsSkipped(skippedServices, serviceName)) continue; if (startDumpThread(serviceName, args) == OK) { if (startDumpThread(type, serviceName, args) == OK) { bool addSeparator = (N > 1); if (addSeparator) { writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags); Loading Loading @@ -313,7 +318,18 @@ void Dumpsys::setServiceArgs(Vector<String16>& args, bool asProto, int priorityF } } status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<String16>& args) { static status_t dumpPidToFd(const sp<IBinder>& service, const unique_fd& fd) { pid_t pid; status_t status = service->getDebugPid(&pid); if (status != OK) { return status; } WriteStringToFd(std::to_string(pid) + "\n", fd.get()); return OK; } status_t Dumpsys::startDumpThread(Type type, const String16& serviceName, const Vector<String16>& args) { sp<IBinder> service = sm_->checkService(serviceName); if (service == nullptr) { aerr << "Can't find service: " << serviceName << endl; Loading @@ -333,16 +349,22 @@ status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<Stri // dump blocks until completion, so spawn a thread.. activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable { int err = service->dump(remote_end.get(), args); status_t err = 0; // It'd be nice to be able to close the remote end of the socketpair before the dump // call returns, to terminate our reads if the other end closes their copy of the // file descriptor, but then hangs for some reason. There doesn't seem to be a good // way to do this, though. remote_end.reset(); switch (type) { case Type::DUMP: err = service->dump(remote_end.get(), args); break; case Type::PID: err = dumpPidToFd(service, remote_end); break; default: aerr << "Unknown dump type" << static_cast<int>(type) << endl; return; } if (err != 0) { aerr << "Error dumping service info: (" << strerror(err) << ") " if (err != OK) { aerr << "Error dumping service info status_t: (" << err << ") " << serviceName << endl; } }); Loading
cmds/dumpsys/dumpsys.h +7 −1 Original line number Diff line number Diff line Loading @@ -51,6 +51,11 @@ class Dumpsys { */ static void setServiceArgs(Vector<String16>& args, bool asProto, int priorityFlags); enum class Type { DUMP, // dump using `dump` function PID, // dump pid of server only }; /** * Starts a thread to connect to a service and get its dump output. The thread redirects * the output to a pipe. Thread must be stopped by a subsequent callto {@code Loading @@ -61,7 +66,8 @@ class Dumpsys { * {@code NAME_NOT_FOUND} service could not be found. * {@code != OK} error */ status_t startDumpThread(const String16& serviceName, const Vector<String16>& args); status_t startDumpThread(Type type, const String16& serviceName, const Vector<String16>& args); /** * Writes a section header to a file descriptor. Loading
cmds/dumpsys/tests/dumpsys_test.cpp +23 −2 Original line number Diff line number Diff line Loading @@ -194,7 +194,7 @@ class DumpsysTest : public Test { CaptureStdout(); CaptureStderr(); dump_.setServiceArgs(args, supportsProto, priorityFlags); status_t status = dump_.startDumpThread(serviceName, args); status_t status = dump_.startDumpThread(Dumpsys::Type::DUMP, serviceName, args); EXPECT_THAT(status, Eq(0)); status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false, elapsedDuration, bytesWritten); Loading Loading @@ -539,6 +539,27 @@ TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) { AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); } // Tests 'dumpsys --pid' TEST_F(DumpsysTest, ListAllServicesWithPid) { ExpectListServices({"Locksmith", "Valet"}); ExpectCheckService("Locksmith"); ExpectCheckService("Valet"); CallMain({"--pid"}); AssertRunningServices({"Locksmith", "Valet"}); AssertOutputContains(std::to_string(getpid())); } // Tests 'dumpsys --pid service_name' TEST_F(DumpsysTest, ListServiceWithPid) { ExpectCheckService("Locksmith"); CallMain({"--pid", "Locksmith"}); AssertOutput(std::to_string(getpid()) + "\n"); } TEST_F(DumpsysTest, GetBytesWritten) { const char* serviceName = "service2"; const char* dumpContents = "dump1"; Loading