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

Commit b05c4724 authored by Christopher Ferris's avatar Christopher Ferris
Browse files

Add arch member into Unwinder object.

This simplifies some of the logic and removes the need to pass an
Arch value to functions that should already know about the arch
it is operating on.

Includes fixes for debuggerd/libbacktrace.

Added new unit tests to cover new cases.

Test: All unit tests pass.
Test: Faked unwinder failing to verify debuggerd error messages display
Test: properly in backtrace and tombstone.
Change-Id: I439fcae0695befcfb1cb4c0a786cc74949d33425
parent de540ad2
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -597,8 +597,8 @@ int main(int argc, char** argv) {
  }

  // TODO: Use seccomp to lock ourselves down.
  unwindstack::UnwinderFromPid unwinder(256, vm_pid);
  if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
  unwindstack::UnwinderFromPid unwinder(256, vm_pid, unwindstack::Regs::CurrentArch());
  if (!unwinder.Init()) {
    LOG(FATAL) << "Failed to init unwinder object.";
  }

+3 −7
Original line number Diff line number Diff line
@@ -82,16 +82,12 @@ static void debuggerd_fallback_trace(int output_fd, ucontext_t* ucontext) {
    thread.pid = getpid();
    thread.tid = gettid();
    thread.thread_name = get_thread_name(gettid());
    unwindstack::ArchEnum arch = unwindstack::Regs::CurrentArch();
    thread.registers.reset(unwindstack::Regs::CreateFromUcontext(arch, ucontext));
    thread.registers.reset(
        unwindstack::Regs::CreateFromUcontext(unwindstack::Regs::CurrentArch(), ucontext));

    // TODO: Create this once and store it in a global?
    unwindstack::UnwinderFromPid unwinder(kMaxFrames, getpid());
    if (unwinder.Init(arch)) {
    dump_backtrace_thread(output_fd, &unwinder, thread);
    } else {
      async_safe_format_log(ANDROID_LOG_ERROR, "libc", "Unable to init unwinder.");
    }
  }
  __linker_disable_fallback_allocator();
}
+7 −2
Original line number Diff line number Diff line
@@ -18,8 +18,9 @@

#include "libdebuggerd/backtrace.h"

#include <errno.h>
#include <dirent.h>
#include <errno.h>
#include <inttypes.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
@@ -65,7 +66,11 @@ void dump_backtrace_thread(int output_fd, unwindstack::Unwinder* unwinder,
  unwinder->SetRegs(thread.registers.get());
  unwinder->Unwind();
  if (unwinder->NumFrames() == 0) {
    _LOG(&log, logtype::THREAD, "Unwind failed: tid = %d", thread.tid);
    _LOG(&log, logtype::THREAD, "Unwind failed: tid = %d\n", thread.tid);
    if (unwinder->LastErrorCode() != unwindstack::ERROR_NONE) {
      _LOG(&log, logtype::THREAD, "  Error code: %s\n", unwinder->LastErrorCodeString());
      _LOG(&log, logtype::THREAD, "  Error address: 0x%" PRIx64 "\n", unwinder->LastErrorAddress());
    }
    return;
  }

+7 −3
Original line number Diff line number Diff line
@@ -407,7 +407,11 @@ static bool dump_thread(log_t* log, unwindstack::Unwinder* unwinder, const Threa
  unwinder->SetRegs(regs_copy.get());
  unwinder->Unwind();
  if (unwinder->NumFrames() == 0) {
    _LOG(log, logtype::THREAD, "Failed to unwind");
    _LOG(log, logtype::THREAD, "Failed to unwind\n");
    if (unwinder->LastErrorCode() != unwindstack::ERROR_NONE) {
      _LOG(log, logtype::THREAD, "  Error code: %s\n", unwinder->LastErrorCodeString());
      _LOG(log, logtype::THREAD, "  Error address: 0x%" PRIx64 "\n", unwinder->LastErrorAddress());
    }
  } else {
    _LOG(log, logtype::BACKTRACE, "\nbacktrace:\n");
    log_backtrace(log, unwinder, "    ");
@@ -578,8 +582,8 @@ void engrave_tombstone_ucontext(int tombstone_fd, uint64_t abort_msg_address, si
      .siginfo = siginfo,
  };

  unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid);
  if (!unwinder.Init(unwindstack::Regs::CurrentArch())) {
  unwindstack::UnwinderFromPid unwinder(kMaxFrames, pid, unwindstack::Regs::CurrentArch());
  if (!unwinder.Init()) {
    LOG(FATAL) << "Failed to init unwinder object.";
  }

+12 −0
Original line number Diff line number Diff line
@@ -37,6 +37,12 @@
#include "ThreadEntry.h"

bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) {
#if defined(__aarch64__)
  // Tagged pointer after Android R would lead top byte to have random values
  // https://source.android.com/devices/tech/debug/tagged-pointers
  ptr &= (1ULL << 56) - 1;
#endif

  if (!VerifyReadWordArgs(ptr, out_value)) {
    return false;
  }
@@ -54,6 +60,12 @@ bool BacktraceCurrent::ReadWord(uint64_t ptr, word_t* out_value) {
}

size_t BacktraceCurrent::Read(uint64_t addr, uint8_t* buffer, size_t bytes) {
#if defined(__aarch64__)
  // Tagged pointer after Android R would lead top byte to have random values
  // https://source.android.com/devices/tech/debug/tagged-pointers
  addr &= (1ULL << 56) - 1;
#endif

  backtrace_map_t map;
  FillInMap(addr, &map);
  if (!BacktraceMap::IsValid(map) || !(map.flags & PROT_READ)) {
Loading