Loading cmds/dumpstate/dumpstate.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1057,7 +1057,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, /* dumpPid = */ true, args); status_t status = dumpsys.startDumpThread(service, args); if (status == OK) { dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority); std::chrono::duration<double> elapsed_seconds; Loading Loading @@ -1129,7 +1129,7 @@ static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priori path.append("_HIGH"); } path.append(kProtoExt); status_t status = dumpsys.startDumpThread(service, /* dumpPid = */ false, args); status_t status = dumpsys.startDumpThread(service, args); if (status == OK) { status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout); bool dumpTerminated = (status == OK); Loading cmds/dumpsys/dumpsys.cpp +5 −20 Original line number Diff line number Diff line Loading @@ -242,13 +242,11 @@ int Dumpsys::main(int argc, char* const argv[]) { return 0; } const bool dumpPid = !asProto; for (size_t i = 0; i < N; i++) { const String16& serviceName = services[i]; if (IsSkipped(skippedServices, serviceName)) continue; if (startDumpThread(serviceName, dumpPid, args) == OK) { if (startDumpThread(serviceName, args) == OK) { bool addSeparator = (N > 1); if (addSeparator) { writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags); Loading Loading @@ -315,7 +313,7 @@ void Dumpsys::setServiceArgs(Vector<String16>& args, bool asProto, int priorityF } } status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, const Vector<String16>& args) { status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<String16>& args) { sp<IBinder> service = sm_->checkService(serviceName); if (service == nullptr) { aerr << "Can't find service: " << serviceName << endl; Loading @@ -335,20 +333,7 @@ status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, con // dump blocks until completion, so spawn a thread.. activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable { if (dumpPid) { pid_t pid; status_t status = service->getDebugPid(&pid); if (status == OK) { std::ostringstream pidinfo; pidinfo << "Pid: " << pid << std::endl; WriteStringToFd(pidinfo.str(), remote_end.get()); } else { aerr << "Error getting pid status_t (" << status << "): " << serviceName << endl; } } status_t err = service->dump(remote_end.get(), args); int err = service->dump(remote_end.get(), args); // 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 Loading @@ -356,8 +341,8 @@ status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, con // way to do this, though. remote_end.reset(); if (err != OK) { aerr << "Error dumping service info status_t (" << err << "): " if (err != 0) { aerr << "Error dumping service info: (" << strerror(err) << ") " << serviceName << endl; } }); Loading cmds/dumpsys/dumpsys.h +1 −2 Original line number Diff line number Diff line Loading @@ -56,13 +56,12 @@ class Dumpsys { * the output to a pipe. Thread must be stopped by a subsequent callto {@code * stopDumpThread}. * @param serviceName * @param dumpPid whether to include a header with service PID information * @param args list of arguments to pass to service dump method. * @return {@code OK} thread is started successfully. * {@code NAME_NOT_FOUND} service could not be found. * {@code != OK} error */ status_t startDumpThread(const String16& serviceName, bool dumpPid, const Vector<String16>& args); status_t startDumpThread(const String16& serviceName, const Vector<String16>& args); /** * Writes a section header to a file descriptor. Loading cmds/dumpsys/tests/dumpsys_test.cpp +42 −8 Original line number Diff line number Diff line Loading @@ -188,6 +188,22 @@ class DumpsysTest : public Test { EXPECT_THAT(status, Eq(0)); } void CallSingleService(const String16& serviceName, Vector<String16>& args, int priorityFlags, bool supportsProto, std::chrono::duration<double>& elapsedDuration, size_t& bytesWritten) { CaptureStdout(); CaptureStderr(); dump_.setServiceArgs(args, supportsProto, priorityFlags); status_t status = dump_.startDumpThread(serviceName, args); EXPECT_THAT(status, Eq(0)); status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false, elapsedDuration, bytesWritten); EXPECT_THAT(status, Eq(0)); dump_.stopDumpThread(/* dumpCompleted = */ true); stdout_ = GetCapturedStdout(); stderr_ = GetCapturedStderr(); } void AssertRunningServices(const std::vector<std::string>& services) { std::string expected; if (services.size() > 1) { Loading @@ -199,13 +215,16 @@ class DumpsysTest : public Test { EXPECT_THAT(stdout_, HasSubstr(expected)); } void AssertOutput(const std::string& expected) { EXPECT_THAT(stdout_, StrEq(expected)); } void AssertOutputContains(const std::string& expected) { EXPECT_THAT(stdout_, HasSubstr(expected)); } void AssertDumped(const std::string& service, const std::string& dump) { EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n")); EXPECT_THAT(stdout_, HasSubstr(dump)); EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump)); EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: ")); } Loading @@ -213,8 +232,7 @@ class DumpsysTest : public Test { const char16_t* priorityType) { std::string priority = String8(priorityType).c_str(); EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n")); EXPECT_THAT(stdout_, HasSubstr(dump)); HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n" + dump)); EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: ")); } Loading Loading @@ -295,8 +313,7 @@ TEST_F(DumpsysTest, DumpRunningService) { CallMain({"Valet"}); AssertOutputContains("Pid: " + std::to_string(getpid())); AssertOutputContains("Here's your car"); AssertOutput("Here's your car"); } // Tests 'dumpsys -t 1 service_name' on a service that times out after 2s Loading Loading @@ -331,7 +348,7 @@ TEST_F(DumpsysTest, DumpWithArgsRunningService) { CallMain({"SERVICE", "Y", "U", "NO", "HANDLE", "ARGS"}); AssertOutputContains("I DO!"); AssertOutput("I DO!"); } // Tests dumpsys passes the -a flag when called on all services Loading Loading @@ -522,6 +539,23 @@ TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) { AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); } TEST_F(DumpsysTest, GetBytesWritten) { const char* serviceName = "service2"; const char* dumpContents = "dump1"; ExpectDump(serviceName, dumpContents); String16 service(serviceName); Vector<String16> args; std::chrono::duration<double> elapsedDuration; size_t bytesWritten; CallSingleService(service, args, IServiceManager::DUMP_FLAG_PRIORITY_ALL, /* as_proto = */ false, elapsedDuration, bytesWritten); AssertOutput(dumpContents); EXPECT_THAT(bytesWritten, Eq(strlen(dumpContents))); } TEST_F(DumpsysTest, WriteDumpWithoutThreadStart) { std::chrono::duration<double> elapsedDuration; size_t bytesWritten; Loading Loading
cmds/dumpstate/dumpstate.cpp +2 −2 Original line number Diff line number Diff line Loading @@ -1057,7 +1057,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, /* dumpPid = */ true, args); status_t status = dumpsys.startDumpThread(service, args); if (status == OK) { dumpsys.writeDumpHeader(STDOUT_FILENO, service, priority); std::chrono::duration<double> elapsed_seconds; Loading Loading @@ -1129,7 +1129,7 @@ static Dumpstate::RunStatus RunDumpsysProto(const std::string& title, int priori path.append("_HIGH"); } path.append(kProtoExt); status_t status = dumpsys.startDumpThread(service, /* dumpPid = */ false, args); status_t status = dumpsys.startDumpThread(service, args); if (status == OK) { status = ds.AddZipEntryFromFd(path, dumpsys.getDumpFd(), service_timeout); bool dumpTerminated = (status == OK); Loading
cmds/dumpsys/dumpsys.cpp +5 −20 Original line number Diff line number Diff line Loading @@ -242,13 +242,11 @@ int Dumpsys::main(int argc, char* const argv[]) { return 0; } const bool dumpPid = !asProto; for (size_t i = 0; i < N; i++) { const String16& serviceName = services[i]; if (IsSkipped(skippedServices, serviceName)) continue; if (startDumpThread(serviceName, dumpPid, args) == OK) { if (startDumpThread(serviceName, args) == OK) { bool addSeparator = (N > 1); if (addSeparator) { writeDumpHeader(STDOUT_FILENO, serviceName, priorityFlags); Loading Loading @@ -315,7 +313,7 @@ void Dumpsys::setServiceArgs(Vector<String16>& args, bool asProto, int priorityF } } status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, const Vector<String16>& args) { status_t Dumpsys::startDumpThread(const String16& serviceName, const Vector<String16>& args) { sp<IBinder> service = sm_->checkService(serviceName); if (service == nullptr) { aerr << "Can't find service: " << serviceName << endl; Loading @@ -335,20 +333,7 @@ status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, con // dump blocks until completion, so spawn a thread.. activeThread_ = std::thread([=, remote_end{std::move(remote_end)}]() mutable { if (dumpPid) { pid_t pid; status_t status = service->getDebugPid(&pid); if (status == OK) { std::ostringstream pidinfo; pidinfo << "Pid: " << pid << std::endl; WriteStringToFd(pidinfo.str(), remote_end.get()); } else { aerr << "Error getting pid status_t (" << status << "): " << serviceName << endl; } } status_t err = service->dump(remote_end.get(), args); int err = service->dump(remote_end.get(), args); // 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 Loading @@ -356,8 +341,8 @@ status_t Dumpsys::startDumpThread(const String16& serviceName, bool dumpPid, con // way to do this, though. remote_end.reset(); if (err != OK) { aerr << "Error dumping service info status_t (" << err << "): " if (err != 0) { aerr << "Error dumping service info: (" << strerror(err) << ") " << serviceName << endl; } }); Loading
cmds/dumpsys/dumpsys.h +1 −2 Original line number Diff line number Diff line Loading @@ -56,13 +56,12 @@ class Dumpsys { * the output to a pipe. Thread must be stopped by a subsequent callto {@code * stopDumpThread}. * @param serviceName * @param dumpPid whether to include a header with service PID information * @param args list of arguments to pass to service dump method. * @return {@code OK} thread is started successfully. * {@code NAME_NOT_FOUND} service could not be found. * {@code != OK} error */ status_t startDumpThread(const String16& serviceName, bool dumpPid, const Vector<String16>& args); status_t startDumpThread(const String16& serviceName, const Vector<String16>& args); /** * Writes a section header to a file descriptor. Loading
cmds/dumpsys/tests/dumpsys_test.cpp +42 −8 Original line number Diff line number Diff line Loading @@ -188,6 +188,22 @@ class DumpsysTest : public Test { EXPECT_THAT(status, Eq(0)); } void CallSingleService(const String16& serviceName, Vector<String16>& args, int priorityFlags, bool supportsProto, std::chrono::duration<double>& elapsedDuration, size_t& bytesWritten) { CaptureStdout(); CaptureStderr(); dump_.setServiceArgs(args, supportsProto, priorityFlags); status_t status = dump_.startDumpThread(serviceName, args); EXPECT_THAT(status, Eq(0)); status = dump_.writeDump(STDOUT_FILENO, serviceName, std::chrono::milliseconds(500), false, elapsedDuration, bytesWritten); EXPECT_THAT(status, Eq(0)); dump_.stopDumpThread(/* dumpCompleted = */ true); stdout_ = GetCapturedStdout(); stderr_ = GetCapturedStderr(); } void AssertRunningServices(const std::vector<std::string>& services) { std::string expected; if (services.size() > 1) { Loading @@ -199,13 +215,16 @@ class DumpsysTest : public Test { EXPECT_THAT(stdout_, HasSubstr(expected)); } void AssertOutput(const std::string& expected) { EXPECT_THAT(stdout_, StrEq(expected)); } void AssertOutputContains(const std::string& expected) { EXPECT_THAT(stdout_, HasSubstr(expected)); } void AssertDumped(const std::string& service, const std::string& dump) { EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n")); EXPECT_THAT(stdout_, HasSubstr(dump)); EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + service + ":\n" + dump)); EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: ")); } Loading @@ -213,8 +232,7 @@ class DumpsysTest : public Test { const char16_t* priorityType) { std::string priority = String8(priorityType).c_str(); EXPECT_THAT(stdout_, HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n")); EXPECT_THAT(stdout_, HasSubstr(dump)); HasSubstr("DUMP OF SERVICE " + priority + " " + service + ":\n" + dump)); EXPECT_THAT(stdout_, HasSubstr("was the duration of dumpsys " + service + ", ending at: ")); } Loading Loading @@ -295,8 +313,7 @@ TEST_F(DumpsysTest, DumpRunningService) { CallMain({"Valet"}); AssertOutputContains("Pid: " + std::to_string(getpid())); AssertOutputContains("Here's your car"); AssertOutput("Here's your car"); } // Tests 'dumpsys -t 1 service_name' on a service that times out after 2s Loading Loading @@ -331,7 +348,7 @@ TEST_F(DumpsysTest, DumpWithArgsRunningService) { CallMain({"SERVICE", "Y", "U", "NO", "HANDLE", "ARGS"}); AssertOutputContains("I DO!"); AssertOutput("I DO!"); } // Tests dumpsys passes the -a flag when called on all services Loading Loading @@ -522,6 +539,23 @@ TEST_F(DumpsysTest, DumpWithPriorityHighAndProto) { AssertDumpedWithPriority("runninghigh2", "dump2", PriorityDumper::PRIORITY_ARG_HIGH); } TEST_F(DumpsysTest, GetBytesWritten) { const char* serviceName = "service2"; const char* dumpContents = "dump1"; ExpectDump(serviceName, dumpContents); String16 service(serviceName); Vector<String16> args; std::chrono::duration<double> elapsedDuration; size_t bytesWritten; CallSingleService(service, args, IServiceManager::DUMP_FLAG_PRIORITY_ALL, /* as_proto = */ false, elapsedDuration, bytesWritten); AssertOutput(dumpContents); EXPECT_THAT(bytesWritten, Eq(strlen(dumpContents))); } TEST_F(DumpsysTest, WriteDumpWithoutThreadStart) { std::chrono::duration<double> elapsedDuration; size_t bytesWritten; Loading