diff --git a/debuggerd/libdebuggerd/arm/machine.cpp b/debuggerd/libdebuggerd/arm/machine.cpp index 78c230615..ac833aef2 100644 --- a/debuggerd/libdebuggerd/arm/machine.cpp +++ b/debuggerd/libdebuggerd/arm/machine.cpp @@ -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(reg_prefix##r0), static_cast(reg_prefix##r1), \ + static_cast(reg_prefix##r2), static_cast(reg_prefix##r3)); \ + _LOG(log, logtype::REGISTERS, " r4 %08x r5 %08x r6 %08x r7 %08x\n", \ + static_cast(reg_prefix##r4), static_cast(reg_prefix##r5), \ + static_cast(reg_prefix##r6), static_cast(reg_prefix##r7)); \ + _LOG(log, logtype::REGISTERS, " r8 %08x r9 %08x sl %08x fp %08x\n", \ + static_cast(reg_prefix##r8), static_cast(reg_prefix##r9), \ + static_cast(reg_prefix##r10), static_cast(reg_prefix##fp)); \ + _LOG(log, logtype::REGISTERS, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", \ + static_cast(reg_prefix##ip), static_cast(reg_prefix##sp), \ + static_cast(reg_prefix##lr), static_cast(reg_prefix##pc), \ + static_cast(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(r.ARM_r0), static_cast(r.ARM_r1), - static_cast(r.ARM_r2), static_cast(r.ARM_r3)); - _LOG(log, logtype::REGISTERS, " r4 %08x r5 %08x r6 %08x r7 %08x\n", - static_cast(r.ARM_r4), static_cast(r.ARM_r5), - static_cast(r.ARM_r6), static_cast(r.ARM_r7)); - _LOG(log, logtype::REGISTERS, " r8 %08x r9 %08x sl %08x fp %08x\n", - static_cast(r.ARM_r8), static_cast(r.ARM_r9), - static_cast(r.ARM_r10), static_cast(r.ARM_fp)); - _LOG(log, logtype::REGISTERS, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", - static_cast(r.ARM_ip), static_cast(r.ARM_sp), - static_cast(r.ARM_lr), static_cast(r.ARM_pc), - static_cast(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_); +} diff --git a/debuggerd/libdebuggerd/arm64/machine.cpp b/debuggerd/libdebuggerd/arm64/machine.cpp index e7bf79a8f..fa73c99ac 100644 --- a/debuggerd/libdebuggerd/arm64/machine.cpp +++ b/debuggerd/libdebuggerd/arm64/machine.cpp @@ -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); +} diff --git a/debuggerd/libdebuggerd/include/machine.h b/debuggerd/libdebuggerd/include/machine.h index e65b147f6..5e5668253 100644 --- a/debuggerd/libdebuggerd/include/machine.h +++ b/debuggerd/libdebuggerd/include/machine.h @@ -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 diff --git a/debuggerd/libdebuggerd/tombstone.cpp b/debuggerd/libdebuggerd/tombstone.cpp index 0c3844941..edc7be5e2 100644 --- a/debuggerd/libdebuggerd/tombstone.cpp +++ b/debuggerd/libdebuggerd/tombstone.cpp @@ -470,6 +470,11 @@ static void dump_backtrace_and_stack(Backtrace* backtrace, log_t* log) { } } +// Weak noop implementation, real implementations are in /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) { @@ -749,11 +754,15 @@ void engrave_tombstone_ucontext(int tombstone_fd, uintptr_t abort_msg_address, s read_with_default("/proc/self/comm", thread_name, sizeof(thread_name), ""); read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), ""); + _LOG(&log, logtype::HEADER, "*** *** *** *** *** *** *** *** *** *** *** *** *** *** *** ***\n"); + dump_header_info(&log); dump_thread_info(&log, pid, tid, thread_name, process_name); dump_signal_info(&log, siginfo); std::unique_ptr 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);