Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a7ffd752 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Support dumpsys timeouts in milliseconds"

parents 03896e88 6921f80f
Loading
Loading
Loading
Loading
+21 −12
Original line number Diff line number Diff line
@@ -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);
@@ -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));
@@ -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() {
@@ -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),
@@ -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 {
@@ -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_ = "";
@@ -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;
@@ -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);
+21 −6
Original line number Diff line number Diff line
@@ -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 {
@@ -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_;
@@ -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. */
@@ -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;
+16 −17
Original line number Diff line number Diff line
@@ -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);
@@ -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"});

+3 −3
Original line number Diff line number Diff line
@@ -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.
+12 −1
Original line number Diff line number Diff line
@@ -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()));
@@ -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