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

Commit 7951dcd1 authored by Steven Moreland's avatar Steven Moreland Committed by gitbuildkicker
Browse files

Dumpstate: dump HAL native traces processes.

Test: hal service dumps in data/anr/bugreport-traces.txt after bugreport
Bug: 36414311
Change-Id: Ifca491d02f77bf4fb26450f06c2ea02769475786
(cherry picked from commit 17b29e1a)
parent 1375b7e0
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@ COMMON_SRC_FILES := \
        utils.cpp
COMMON_SHARED_LIBRARIES := \
        android.hardware.dumpstate@1.0 \
        android.hidl.manager@1.0 \
        libhidlbase \
        libbase \
        libbinder \
+53 −1
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@
#include <time.h>
#include <unistd.h>

#include <set>
#include <string>
#include <vector>

@@ -45,6 +46,7 @@
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <android/hidl/manager/1.0/IServiceManager.h>
#include <cutils/properties.h>
#include <cutils/sockets.h>
#include <debuggerd/client.h>
@@ -87,6 +89,16 @@ static const char* native_processes_to_dump[] = {
        NULL,
};

/* list of hal interface to dump containing process during native dumps */
static const char* hal_interfaces_to_dump[] {
        "android.hardware.audio@2.0::IDevicesFactory",
        "android.hardware.bluetooth@1.0::IBluetoothHci",
        "android.hardware.camera.provider@2.4::ICameraProvider",
        "android.hardware.vr@1.0::IVr",
        "android.hardware.media.omx@1.0::IOmx",
        NULL,
};

// Reasonable value for max stats.
static const int STATS_MAX_N_RUNS = 1000;
static const long STATS_MAX_AVERAGE = 100000;
@@ -792,6 +804,15 @@ void redirect_to_existing_file(FILE *redirect, char *path) {
    _redirect_to_file(redirect, path, O_APPEND);
}

static bool should_dump_hal_interface(const char* interface) {
    for (const char** i = hal_interfaces_to_dump; *i; i++) {
        if (!strcmp(*i, interface)) {
            return true;
        }
    }
    return false;
}

static bool should_dump_native_traces(const char* path) {
    for (const char** p = native_processes_to_dump; *p; p++) {
        if (!strcmp(*p, path)) {
@@ -801,6 +822,35 @@ static bool should_dump_native_traces(const char* path) {
    return false;
}

std::set<int> get_interesting_hal_pids() {
    using android::hidl::manager::V1_0::IServiceManager;
    using android::sp;
    using android::hardware::Return;

    sp<IServiceManager> manager = IServiceManager::getService();
    std::set<int> pids;

    Return<void> ret = manager->debugDump([&](auto& hals) {
        for (const auto &info : hals) {
            if (info.pid == static_cast<int>(IServiceManager::PidConstant::NO_PID)) {
                continue;
            }

            if (!should_dump_hal_interface(info.interfaceName)) {
                continue;
            }

            pids.insert(info.pid);
        }
    });

    if (!ret.isOk()) {
        MYLOGE("Could not get list of HAL PIDs: %s\n", ret.description().c_str());
    }

    return pids; // whether it was okay or not
}

/* dump Dalvik and native stack traces, return the trace file location (NULL if none) */
const char *dump_traces() {
    DurationReporter duration_reporter("DUMP TRACES");
@@ -835,6 +885,7 @@ const char *dump_traces() {
    /* Variables below must be initialized before 'goto' statements */
    int dalvik_found = 0;
    int ifd, wfd = -1;
    std::set<int> hal_pids = get_interesting_hal_pids();

    /* walk /proc and kill -QUIT all Dalvik processes */
    DIR *proc = opendir("/proc");
@@ -909,7 +960,8 @@ const char *dump_traces() {
                dprintf(fd, "[dump dalvik stack %d: %.3fs elapsed]\n", pid,
                        (float)(Nanotime() - start) / NANOS_PER_SEC);
            }
        } else if (should_dump_native_traces(data)) {
        } else if (should_dump_native_traces(data) ||
                   hal_pids.find(pid) != hal_pids.end()) {
            /* dump native process if appropriate */
            if (lseek(fd, 0, SEEK_END) < 0) {
                MYLOGE("lseek: %s\n", strerror(errno));