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

Commit 7dbe9660 authored by Christopher Ferris's avatar Christopher Ferris Committed by Gerrit Code Review
Browse files

Merge "Update debuggerd to use libbacktrace."

parents 79b277ab 365e4ae7
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -24,11 +24,11 @@ LOCAL_CFLAGS += -DWITH_VFP_D32
endif # ARCH_ARM_HAVE_VFP_D32

LOCAL_SHARED_LIBRARIES := \
	libbacktrace \
	libc \
	libcutils \
	liblog \
	libc \
	libcorkscrew \
	libselinux
	libselinux \

include $(BUILD_EXECUTABLE)

+19 −25
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@
#endif
#endif

static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scopeFlags) {
static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scope_flags) {
    char code_buffer[64];       /* actual 8+1+((8+1)*4) + 1 == 45 */
    char ascii_buffer[32];      /* actual 16 + 1 == 17 */
    uintptr_t p, end;
@@ -102,7 +102,7 @@ static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scopeFlags) {
            p += 4;
        }
        *asc_out = '\0';
        _LOG(log, scopeFlags, "    %s %s\n", code_buffer, ascii_buffer);
        _LOG(log, scope_flags, "    %s %s\n", code_buffer, ascii_buffer);
    }
}

@@ -110,16 +110,13 @@ static void dump_memory(log_t* log, pid_t tid, uintptr_t addr, int scopeFlags) {
 * If configured to do so, dump memory around *all* registers
 * for the crashing thread.
 */
void dump_memory_and_code(const ptrace_context_t* context __attribute((unused)),
        log_t* log, pid_t tid, bool at_fault) {
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) {
    struct pt_regs regs;
    if(ptrace(PTRACE_GETREGS, tid, 0, &regs)) {
        return;
    }

    int scopeFlags = at_fault ? SCOPE_AT_FAULT : 0;

    if (at_fault && DUMP_MEMORY_FOR_ALL_REGISTERS) {
    if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) {
        static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp";

        for (int reg = 0; reg < 14; reg++) {
@@ -134,39 +131,36 @@ void dump_memory_and_code(const ptrace_context_t* context __attribute((unused)),
                continue;
            }

            _LOG(log, scopeFlags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
            dump_memory(log, tid, addr, scopeFlags | SCOPE_SENSITIVE);
            _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", &REG_NAMES[reg * 2]);
            dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE);
        }
    }

    /* explicitly allow upload of code dump logging */
    _LOG(log, scopeFlags, "\ncode around pc:\n");
    dump_memory(log, tid, (uintptr_t)regs.ARM_pc, scopeFlags);
    _LOG(log, scope_flags, "\ncode around pc:\n");
    dump_memory(log, tid, (uintptr_t)regs.ARM_pc, scope_flags);

    if (regs.ARM_pc != regs.ARM_lr) {
        _LOG(log, scopeFlags, "\ncode around lr:\n");
        dump_memory(log, tid, (uintptr_t)regs.ARM_lr, scopeFlags);
        _LOG(log, scope_flags, "\ncode around lr:\n");
        dump_memory(log, tid, (uintptr_t)regs.ARM_lr, scope_flags);
    }
}

void dump_registers(const ptrace_context_t* context __attribute((unused)),
        log_t* log, pid_t tid, bool at_fault)
void dump_registers(log_t* log, pid_t tid, int scope_flags)
{
    struct pt_regs r;
    int scopeFlags = at_fault ? SCOPE_AT_FAULT : 0;

    if(ptrace(PTRACE_GETREGS, tid, 0, &r)) {
        _LOG(log, scopeFlags, "cannot get registers: %s\n", strerror(errno));
        _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
        return;
    }

    _LOG(log, scopeFlags, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",
    _LOG(log, scope_flags, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",
            (uint32_t)r.ARM_r0, (uint32_t)r.ARM_r1, (uint32_t)r.ARM_r2, (uint32_t)r.ARM_r3);
    _LOG(log, scopeFlags, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",
    _LOG(log, scope_flags, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",
            (uint32_t)r.ARM_r4, (uint32_t)r.ARM_r5, (uint32_t)r.ARM_r6, (uint32_t)r.ARM_r7);
    _LOG(log, scopeFlags, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",
    _LOG(log, scope_flags, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",
            (uint32_t)r.ARM_r8, (uint32_t)r.ARM_r9, (uint32_t)r.ARM_r10, (uint32_t)r.ARM_fp);
    _LOG(log, scopeFlags, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n",
    _LOG(log, scope_flags, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n",
            (uint32_t)r.ARM_ip, (uint32_t)r.ARM_sp, (uint32_t)r.ARM_lr,
            (uint32_t)r.ARM_pc, (uint32_t)r.ARM_cpsr);

@@ -175,14 +169,14 @@ void dump_registers(const ptrace_context_t* context __attribute((unused)),
    int i;

    if(ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
        _LOG(log, scopeFlags, "cannot get registers: %s\n", strerror(errno));
        _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno));
        return;
    }

    for (i = 0; i < NUM_VFP_REGS; i += 2) {
        _LOG(log, scopeFlags, "    d%-2d %016llx  d%-2d %016llx\n",
        _LOG(log, scope_flags, "    d%-2d %016llx  d%-2d %016llx\n",
                i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]);
    }
    _LOG(log, scopeFlags, "    scr %08lx\n", vfp_regs.fpscr);
    _LOG(log, scope_flags, "    scr %08lx\n", vfp_regs.fpscr);
#endif
}
+19 −22
Original line number Diff line number Diff line
@@ -27,13 +27,11 @@
#include <sys/types.h>
#include <sys/ptrace.h>

#include <corkscrew/backtrace.h>
#include <backtrace/backtrace.h>

#include "tombstone.h"
#include "backtrace.h"
#include "utility.h"

#define STACK_DEPTH 32

static void dump_process_header(log_t* log, pid_t pid) {
    char path[PATH_MAX];
    char procnamebuf[1024];
@@ -62,7 +60,7 @@ static void dump_process_footer(log_t* log, pid_t pid) {
    _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid);
}

static void dump_thread(log_t* log, pid_t tid, ptrace_context_t* context, bool attached,
static void dump_thread(log_t* log, pid_t tid, bool attached,
        bool* detach_failed, int* total_sleep_time_usec) {
    char path[PATH_MAX];
    char threadnamebuf[1024];
@@ -91,20 +89,12 @@ static void dump_thread(log_t* log, pid_t tid, ptrace_context_t* context, bool a

    wait_for_stop(tid, total_sleep_time_usec);

    backtrace_frame_t backtrace[STACK_DEPTH];
    ssize_t frames = unwind_backtrace_ptrace(tid, context, backtrace, 0, STACK_DEPTH);
    if (frames <= 0) {
        _LOG(log, SCOPE_AT_FAULT, "Could not obtain stack trace for thread.\n");
    backtrace_t backtrace;
    if (!backtrace_get_data(&backtrace, tid)) {
        _LOG(log, SCOPE_AT_FAULT, "Could not create backtrace context.\n");
    } else {
        backtrace_symbol_t backtrace_symbols[STACK_DEPTH];
        get_backtrace_symbols_ptrace(context, backtrace, frames, backtrace_symbols);
        for (size_t i = 0; i < (size_t)frames; i++) {
            char line[MAX_BACKTRACE_LINE_LENGTH];
            format_backtrace_line(i, &backtrace[i], &backtrace_symbols[i],
                    line, MAX_BACKTRACE_LINE_LENGTH);
            _LOG(log, SCOPE_AT_FAULT, "  %s\n", line);
        }
        free_backtrace_symbols(backtrace_symbols, frames);
        dump_backtrace_to_log(&backtrace, log, SCOPE_AT_FAULT, "  ");
        backtrace_free_data(&backtrace);
    }

    if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) {
@@ -120,9 +110,8 @@ void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed,
    log.amfd = amfd;
    log.quiet = true;

    ptrace_context_t* context = load_ptrace_context(tid);
    dump_process_header(&log, pid);
    dump_thread(&log, tid, context, true, detach_failed, total_sleep_time_usec);
    dump_thread(&log, tid, true, detach_failed, total_sleep_time_usec);

    char task_path[64];
    snprintf(task_path, sizeof(task_path), "/proc/%d/task", pid);
@@ -140,11 +129,19 @@ void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed,
                continue;
            }

            dump_thread(&log, new_tid, context, false, detach_failed, total_sleep_time_usec);
            dump_thread(&log, new_tid, false, detach_failed, total_sleep_time_usec);
        }
        closedir(d);
    }

    dump_process_footer(&log, pid);
    free_ptrace_context(context);
}

void dump_backtrace_to_log(const backtrace_t* backtrace, log_t* log,
                           int scope_flags, const char* prefix) {
    char buf[512];
    for (size_t i = 0; i < backtrace->num_frames; i++) {
        backtrace_format_frame_data(&backtrace->frames[i], i, buf, sizeof(buf));
        _LOG(log, scope_flags, "%s%s\n", prefix, buf);
    }
}
+7 −1
Original line number Diff line number Diff line
@@ -21,11 +21,17 @@
#include <stdbool.h>
#include <sys/types.h>

#include <corkscrew/ptrace.h>
#include <backtrace/backtrace.h>

#include "utility.h"

/* Dumps a backtrace using a format similar to what Dalvik uses so that the result
 * can be intermixed in a bug report. */
void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed,
        int* total_sleep_time_usec);

/* Dumps the backtrace in the backtrace data structure to the log. */
void dump_backtrace_to_log(const backtrace_t* backtrace, log_t* log,
        int scope_flags, const char* prefix);

#endif // _DEBUGGERD_BACKTRACE_H
+2 −6
Original line number Diff line number Diff line
@@ -17,15 +17,11 @@
#ifndef _DEBUGGERD_MACHINE_H
#define _DEBUGGERD_MACHINE_H

#include <stddef.h>
#include <stdbool.h>
#include <sys/types.h>

#include <corkscrew/ptrace.h>

#include "utility.h"

void dump_memory_and_code(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault);
void dump_registers(const ptrace_context_t* context, log_t* log, pid_t tid, bool at_fault);
void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags);
void dump_registers(log_t* log, pid_t tid, int scope_flags);

#endif // _DEBUGGERD_MACHINE_H
Loading