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

Commit 77b00ed4 authored by Josh Gao's avatar Josh Gao
Browse files

libdebuggerd: implement fallback register dumping on arm/aarch64.

Bug: http://b/35439781
Test: killall -ABRT media.codec on internal
Change-Id: I7a23d3bfcf07ad584e677b2ef5fff28436ef0972
parent 2e7b8e2d
Loading
Loading
Loading
Loading
+20 −13
Original line number Diff line number Diff line
@@ -48,6 +48,21 @@ void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
  }
}

#define DUMP_GP_REGISTERS(log, reg_prefix)                                             \
  _LOG(log, logtype::REGISTERS, "    r0 %08x  r1 %08x  r2 %08x  r3 %08x\n",            \
       static_cast<uint32_t>(reg_prefix##r0), static_cast<uint32_t>(reg_prefix##r1),   \
       static_cast<uint32_t>(reg_prefix##r2), static_cast<uint32_t>(reg_prefix##r3));  \
  _LOG(log, logtype::REGISTERS, "    r4 %08x  r5 %08x  r6 %08x  r7 %08x\n",            \
       static_cast<uint32_t>(reg_prefix##r4), static_cast<uint32_t>(reg_prefix##r5),   \
       static_cast<uint32_t>(reg_prefix##r6), static_cast<uint32_t>(reg_prefix##r7));  \
  _LOG(log, logtype::REGISTERS, "    r8 %08x  r9 %08x  sl %08x  fp %08x\n",            \
       static_cast<uint32_t>(reg_prefix##r8), static_cast<uint32_t>(reg_prefix##r9),   \
       static_cast<uint32_t>(reg_prefix##r10), static_cast<uint32_t>(reg_prefix##fp)); \
  _LOG(log, logtype::REGISTERS, "    ip %08x  sp %08x  lr %08x  pc %08x  cpsr %08x\n", \
       static_cast<uint32_t>(reg_prefix##ip), static_cast<uint32_t>(reg_prefix##sp),   \
       static_cast<uint32_t>(reg_prefix##lr), static_cast<uint32_t>(reg_prefix##pc),   \
       static_cast<uint32_t>(reg_prefix##cpsr))

void dump_registers(log_t* log, pid_t tid) {
  pt_regs r;
  if (ptrace(PTRACE_GETREGS, tid, 0, &r)) {
@@ -55,19 +70,7 @@ void dump_registers(log_t* log, pid_t tid) {
    return;
  }

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

  user_vfp vfp_regs;
  if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) {
@@ -81,3 +84,7 @@ void dump_registers(log_t* log, pid_t tid) {
  }
  _LOG(log, logtype::FP_REGISTERS, "    scr %08lx\n", vfp_regs.fpscr);
}

void dump_registers(log_t* log, const ucontext_t* uc) {
  DUMP_GP_REGISTERS(log, uc->uc_mcontext.arm_);
}
+17 −14
Original line number Diff line number Diff line
@@ -52,6 +52,17 @@ void dump_memory_and_code(log_t* log, Backtrace* backtrace) {
  }
}

#define DUMP_GP_REGISTERS(log)                                                                   \
  for (int i = 0; i < 28; i += 4) {                                                              \
    const char* fmt = "    x%-2d  %016llx  x%-2d  %016llx  x%-2d  %016llx  x%-2d  %016llx\n";    \
    _LOG(log, logtype::REGISTERS, fmt, i, r.regs[i], i + 1, r.regs[i + 1], i + 2, r.regs[i + 2], \
         i + 3, r.regs[i + 3]);                                                                  \
  }                                                                                              \
  _LOG(log, logtype::REGISTERS, "    x28  %016llx  x29  %016llx  x30  %016llx\n", r.regs[28],    \
       r.regs[29], r.regs[30]);                                                                  \
  _LOG(log, logtype::REGISTERS, "    sp   %016llx  pc   %016llx  pstate %016llx\n", r.sp, r.pc,  \
       r.pstate)

void dump_registers(log_t* log, pid_t tid) {
  struct user_pt_regs r;
  struct iovec io;
@@ -63,20 +74,7 @@ void dump_registers(log_t* log, pid_t tid) {
    return;
  }

  for (int i = 0; i < 28; i += 4) {
    _LOG(log, logtype::REGISTERS,
         "    x%-2d  %016llx  x%-2d  %016llx  x%-2d  %016llx  x%-2d  %016llx\n",
         i, r.regs[i],
         i+1, r.regs[i+1],
         i+2, r.regs[i+2],
         i+3, r.regs[i+3]);
  }

  _LOG(log, logtype::REGISTERS, "    x28  %016llx  x29  %016llx  x30  %016llx\n",
       r.regs[28], r.regs[29], r.regs[30]);

  _LOG(log, logtype::REGISTERS, "    sp   %016llx  pc   %016llx  pstate %016llx\n",
       r.sp, r.pc, r.pstate);
  DUMP_GP_REGISTERS(log);

  struct user_fpsimd_state f;
  io.iov_base = &f;
@@ -99,3 +97,8 @@ void dump_registers(log_t* log, pid_t tid) {
  }
  _LOG(log, logtype::FP_REGISTERS, "    fpsr %08x  fpcr %08x\n", f.fpsr, f.fpcr);
}

void dump_registers(log_t* log, const ucontext_t* ucontext) {
  const mcontext_t& r = ucontext->uc_mcontext;
  DUMP_GP_REGISTERS(log);
}
+1 −0
Original line number Diff line number Diff line
@@ -25,5 +25,6 @@

void dump_memory_and_code(log_t* log, Backtrace* backtrace);
void dump_registers(log_t* log, pid_t tid);
void dump_registers(log_t* log, const ucontext_t* uc);

#endif // _DEBUGGERD_MACHINE_H
+7 −0
Original line number Diff line number Diff line
@@ -470,6 +470,11 @@ static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) {
  }
}

// Weak noop implementation, real implementations are in <arch>/machine.cpp.
__attribute__((weak)) void dump_registers(log_t* log, const ucontext_t*) {
  _LOG(log, logtype::REGISTERS, "    register dumping unimplemented on this architecture");
}

static void dump_thread(log_t* log, pid_t pid, pid_t tid, const std::string& process_name,
                        const std::string& thread_name, BacktraceMap* map,
                        uintptr_t abort_msg_address, bool primary_thread) {
@@ -754,6 +759,8 @@ void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, s

  std::unique_ptr<Backtrace> backtrace(Backtrace::Create(pid, tid));
  dump_abort_message(backtrace.get(), &log, abort_msg_address);
  dump_registers(&log, ucontext);

  // TODO: Dump registers from the ucontext.
  if (backtrace->Unwind(0, ucontext)) {
    dump_backtrace_and_stack(backtrace.get(), &log);