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

Commit 1bdb0b3f authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 5367932 from dde31327 to qt-release

Change-Id: Ie8cf0cbb79567fbc78e631be2ad4ec1e7bdaa521
parents 2e843850 dde31327
Loading
Loading
Loading
Loading
+111 −1
Original line number Diff line number Diff line
@@ -54,7 +54,9 @@
#include <android/os/IIncidentCompanion.h>
#include <cutils/native_handle.h>
#include <cutils/properties.h>
#include <debuggerd/client.h>
#include <dumpsys.h>
#include <dumputils/dump_utils.h>
#include <hidl/ServiceManagement.h>
#include <openssl/sha.h>
#include <private/android_filesystem_config.h>
@@ -1450,7 +1452,7 @@ static bool DumpstateDefault() {
    RunDumpsysCritical();

    /* collect stack traces from Dalvik and native processes (needs root) */
    dump_traces_path = dump_traces();
    dump_traces_path = ds.DumpTraces();

    /* Run some operations that require root. */
    ds.tombstone_data_ = GetDumpFds(TOMBSTONE_DIR, TOMBSTONE_FILE_PREFIX, !ds.IsZipping());
@@ -1587,6 +1589,114 @@ static void DumpstateWifiOnly() {
    printf("========================================================\n");
}

const char* Dumpstate::DumpTraces() {
    DurationReporter duration_reporter("DUMP TRACES");

    const std::string temp_file_pattern = "/data/anr/dumptrace_XXXXXX";
    const size_t buf_size = temp_file_pattern.length() + 1;
    std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
    memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);

    // Create a new, empty file to receive all trace dumps.
    //
    // TODO: This can be simplified once we remove support for the old style
    // dumps. We can have a file descriptor passed in to dump_traces instead
    // of creating a file, closing it and then reopening it again.
    android::base::unique_fd fd(mkostemp(file_name_buf.get(), O_APPEND | O_CLOEXEC));
    if (fd < 0) {
        MYLOGE("mkostemp on pattern %s: %s\n", file_name_buf.get(), strerror(errno));
        return nullptr;
    }

    // Nobody should have access to this temporary file except dumpstate, but we
    // temporarily grant 'read' to 'others' here because this file is created
    // when tombstoned is still running as root, but dumped after dropping. This
    // can go away once support for old style dumping has.
    const int chmod_ret = fchmod(fd, 0666);
    if (chmod_ret < 0) {
        MYLOGE("fchmod on %s failed: %s\n", file_name_buf.get(), strerror(errno));
        return nullptr;
    }

    std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
    if (proc.get() == nullptr) {
        MYLOGE("opendir /proc failed: %s\n", strerror(errno));
        return nullptr;
    }

    // Number of times process dumping has timed out. If we encounter too many
    // failures, we'll give up.
    int timeout_failures = 0;
    bool dalvik_found = false;

    const std::set<int> hal_pids = get_interesting_hal_pids();

    struct dirent* d;
    while ((d = readdir(proc.get()))) {
        int pid = atoi(d->d_name);
        if (pid <= 0) {
            continue;
        }

        const std::string link_name = android::base::StringPrintf("/proc/%d/exe", pid);
        std::string exe;
        if (!android::base::Readlink(link_name, &exe)) {
            continue;
        }

        bool is_java_process;
        if (exe == "/system/bin/app_process32" || exe == "/system/bin/app_process64") {
            // Don't bother dumping backtraces for the zygote.
            if (IsZygote(pid)) {
                continue;
            }

            dalvik_found = true;
            is_java_process = true;
        } else if (should_dump_native_traces(exe.c_str()) || hal_pids.find(pid) != hal_pids.end()) {
            is_java_process = false;
        } else {
            // Probably a native process we don't care about, continue.
            continue;
        }

        // If 3 backtrace dumps fail in a row, consider debuggerd dead.
        if (timeout_failures == 3) {
            dprintf(fd, "ERROR: Too many stack dump failures, exiting.\n");
            break;
        }

        const uint64_t start = Nanotime();
        const int ret = dump_backtrace_to_file_timeout(
            pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace,
            is_java_process ? 5 : 20, fd);

        if (ret == -1) {
            // For consistency, the header and footer to this message match those
            // dumped by debuggerd in the success case.
            dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
            dprintf(fd, "Dump failed, likely due to a timeout.\n");
            dprintf(fd, "---- end %d ----", pid);
            timeout_failures++;
            continue;
        }

        // We've successfully dumped stack traces, reset the failure count
        // and write a summary of the elapsed time to the file and continue with the
        // next process.
        timeout_failures = 0;

        dprintf(fd, "[dump %s stack %d: %.3fs elapsed]\n", is_java_process ? "dalvik" : "native",
                pid, (float)(Nanotime() - start) / NANOS_PER_SEC);
    }

    if (!dalvik_found) {
        MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
    }

    return file_name_buf.release();
}

void Dumpstate::DumpstateBoard() {
    DurationReporter duration_reporter("dumpstate_board()");
    printf("========================================================\n");
+5 −5
Original line number Diff line number Diff line
@@ -73,13 +73,13 @@ extern "C" {
 */
class DurationReporter {
  public:
    explicit DurationReporter(const std::string& title, bool log_only = false);
    explicit DurationReporter(const std::string& title, bool logcat_only = false);

    ~DurationReporter();

  private:
    std::string title_;
    bool log_only_;
    bool logcat_only_;
    uint64_t started_;

    DISALLOW_COPY_AND_ASSIGN(DurationReporter);
@@ -291,6 +291,9 @@ class Dumpstate {
    // TODO: temporary method until Dumpstate object is properly set
    void SetProgress(std::unique_ptr<Progress> progress);

    // Dumps Dalvik and native stack traces, return the trace file location (nullptr if none).
    const char* DumpTraces();

    void DumpstateBoard();

    /*
@@ -543,9 +546,6 @@ bool redirect_to_existing_file(FILE* redirect, char* path);
/* create leading directories, if necessary */
void create_parent_dirs(const char *path);

/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
const char *dump_traces();

/* for each process in the system, run the specified function */
void for_each_pid(for_each_pid_func func, const char *header);

+8 −121
Original line number Diff line number Diff line
@@ -50,8 +50,6 @@
#include <android-base/unique_fd.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <debuggerd/client.h>
#include <dumputils/dump_utils.h>
#include <log/log.h>
#include <private/android_filesystem_config.h>

@@ -95,8 +93,8 @@ Dumpstate& Dumpstate::GetInstance() {
    return singleton_;
}

DurationReporter::DurationReporter(const std::string& title, bool log_only)
    : title_(title), log_only_(log_only) {
DurationReporter::DurationReporter(const std::string& title, bool logcat_only)
    : title_(title), logcat_only_(logcat_only) {
    if (!title_.empty()) {
        started_ = Nanotime();
    }
@@ -105,17 +103,15 @@ DurationReporter::DurationReporter(const std::string& title, bool log_only)
DurationReporter::~DurationReporter() {
    if (!title_.empty()) {
        uint64_t elapsed = Nanotime() - started_;
        if (log_only_) {
            MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
        } else {
            // TODO(124089395): Remove or rewrite when bugreport latency is fixed.
        MYLOGD("Duration of '%s': %.3fs\n", title_.c_str(), (float)elapsed / NANOS_PER_SEC);
        if (logcat_only_) {
            return;
        }
        // Use "Yoda grammar" to make it easier to grep|sort sections.
        printf("------ %.3fs was the duration of '%s' ------\n", (float)elapsed / NANOS_PER_SEC,
               title_.c_str());
    }
}
}

const int32_t Progress::kDefaultMax = 5000;

@@ -795,115 +791,6 @@ bool redirect_to_existing_file(FILE* redirect, char* path) {
    return _redirect_to_file(redirect, path, O_APPEND);
}

// Dump Dalvik and native stack traces, return the trace file location (nullptr if none).
const char* dump_traces() {
    DurationReporter duration_reporter("DUMP TRACES");

    const std::string temp_file_pattern = "/data/anr/dumptrace_XXXXXX";
    const size_t buf_size = temp_file_pattern.length() + 1;
    std::unique_ptr<char[]> file_name_buf(new char[buf_size]);
    memcpy(file_name_buf.get(), temp_file_pattern.c_str(), buf_size);

    // Create a new, empty file to receive all trace dumps.
    //
    // TODO: This can be simplified once we remove support for the old style
    // dumps. We can have a file descriptor passed in to dump_traces instead
    // of creating a file, closing it and then reopening it again.
    android::base::unique_fd fd(mkostemp(file_name_buf.get(), O_APPEND | O_CLOEXEC));
    if (fd < 0) {
        MYLOGE("mkostemp on pattern %s: %s\n", file_name_buf.get(), strerror(errno));
        return nullptr;
    }

    // Nobody should have access to this temporary file except dumpstate, but we
    // temporarily grant 'read' to 'others' here because this file is created
    // when tombstoned is still running as root, but dumped after dropping. This
    // can go away once support for old style dumping has.
    const int chmod_ret = fchmod(fd, 0666);
    if (chmod_ret < 0) {
        MYLOGE("fchmod on %s failed: %s\n", file_name_buf.get(), strerror(errno));
        return nullptr;
    }

    std::unique_ptr<DIR, decltype(&closedir)> proc(opendir("/proc"), closedir);
    if (proc.get() == nullptr) {
        MYLOGE("opendir /proc failed: %s\n", strerror(errno));
        return nullptr;
    }

    // Number of times process dumping has timed out. If we encounter too many
    // failures, we'll give up.
    int timeout_failures = 0;
    bool dalvik_found = false;

    const std::set<int> hal_pids = get_interesting_hal_pids();

    struct dirent* d;
    while ((d = readdir(proc.get()))) {
        int pid = atoi(d->d_name);
        if (pid <= 0) {
            continue;
        }

        const std::string link_name = android::base::StringPrintf("/proc/%d/exe", pid);
        std::string exe;
        if (!android::base::Readlink(link_name, &exe)) {
            continue;
        }

        bool is_java_process;
        if (exe == "/system/bin/app_process32" || exe == "/system/bin/app_process64") {
            // Don't bother dumping backtraces for the zygote.
            if (IsZygote(pid)) {
                continue;
            }

            dalvik_found = true;
            is_java_process = true;
        } else if (should_dump_native_traces(exe.c_str()) || hal_pids.find(pid) != hal_pids.end()) {
            is_java_process = false;
        } else {
            // Probably a native process we don't care about, continue.
            continue;
        }

        // If 3 backtrace dumps fail in a row, consider debuggerd dead.
        if (timeout_failures == 3) {
            dprintf(fd, "ERROR: Too many stack dump failures, exiting.\n");
            break;
        }

        const uint64_t start = Nanotime();
        const int ret = dump_backtrace_to_file_timeout(
            pid, is_java_process ? kDebuggerdJavaBacktrace : kDebuggerdNativeBacktrace,
            is_java_process ? 5 : 20, fd);

        if (ret == -1) {
            // For consistency, the header and footer to this message match those
            // dumped by debuggerd in the success case.
            dprintf(fd, "\n---- pid %d at [unknown] ----\n", pid);
            dprintf(fd, "Dump failed, likely due to a timeout.\n");
            dprintf(fd, "---- end %d ----", pid);
            timeout_failures++;
            continue;
        }

        // We've successfully dumped stack traces, reset the failure count
        // and write a summary of the elapsed time to the file and continue with the
        // next process.
        timeout_failures = 0;

        dprintf(fd, "[dump %s stack %d: %.3fs elapsed]\n", is_java_process ? "dalvik" : "native",
                pid, (float)(Nanotime() - start) / NANOS_PER_SEC);
    }

    if (!dalvik_found) {
        MYLOGE("Warning: no Dalvik processes found to dump stacks\n");
    }

    return file_name_buf.release();
}

void dump_route_tables() {
    DurationReporter duration_reporter("DUMP ROUTE TABLES");
    if (PropertiesHelper::IsDryRun()) return;
+2 −0
Original line number Diff line number Diff line
@@ -3,6 +3,8 @@ set noparent
agampe@google.com
calin@google.com
jsharkey@android.com
maco@google.com
mathieuc@google.com
narayan@google.com
ngeoffray@google.com
toddke@google.com
+1 −1
Original line number Diff line number Diff line
@@ -100,7 +100,7 @@ int32_t SensorService::SensorDirectConnection::configureChannel(int handle, int
        return NO_ERROR;
    }

    if (mService->isOperationRestricted(mOpPackageName)) {
    if (!mService->isOperationPermitted(mOpPackageName)) {
        return PERMISSION_DENIED;
    }

Loading