Loading cmds/dumpstate/DumpstateUtil.cpp +21 −12 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ namespace { static constexpr const char* kSuPath = "/system/xbin/su"; static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) { static bool waitpid_with_timeout(pid_t pid, int timeout_ms, int* status) { sigset_t child_mask, old_mask; sigemptyset(&child_mask); sigaddset(&child_mask, SIGCHLD); Loading @@ -54,10 +54,11 @@ static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) { } timespec ts; ts.tv_sec = timeout_seconds; ts.tv_nsec = 0; ts.tv_sec = MSEC_TO_SEC(timeout_ms); ts.tv_nsec = (timeout_ms % 1000) * 1000000; int ret = TEMP_FAILURE_RETRY(sigtimedwait(&child_mask, NULL, &ts)); int saved_errno = errno; // Set the signals back the way they were. if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) { printf("*** sigprocmask failed: %s\n", strerror(errno)); Loading Loading @@ -91,7 +92,7 @@ static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) { CommandOptions CommandOptions::DEFAULT = CommandOptions::WithTimeout(10).Build(); CommandOptions CommandOptions::AS_ROOT = CommandOptions::WithTimeout(10).AsRoot().Build(); CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(int64_t timeout) : values(timeout) { CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(int64_t timeout_ms) : values(timeout_ms) { } CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::Always() { Loading Loading @@ -130,8 +131,8 @@ CommandOptions CommandOptions::CommandOptionsBuilder::Build() { return CommandOptions(values); } CommandOptions::CommandOptionsValues::CommandOptionsValues(int64_t timeout) : timeout_(timeout), CommandOptions::CommandOptionsValues::CommandOptionsValues(int64_t timeout_ms) : timeout_ms_(timeout_ms), always_(false), account_mode_(DONT_DROP_ROOT), output_mode_(NORMAL_OUTPUT), Loading @@ -142,7 +143,11 @@ CommandOptions::CommandOptions(const CommandOptionsValues& values) : values(valu } int64_t CommandOptions::Timeout() const { return values.timeout_; return MSEC_TO_SEC(values.timeout_ms_); } int64_t CommandOptions::TimeoutInMs() const { return values.timeout_ms_; } bool CommandOptions::Always() const { Loading @@ -161,8 +166,12 @@ std::string CommandOptions::LoggingMessage() const { return values.logging_message_; } CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(int64_t timeout) { return CommandOptions::CommandOptionsBuilder(timeout); CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(int64_t timeout_sec) { return CommandOptions::CommandOptionsBuilder(SEC_TO_MSEC(timeout_sec)); } CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeoutInMs(int64_t timeout_ms) { return CommandOptions::CommandOptionsBuilder(timeout_ms); } std::string PropertiesHelper::build_type_ = ""; Loading Loading @@ -314,7 +323,7 @@ int RunCommandToFd(int fd, const std::string& title, const std::vector<std::stri /* handle parent case */ int status; bool ret = waitpid_with_timeout(pid, options.Timeout(), &status); bool ret = waitpid_with_timeout(pid, options.TimeoutInMs(), &status); fsync(fd); uint64_t elapsed = Nanotime() - start; Loading @@ -333,9 +342,9 @@ int RunCommandToFd(int fd, const std::string& title, const std::vector<std::stri static_cast<float>(elapsed) / NANOS_PER_SEC, pid); } kill(pid, SIGTERM); if (!waitpid_with_timeout(pid, 5, nullptr)) { if (!waitpid_with_timeout(pid, 5000, nullptr)) { kill(pid, SIGKILL); if (!waitpid_with_timeout(pid, 5, nullptr)) { if (!waitpid_with_timeout(pid, 5000, nullptr)) { if (!silent) dprintf(fd, "could not kill command '%s' (pid %d) even with SIGKILL.\n", command, pid); Loading cmds/dumpstate/DumpstateUtil.h +21 −6 Original line number Diff line number Diff line Loading @@ -19,6 +19,16 @@ #include <cstdint> #include <string> /* * Converts seconds to milliseconds. */ #define SEC_TO_MSEC(second) (second * 1000) /* * Converts milliseconds to seconds. */ #define MSEC_TO_SEC(millisecond) (millisecond / 1000) namespace android { namespace os { namespace dumpstate { Loading Loading @@ -66,9 +76,9 @@ class CommandOptions { private: class CommandOptionsValues { private: CommandOptionsValues(int64_t timeout); CommandOptionsValues(int64_t timeout_ms); int64_t timeout_; int64_t timeout_ms_; bool always_; PrivilegeMode account_mode_; OutputMode output_mode_; Loading Loading @@ -102,13 +112,15 @@ class CommandOptions { CommandOptions Build(); private: CommandOptionsBuilder(int64_t timeout); CommandOptionsBuilder(int64_t timeout_ms); CommandOptionsValues values; friend class CommandOptions; }; /** Gets the command timeout, in seconds. */ /** Gets the command timeout in seconds. */ int64_t Timeout() const; /** Gets the command timeout in milliseconds. */ int64_t TimeoutInMs() const; /* Checks whether the command should always be run, even on dry-run mode. */ bool Always() const; /** Gets the PrivilegeMode of the command. */ Loading @@ -118,8 +130,11 @@ class CommandOptions { /** Gets the logging message header, it any. */ std::string LoggingMessage() const; /** Creates a builder with the requied timeout. */ static CommandOptionsBuilder WithTimeout(int64_t timeout); /** Creates a builder with the requied timeout in seconds. */ static CommandOptionsBuilder WithTimeout(int64_t timeout_sec); /** Creates a builder with the requied timeout in milliseconds. */ static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms); // Common options. static CommandOptions DEFAULT; Loading cmds/dumpstate/dumpstate.cpp +16 −17 Original line number Diff line number Diff line Loading @@ -113,8 +113,8 @@ static int RunCommand(const std::string& title, const std::vector<std::string>& } static void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsysArgs, const CommandOptions& options = Dumpstate::DEFAULT_DUMPSYS, long dumpsysTimeout = 0) { return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeout); long dumpsysTimeoutMs = 0) { return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeoutMs); } static int DumpFile(const std::string& title, const std::string& path) { return ds.DumpFile(title, path); Loading Loading @@ -830,33 +830,32 @@ static void DoKmsg() { } static void DoLogcat() { unsigned long timeout; unsigned long timeout_ms; // DumpFile("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout < 20000) { timeout = 20000; timeout_ms = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout_ms < 20000) { timeout_ms = 20000; } RunCommand("SYSTEM LOG", {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeout(timeout / 1000).Build()); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeoutInMs(timeout_ms).Build()); timeout_ms = logcat_timeout("events"); if (timeout_ms < 20000) { timeout_ms = 20000; } RunCommand("EVENT LOG", {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeout(timeout / 1000).Build()); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; CommandOptions::WithTimeoutInMs(timeout_ms).Build()); timeout_ms = logcat_timeout("radio"); if (timeout_ms < 20000) { timeout_ms = 20000; } RunCommand("RADIO LOG", {"logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeout(timeout / 1000).Build()); CommandOptions::WithTimeoutInMs(timeout_ms).Build()); RunCommand("LOG STATISTICS", {"logcat", "-b", "all", "-S"}); Loading cmds/dumpstate/dumpstate.h +3 −3 Original line number Diff line number Diff line Loading @@ -196,19 +196,19 @@ class Dumpstate { /* * Runs `dumpsys` with the given arguments, automatically setting its timeout * (`-t` argument) * (`-T` argument) * according to the command options. * * |title| description of the command printed on `stdout` (or empty to skip * description). * |dumpsys_args| `dumpsys` arguments (except `-t`). * |options| optional argument defining the command's behavior. * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -t` (otherwise it uses the * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -T` (otherwise it uses the * timeout from `options`) */ void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args, const android::os::dumpstate::CommandOptions& options = DEFAULT_DUMPSYS, long dumpsys_timeout = 0); long dumpsys_timeout_ms = 0); /* * Prints the contents of a file. Loading cmds/dumpstate/tests/dumpstate_test.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -1001,7 +1001,7 @@ TEST_F(DumpstateUtilTest, RunCommandCrashes) { err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code")); } TEST_F(DumpstateUtilTest, RunCommandTimesout) { TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) { CreateFd("RunCommandTimesout.txt"); EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"}, CommandOptions::WithTimeout(1).Build())); Loading @@ -1011,6 +1011,17 @@ TEST_F(DumpstateUtilTest, RunCommandTimesout) { " --sleep 2' timed out after 1")); } TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) { CreateFd("RunCommandTimesout.txt"); EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"}, CommandOptions::WithTimeoutInMs(1000).Build())); EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand + " --sleep 2' timed out after 1")); EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand + " --sleep 2' timed out after 1")); } TEST_F(DumpstateUtilTest, RunCommandIsKilled) { CreateFd("RunCommandIsKilled.txt"); CaptureStderr(); Loading Loading
cmds/dumpstate/DumpstateUtil.cpp +21 −12 Original line number Diff line number Diff line Loading @@ -43,7 +43,7 @@ namespace { static constexpr const char* kSuPath = "/system/xbin/su"; static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) { static bool waitpid_with_timeout(pid_t pid, int timeout_ms, int* status) { sigset_t child_mask, old_mask; sigemptyset(&child_mask); sigaddset(&child_mask, SIGCHLD); Loading @@ -54,10 +54,11 @@ static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) { } timespec ts; ts.tv_sec = timeout_seconds; ts.tv_nsec = 0; ts.tv_sec = MSEC_TO_SEC(timeout_ms); ts.tv_nsec = (timeout_ms % 1000) * 1000000; int ret = TEMP_FAILURE_RETRY(sigtimedwait(&child_mask, NULL, &ts)); int saved_errno = errno; // Set the signals back the way they were. if (sigprocmask(SIG_SETMASK, &old_mask, NULL) == -1) { printf("*** sigprocmask failed: %s\n", strerror(errno)); Loading Loading @@ -91,7 +92,7 @@ static bool waitpid_with_timeout(pid_t pid, int timeout_seconds, int* status) { CommandOptions CommandOptions::DEFAULT = CommandOptions::WithTimeout(10).Build(); CommandOptions CommandOptions::AS_ROOT = CommandOptions::WithTimeout(10).AsRoot().Build(); CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(int64_t timeout) : values(timeout) { CommandOptions::CommandOptionsBuilder::CommandOptionsBuilder(int64_t timeout_ms) : values(timeout_ms) { } CommandOptions::CommandOptionsBuilder& CommandOptions::CommandOptionsBuilder::Always() { Loading Loading @@ -130,8 +131,8 @@ CommandOptions CommandOptions::CommandOptionsBuilder::Build() { return CommandOptions(values); } CommandOptions::CommandOptionsValues::CommandOptionsValues(int64_t timeout) : timeout_(timeout), CommandOptions::CommandOptionsValues::CommandOptionsValues(int64_t timeout_ms) : timeout_ms_(timeout_ms), always_(false), account_mode_(DONT_DROP_ROOT), output_mode_(NORMAL_OUTPUT), Loading @@ -142,7 +143,11 @@ CommandOptions::CommandOptions(const CommandOptionsValues& values) : values(valu } int64_t CommandOptions::Timeout() const { return values.timeout_; return MSEC_TO_SEC(values.timeout_ms_); } int64_t CommandOptions::TimeoutInMs() const { return values.timeout_ms_; } bool CommandOptions::Always() const { Loading @@ -161,8 +166,12 @@ std::string CommandOptions::LoggingMessage() const { return values.logging_message_; } CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(int64_t timeout) { return CommandOptions::CommandOptionsBuilder(timeout); CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeout(int64_t timeout_sec) { return CommandOptions::CommandOptionsBuilder(SEC_TO_MSEC(timeout_sec)); } CommandOptions::CommandOptionsBuilder CommandOptions::WithTimeoutInMs(int64_t timeout_ms) { return CommandOptions::CommandOptionsBuilder(timeout_ms); } std::string PropertiesHelper::build_type_ = ""; Loading Loading @@ -314,7 +323,7 @@ int RunCommandToFd(int fd, const std::string& title, const std::vector<std::stri /* handle parent case */ int status; bool ret = waitpid_with_timeout(pid, options.Timeout(), &status); bool ret = waitpid_with_timeout(pid, options.TimeoutInMs(), &status); fsync(fd); uint64_t elapsed = Nanotime() - start; Loading @@ -333,9 +342,9 @@ int RunCommandToFd(int fd, const std::string& title, const std::vector<std::stri static_cast<float>(elapsed) / NANOS_PER_SEC, pid); } kill(pid, SIGTERM); if (!waitpid_with_timeout(pid, 5, nullptr)) { if (!waitpid_with_timeout(pid, 5000, nullptr)) { kill(pid, SIGKILL); if (!waitpid_with_timeout(pid, 5, nullptr)) { if (!waitpid_with_timeout(pid, 5000, nullptr)) { if (!silent) dprintf(fd, "could not kill command '%s' (pid %d) even with SIGKILL.\n", command, pid); Loading
cmds/dumpstate/DumpstateUtil.h +21 −6 Original line number Diff line number Diff line Loading @@ -19,6 +19,16 @@ #include <cstdint> #include <string> /* * Converts seconds to milliseconds. */ #define SEC_TO_MSEC(second) (second * 1000) /* * Converts milliseconds to seconds. */ #define MSEC_TO_SEC(millisecond) (millisecond / 1000) namespace android { namespace os { namespace dumpstate { Loading Loading @@ -66,9 +76,9 @@ class CommandOptions { private: class CommandOptionsValues { private: CommandOptionsValues(int64_t timeout); CommandOptionsValues(int64_t timeout_ms); int64_t timeout_; int64_t timeout_ms_; bool always_; PrivilegeMode account_mode_; OutputMode output_mode_; Loading Loading @@ -102,13 +112,15 @@ class CommandOptions { CommandOptions Build(); private: CommandOptionsBuilder(int64_t timeout); CommandOptionsBuilder(int64_t timeout_ms); CommandOptionsValues values; friend class CommandOptions; }; /** Gets the command timeout, in seconds. */ /** Gets the command timeout in seconds. */ int64_t Timeout() const; /** Gets the command timeout in milliseconds. */ int64_t TimeoutInMs() const; /* Checks whether the command should always be run, even on dry-run mode. */ bool Always() const; /** Gets the PrivilegeMode of the command. */ Loading @@ -118,8 +130,11 @@ class CommandOptions { /** Gets the logging message header, it any. */ std::string LoggingMessage() const; /** Creates a builder with the requied timeout. */ static CommandOptionsBuilder WithTimeout(int64_t timeout); /** Creates a builder with the requied timeout in seconds. */ static CommandOptionsBuilder WithTimeout(int64_t timeout_sec); /** Creates a builder with the requied timeout in milliseconds. */ static CommandOptionsBuilder WithTimeoutInMs(int64_t timeout_ms); // Common options. static CommandOptions DEFAULT; Loading
cmds/dumpstate/dumpstate.cpp +16 −17 Original line number Diff line number Diff line Loading @@ -113,8 +113,8 @@ static int RunCommand(const std::string& title, const std::vector<std::string>& } static void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsysArgs, const CommandOptions& options = Dumpstate::DEFAULT_DUMPSYS, long dumpsysTimeout = 0) { return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeout); long dumpsysTimeoutMs = 0) { return ds.RunDumpsys(title, dumpsysArgs, options, dumpsysTimeoutMs); } static int DumpFile(const std::string& title, const std::string& path) { return ds.DumpFile(title, path); Loading Loading @@ -830,33 +830,32 @@ static void DoKmsg() { } static void DoLogcat() { unsigned long timeout; unsigned long timeout_ms; // DumpFile("EVENT LOG TAGS", "/etc/event-log-tags"); // calculate timeout timeout = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout < 20000) { timeout = 20000; timeout_ms = logcat_timeout("main") + logcat_timeout("system") + logcat_timeout("crash"); if (timeout_ms < 20000) { timeout_ms = 20000; } RunCommand("SYSTEM LOG", {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeout(timeout / 1000).Build()); timeout = logcat_timeout("events"); if (timeout < 20000) { timeout = 20000; {"logcat", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeoutInMs(timeout_ms).Build()); timeout_ms = logcat_timeout("events"); if (timeout_ms < 20000) { timeout_ms = 20000; } RunCommand("EVENT LOG", {"logcat", "-b", "events", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeout(timeout / 1000).Build()); timeout = logcat_timeout("radio"); if (timeout < 20000) { timeout = 20000; CommandOptions::WithTimeoutInMs(timeout_ms).Build()); timeout_ms = logcat_timeout("radio"); if (timeout_ms < 20000) { timeout_ms = 20000; } RunCommand("RADIO LOG", {"logcat", "-b", "radio", "-v", "threadtime", "-v", "printable", "-v", "uid", "-d", "*:v"}, CommandOptions::WithTimeout(timeout / 1000).Build()); CommandOptions::WithTimeoutInMs(timeout_ms).Build()); RunCommand("LOG STATISTICS", {"logcat", "-b", "all", "-S"}); Loading
cmds/dumpstate/dumpstate.h +3 −3 Original line number Diff line number Diff line Loading @@ -196,19 +196,19 @@ class Dumpstate { /* * Runs `dumpsys` with the given arguments, automatically setting its timeout * (`-t` argument) * (`-T` argument) * according to the command options. * * |title| description of the command printed on `stdout` (or empty to skip * description). * |dumpsys_args| `dumpsys` arguments (except `-t`). * |options| optional argument defining the command's behavior. * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -t` (otherwise it uses the * |dumpsys_timeout| when > 0, defines the value passed to `dumpsys -T` (otherwise it uses the * timeout from `options`) */ void RunDumpsys(const std::string& title, const std::vector<std::string>& dumpsys_args, const android::os::dumpstate::CommandOptions& options = DEFAULT_DUMPSYS, long dumpsys_timeout = 0); long dumpsys_timeout_ms = 0); /* * Prints the contents of a file. Loading
cmds/dumpstate/tests/dumpstate_test.cpp +12 −1 Original line number Diff line number Diff line Loading @@ -1001,7 +1001,7 @@ TEST_F(DumpstateUtilTest, RunCommandCrashes) { err, StartsWith("stderr\n*** command '" + kSimpleCommand + " --crash' failed: exit code")); } TEST_F(DumpstateUtilTest, RunCommandTimesout) { TEST_F(DumpstateUtilTest, RunCommandTimesoutWithSec) { CreateFd("RunCommandTimesout.txt"); EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"}, CommandOptions::WithTimeout(1).Build())); Loading @@ -1011,6 +1011,17 @@ TEST_F(DumpstateUtilTest, RunCommandTimesout) { " --sleep 2' timed out after 1")); } TEST_F(DumpstateUtilTest, RunCommandTimesoutWithMsec) { CreateFd("RunCommandTimesout.txt"); EXPECT_EQ(-1, RunCommand("", {kSimpleCommand, "--sleep", "2"}, CommandOptions::WithTimeoutInMs(1000).Build())); EXPECT_THAT(out, StartsWith("stdout line1\n*** command '" + kSimpleCommand + " --sleep 2' timed out after 1")); EXPECT_THAT(err, StartsWith("sleeping for 2s\n*** command '" + kSimpleCommand + " --sleep 2' timed out after 1")); } TEST_F(DumpstateUtilTest, RunCommandIsKilled) { CreateFd("RunCommandIsKilled.txt"); CaptureStderr(); Loading