Loading debuggerd/libdebuggerd/arm/machine.cpp +20 −13 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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)) { Loading @@ -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_); } debuggerd/libdebuggerd/arm64/machine.cpp +17 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); } debuggerd/libdebuggerd/include/machine.h +1 −0 Original line number Diff line number Diff line Loading @@ -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 debuggerd/libdebuggerd/tombstone.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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), "<unknown>"); read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>"); _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(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); Loading Loading
debuggerd/libdebuggerd/arm/machine.cpp +20 −13 Original line number Diff line number Diff line Loading @@ -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)) { Loading @@ -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)) { Loading @@ -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_); }
debuggerd/libdebuggerd/arm64/machine.cpp +17 −14 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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); }
debuggerd/libdebuggerd/include/machine.h +1 −0 Original line number Diff line number Diff line Loading @@ -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
debuggerd/libdebuggerd/tombstone.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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), "<unknown>"); read_with_default("/proc/self/cmdline", process_name, sizeof(process_name), "<unknown>"); _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(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); Loading