Loading debuggerd/arm/machine.cpp +25 −27 Original line number Diff line number Diff line Loading @@ -40,13 +40,12 @@ // If configured to do so, dump memory around *all* registers // for the crashing thread. void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { void dump_memory_and_code(log_t* log, pid_t tid) { struct pt_regs regs; if (ptrace(PTRACE_GETREGS, tid, 0, ®s)) { return; } if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) { static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp"; for (int reg = 0; reg < 14; reg++) { Loading @@ -59,38 +58,37 @@ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { continue; } _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", ®_NAMES[reg * 2]); dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE); } _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", ®_NAMES[reg * 2]); dump_memory(log, tid, addr); } // explicitly allow upload of code dump logging _LOG(log, scope_flags, "\ncode around pc:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags); _LOG(log, logtype::MEMORY, "\ncode around pc:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc)); if (regs.ARM_pc != regs.ARM_lr) { _LOG(log, scope_flags, "\ncode around lr:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags); _LOG(log, logtype::MEMORY, "\ncode around lr:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr)); } } void dump_registers(log_t* log, pid_t tid, int scope_flags) { void dump_registers(log_t* log, pid_t tid) { struct pt_regs r; if (ptrace(PTRACE_GETREGS, tid, 0, &r)) { _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno)); _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno)); return; } _LOG(log, scope_flags, " r0 %08x r1 %08x r2 %08x r3 %08x\n", _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, scope_flags, " r4 %08x r5 %08x r6 %08x r7 %08x\n", _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, scope_flags, " r8 %08x r9 %08x sl %08x fp %08x\n", _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, scope_flags, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", _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)); Loading @@ -100,14 +98,14 @@ void dump_registers(log_t* log, pid_t tid, int scope_flags) { int i; if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) { _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno)); _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno)); return; } for (i = 0; i < NUM_VFP_REGS; i += 2) { _LOG(log, scope_flags, " d%-2d %016llx d%-2d %016llx\n", _LOG(log, logtype::REGISTERS, " d%-2d %016llx d%-2d %016llx\n", i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]); } _LOG(log, scope_flags, " scr %08lx\n", vfp_regs.fpscr); _LOG(log, logtype::REGISTERS, " scr %08lx\n", vfp_regs.fpscr); #endif } debuggerd/arm64/machine.cpp +25 −27 Original line number Diff line number Diff line Loading @@ -37,19 +37,18 @@ * If configured to do so, dump memory around *all* registers * for the crashing thread. */ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { void dump_memory_and_code(log_t* log, pid_t tid) { struct user_pt_regs regs; struct iovec io; io.iov_base = ®s; io.iov_len = sizeof(regs); if (ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, &io) == -1) { _LOG(log, scope_flags, "%s: ptrace failed to get registers: %s\n", LOG_ERROR("%s: ptrace failed to get registers: %s\n", __func__, strerror(errno)); return; } if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) { for (int reg = 0; reg < 31; reg++) { uintptr_t addr = regs.regs[reg]; Loading @@ -61,44 +60,43 @@ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { continue; } _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near x%d:\n", reg); dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE); } _LOG(log, logtype::MEMORY, "\nmemory near x%d:\n", reg); dump_memory(log, tid, addr); } _LOG(log, scope_flags, "\ncode around pc:\n"); dump_memory(log, tid, (uintptr_t)regs.pc, scope_flags); _LOG(log, logtype::MEMORY, "\ncode around pc:\n"); dump_memory(log, tid, (uintptr_t)regs.pc); if (regs.pc != regs.sp) { _LOG(log, scope_flags, "\ncode around sp:\n"); dump_memory(log, tid, (uintptr_t)regs.sp, scope_flags); _LOG(log, logtype::MEMORY, "\ncode around sp:\n"); dump_memory(log, tid, (uintptr_t)regs.sp); } } void dump_registers(log_t* log, pid_t tid, int scope_flags) { void dump_registers(log_t* log, pid_t tid) { struct user_pt_regs r; struct iovec io; io.iov_base = &r; io.iov_len = sizeof(r); if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) { _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno)); LOG_ERROR("ptrace error: %s\n", strerror(errno)); return; } for (int i = 0; i < 28; i += 4) { _LOG(log, scope_flags, " x%-2d %016lx x%-2d %016lx x%-2d %016lx x%-2d %016lx\n", _LOG(log, logtype::REGISTERS, " x%-2d %016lx x%-2d %016lx x%-2d %016lx x%-2d %016lx\n", i, (uint64_t)r.regs[i], i+1, (uint64_t)r.regs[i+1], i+2, (uint64_t)r.regs[i+2], i+3, (uint64_t)r.regs[i+3]); } _LOG(log, scope_flags, " x28 %016lx x29 %016lx x30 %016lx\n", _LOG(log, logtype::REGISTERS, " x28 %016lx x29 %016lx x30 %016lx\n", (uint64_t)r.regs[28], (uint64_t)r.regs[29], (uint64_t)r.regs[30]); _LOG(log, scope_flags, " sp %016lx pc %016lx\n", _LOG(log, logtype::REGISTERS, " sp %016lx pc %016lx\n", (uint64_t)r.sp, (uint64_t)r.pc); Loading @@ -107,12 +105,12 @@ void dump_registers(log_t* log, pid_t tid, int scope_flags) io.iov_len = sizeof(f); if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) { _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno)); LOG_ERROR("ptrace error: %s\n", strerror(errno)); return; } for (int i = 0; i < 32; i += 4) { _LOG(log, scope_flags, " v%-2d %016lx v%-2d %016lx v%-2d %016lx v%-2d %016lx\n", _LOG(log, logtype::REGISTERS, " v%-2d %016lx v%-2d %016lx v%-2d %016lx v%-2d %016lx\n", i, (uint64_t)f.vregs[i], i+1, (uint64_t)f.vregs[i+1], i+2, (uint64_t)f.vregs[i+2], Loading debuggerd/backtrace.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <UniquePtr.h> #include "backtrace.h" #include "utility.h" static void dump_process_header(log_t* log, pid_t pid) { Loading @@ -49,15 +50,15 @@ static void dump_process_header(log_t* log, pid_t pid) { localtime_r(&t, &tm); char timestr[64]; strftime(timestr, sizeof(timestr), "%F %T", &tm); _LOG(log, SCOPE_AT_FAULT, "\n\n----- pid %d at %s -----\n", pid, timestr); _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr); if (procname) { _LOG(log, SCOPE_AT_FAULT, "Cmd line: %s\n", procname); _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname); } } static void dump_process_footer(log_t* log, pid_t pid) { _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid); _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid); } static void dump_thread( Loading @@ -79,10 +80,10 @@ static void dump_thread( } } _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid); _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid); if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) { _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno)); _LOG(log, logtype::BACKTRACE, "Could not attach to thread: %s\n", strerror(errno)); return; } Loading @@ -90,11 +91,11 @@ static void dump_thread( UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD)); if (backtrace->Unwind(0)) { dump_backtrace_to_log(backtrace.get(), log, SCOPE_AT_FAULT, " "); dump_backtrace_to_log(backtrace.get(), log, " "); } if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) { LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno)); LOG_ERROR("ptrace detach from %d failed: %s\n", tid, strerror(errno)); *detach_failed = true; } } Loading Loading @@ -133,9 +134,8 @@ void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed, dump_process_footer(&log, pid); } void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, int scope_flags, const char* prefix) { void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) { for (size_t i = 0; i < backtrace->NumFrames(); i++) { _LOG(log, scope_flags, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str()); _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str()); } } debuggerd/backtrace.h +1 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ 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(Backtrace* backtrace, log_t* log, int scope_flags, const char* prefix); void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix); #endif // _DEBUGGERD_BACKTRACE_H debuggerd/debuggerd.cpp +17 −18 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ #include <sys/stat.h> #include <sys/poll.h> #include <log/logd.h> #include <log/logger.h> #include <cutils/sockets.h> Loading Loading @@ -62,7 +61,7 @@ static void wait_for_user_action(pid_t pid) { char exe[PATH_MAX]; int count; if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) { LOG("readlink('%s') failed: %s", path, strerror(errno)); LOG_ERROR("readlink('%s') failed: %s", path, strerror(errno)); strlcpy(exe, "unknown", sizeof(exe)); } else { exe[count] = '\0'; Loading @@ -79,7 +78,7 @@ static void wait_for_user_action(pid_t pid) { } // Explain how to attach the debugger. LOG( "********************************************************\n" LOG_ERROR( "********************************************************\n" "* Process %d has been suspended while crashing.\n" "* To attach gdbserver for a gdb connection on port 5039\n" "* and start gdbclient:\n" Loading @@ -104,7 +103,7 @@ static void wait_for_user_action(pid_t pid) { uninit_getevent(); } LOG("debuggerd resuming process %d", pid); LOG_ERROR("debuggerd resuming process %d", pid); } static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) { Loading Loading @@ -140,7 +139,7 @@ static int read_request(int fd, debugger_request_t* out_request) { socklen_t len = sizeof(cr); int status = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len); if (status != 0) { LOG("cannot get credentials\n"); LOG_ERROR("cannot get credentials\n"); return -1; } Loading @@ -153,7 +152,7 @@ static int read_request(int fd, debugger_request_t* out_request) { pollfds[0].revents = 0; status = TEMP_FAILURE_RETRY(poll(pollfds, 1, 3000)); if (status != 1) { LOG("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid); LOG_ERROR("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid); return -1; } Loading @@ -161,14 +160,14 @@ static int read_request(int fd, debugger_request_t* out_request) { memset(&msg, 0, sizeof(msg)); status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg))); if (status < 0) { LOG("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid); LOG_ERROR("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid); return -1; } if (status == sizeof(debugger_msg_t)) { XLOG("crash request of size %d abort_msg_address=0x%" PRIPTR "\n", status, msg.abort_msg_address); } else { LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid); LOG_ERROR("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid); return -1; } Loading @@ -186,7 +185,7 @@ static int read_request(int fd, debugger_request_t* out_request) { struct stat s; snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid); if (stat(buf, &s)) { LOG("tid %d does not exist in pid %d. ignoring debug request\n", LOG_ERROR("tid %d does not exist in pid %d. ignoring debug request\n", out_request->tid, out_request->pid); return -1; } Loading @@ -197,7 +196,7 @@ static int read_request(int fd, debugger_request_t* out_request) { status = get_process_info(out_request->tid, &out_request->pid, &out_request->uid, &out_request->gid); if (status < 0) { LOG("tid %d does not exist. ignoring explicit dump request\n", out_request->tid); LOG_ERROR("tid %d does not exist. ignoring explicit dump request\n", out_request->tid); return -1; } } else { Loading Loading @@ -238,12 +237,12 @@ static void handle_request(int fd) { // See details in bionic/libc/linker/debugger.c, in function // debugger_signal_handler(). if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) { LOG("ptrace attach failed: %s\n", strerror(errno)); LOG_ERROR("ptrace attach failed: %s\n", strerror(errno)); } else { bool detach_failed = false; bool attach_gdb = should_attach_gdb(&request); if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) { LOG("failed responding to client: %s\n", strerror(errno)); LOG_ERROR("failed responding to client: %s\n", strerror(errno)); } else { char* tombstone_path = NULL; Loading Loading @@ -275,7 +274,7 @@ static void handle_request(int fd) { XLOG("stopped -- continuing\n"); status = ptrace(PTRACE_CONT, request.tid, 0, 0); if (status) { LOG("ptrace continue failed: %s\n", strerror(errno)); LOG_ERROR("ptrace continue failed: %s\n", strerror(errno)); } continue; // loop again } Loading Loading @@ -307,7 +306,7 @@ static void handle_request(int fd) { default: XLOG("stopped -- unexpected signal\n"); LOG("process stopped due to unexpected signal %d\n", signal); LOG_ERROR("process stopped due to unexpected signal %d\n", signal); break; } break; Loading @@ -330,7 +329,7 @@ static void handle_request(int fd) { // detach so we can attach gdbserver if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) { LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); detach_failed = true; } Loading @@ -342,7 +341,7 @@ static void handle_request(int fd) { } else { // just detach if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) { LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); detach_failed = true; } } Loading @@ -354,7 +353,7 @@ static void handle_request(int fd) { // actual parent won't receive a death notification via wait(2). At this point // there's not much we can do about that. if (detach_failed) { LOG("debuggerd committing suicide to free the zombie!\n"); LOG_ERROR("debuggerd committing suicide to free the zombie!\n"); kill(getpid(), SIGKILL); } } Loading Loading @@ -400,7 +399,7 @@ static int do_server() { return 1; fcntl(s, F_SETFD, FD_CLOEXEC); LOG("debuggerd: " __DATE__ " " __TIME__ "\n"); LOG_ERROR("debuggerd: " __DATE__ " " __TIME__ "\n"); for (;;) { sockaddr addr; Loading Loading
debuggerd/arm/machine.cpp +25 −27 Original line number Diff line number Diff line Loading @@ -40,13 +40,12 @@ // If configured to do so, dump memory around *all* registers // for the crashing thread. void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { void dump_memory_and_code(log_t* log, pid_t tid) { struct pt_regs regs; if (ptrace(PTRACE_GETREGS, tid, 0, ®s)) { return; } if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) { static const char REG_NAMES[] = "r0r1r2r3r4r5r6r7r8r9slfpipsp"; for (int reg = 0; reg < 14; reg++) { Loading @@ -59,38 +58,37 @@ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { continue; } _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near %.2s:\n", ®_NAMES[reg * 2]); dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE); } _LOG(log, logtype::MEMORY, "\nmemory near %.2s:\n", ®_NAMES[reg * 2]); dump_memory(log, tid, addr); } // explicitly allow upload of code dump logging _LOG(log, scope_flags, "\ncode around pc:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc), scope_flags); _LOG(log, logtype::MEMORY, "\ncode around pc:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_pc)); if (regs.ARM_pc != regs.ARM_lr) { _LOG(log, scope_flags, "\ncode around lr:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr), scope_flags); _LOG(log, logtype::MEMORY, "\ncode around lr:\n"); dump_memory(log, tid, static_cast<uintptr_t>(regs.ARM_lr)); } } void dump_registers(log_t* log, pid_t tid, int scope_flags) { void dump_registers(log_t* log, pid_t tid) { struct pt_regs r; if (ptrace(PTRACE_GETREGS, tid, 0, &r)) { _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno)); _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno)); return; } _LOG(log, scope_flags, " r0 %08x r1 %08x r2 %08x r3 %08x\n", _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, scope_flags, " r4 %08x r5 %08x r6 %08x r7 %08x\n", _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, scope_flags, " r8 %08x r9 %08x sl %08x fp %08x\n", _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, scope_flags, " ip %08x sp %08x lr %08x pc %08x cpsr %08x\n", _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)); Loading @@ -100,14 +98,14 @@ void dump_registers(log_t* log, pid_t tid, int scope_flags) { int i; if (ptrace(PTRACE_GETVFPREGS, tid, 0, &vfp_regs)) { _LOG(log, scope_flags, "cannot get registers: %s\n", strerror(errno)); _LOG(log, logtype::REGISTERS, "cannot get registers: %s\n", strerror(errno)); return; } for (i = 0; i < NUM_VFP_REGS; i += 2) { _LOG(log, scope_flags, " d%-2d %016llx d%-2d %016llx\n", _LOG(log, logtype::REGISTERS, " d%-2d %016llx d%-2d %016llx\n", i, vfp_regs.fpregs[i], i+1, vfp_regs.fpregs[i+1]); } _LOG(log, scope_flags, " scr %08lx\n", vfp_regs.fpscr); _LOG(log, logtype::REGISTERS, " scr %08lx\n", vfp_regs.fpscr); #endif }
debuggerd/arm64/machine.cpp +25 −27 Original line number Diff line number Diff line Loading @@ -37,19 +37,18 @@ * If configured to do so, dump memory around *all* registers * for the crashing thread. */ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { void dump_memory_and_code(log_t* log, pid_t tid) { struct user_pt_regs regs; struct iovec io; io.iov_base = ®s; io.iov_len = sizeof(regs); if (ptrace(PTRACE_GETREGSET, tid, (void*)NT_PRSTATUS, &io) == -1) { _LOG(log, scope_flags, "%s: ptrace failed to get registers: %s\n", LOG_ERROR("%s: ptrace failed to get registers: %s\n", __func__, strerror(errno)); return; } if (IS_AT_FAULT(scope_flags) && DUMP_MEMORY_FOR_ALL_REGISTERS) { for (int reg = 0; reg < 31; reg++) { uintptr_t addr = regs.regs[reg]; Loading @@ -61,44 +60,43 @@ void dump_memory_and_code(log_t* log, pid_t tid, int scope_flags) { continue; } _LOG(log, scope_flags | SCOPE_SENSITIVE, "\nmemory near x%d:\n", reg); dump_memory(log, tid, addr, scope_flags | SCOPE_SENSITIVE); } _LOG(log, logtype::MEMORY, "\nmemory near x%d:\n", reg); dump_memory(log, tid, addr); } _LOG(log, scope_flags, "\ncode around pc:\n"); dump_memory(log, tid, (uintptr_t)regs.pc, scope_flags); _LOG(log, logtype::MEMORY, "\ncode around pc:\n"); dump_memory(log, tid, (uintptr_t)regs.pc); if (regs.pc != regs.sp) { _LOG(log, scope_flags, "\ncode around sp:\n"); dump_memory(log, tid, (uintptr_t)regs.sp, scope_flags); _LOG(log, logtype::MEMORY, "\ncode around sp:\n"); dump_memory(log, tid, (uintptr_t)regs.sp); } } void dump_registers(log_t* log, pid_t tid, int scope_flags) { void dump_registers(log_t* log, pid_t tid) { struct user_pt_regs r; struct iovec io; io.iov_base = &r; io.iov_len = sizeof(r); if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRSTATUS, (void*) &io) == -1) { _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno)); LOG_ERROR("ptrace error: %s\n", strerror(errno)); return; } for (int i = 0; i < 28; i += 4) { _LOG(log, scope_flags, " x%-2d %016lx x%-2d %016lx x%-2d %016lx x%-2d %016lx\n", _LOG(log, logtype::REGISTERS, " x%-2d %016lx x%-2d %016lx x%-2d %016lx x%-2d %016lx\n", i, (uint64_t)r.regs[i], i+1, (uint64_t)r.regs[i+1], i+2, (uint64_t)r.regs[i+2], i+3, (uint64_t)r.regs[i+3]); } _LOG(log, scope_flags, " x28 %016lx x29 %016lx x30 %016lx\n", _LOG(log, logtype::REGISTERS, " x28 %016lx x29 %016lx x30 %016lx\n", (uint64_t)r.regs[28], (uint64_t)r.regs[29], (uint64_t)r.regs[30]); _LOG(log, scope_flags, " sp %016lx pc %016lx\n", _LOG(log, logtype::REGISTERS, " sp %016lx pc %016lx\n", (uint64_t)r.sp, (uint64_t)r.pc); Loading @@ -107,12 +105,12 @@ void dump_registers(log_t* log, pid_t tid, int scope_flags) io.iov_len = sizeof(f); if (ptrace(PTRACE_GETREGSET, tid, (void*) NT_PRFPREG, (void*) &io) == -1) { _LOG(log, scope_flags, "ptrace error: %s\n", strerror(errno)); LOG_ERROR("ptrace error: %s\n", strerror(errno)); return; } for (int i = 0; i < 32; i += 4) { _LOG(log, scope_flags, " v%-2d %016lx v%-2d %016lx v%-2d %016lx v%-2d %016lx\n", _LOG(log, logtype::REGISTERS, " v%-2d %016lx v%-2d %016lx v%-2d %016lx v%-2d %016lx\n", i, (uint64_t)f.vregs[i], i+1, (uint64_t)f.vregs[i+1], i+2, (uint64_t)f.vregs[i+2], Loading
debuggerd/backtrace.cpp +10 −10 Original line number Diff line number Diff line Loading @@ -30,6 +30,7 @@ #include <UniquePtr.h> #include "backtrace.h" #include "utility.h" static void dump_process_header(log_t* log, pid_t pid) { Loading @@ -49,15 +50,15 @@ static void dump_process_header(log_t* log, pid_t pid) { localtime_r(&t, &tm); char timestr[64]; strftime(timestr, sizeof(timestr), "%F %T", &tm); _LOG(log, SCOPE_AT_FAULT, "\n\n----- pid %d at %s -----\n", pid, timestr); _LOG(log, logtype::BACKTRACE, "\n\n----- pid %d at %s -----\n", pid, timestr); if (procname) { _LOG(log, SCOPE_AT_FAULT, "Cmd line: %s\n", procname); _LOG(log, logtype::BACKTRACE, "Cmd line: %s\n", procname); } } static void dump_process_footer(log_t* log, pid_t pid) { _LOG(log, SCOPE_AT_FAULT, "\n----- end %d -----\n", pid); _LOG(log, logtype::BACKTRACE, "\n----- end %d -----\n", pid); } static void dump_thread( Loading @@ -79,10 +80,10 @@ static void dump_thread( } } _LOG(log, SCOPE_AT_FAULT, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid); _LOG(log, logtype::BACKTRACE, "\n\"%s\" sysTid=%d\n", threadname ? threadname : "<unknown>", tid); if (!attached && ptrace(PTRACE_ATTACH, tid, 0, 0) < 0) { _LOG(log, SCOPE_AT_FAULT, "Could not attach to thread: %s\n", strerror(errno)); _LOG(log, logtype::BACKTRACE, "Could not attach to thread: %s\n", strerror(errno)); return; } Loading @@ -90,11 +91,11 @@ static void dump_thread( UniquePtr<Backtrace> backtrace(Backtrace::Create(tid, BACKTRACE_CURRENT_THREAD)); if (backtrace->Unwind(0)) { dump_backtrace_to_log(backtrace.get(), log, SCOPE_AT_FAULT, " "); dump_backtrace_to_log(backtrace.get(), log, " "); } if (!attached && ptrace(PTRACE_DETACH, tid, 0, 0) != 0) { LOG("ptrace detach from %d failed: %s\n", tid, strerror(errno)); LOG_ERROR("ptrace detach from %d failed: %s\n", tid, strerror(errno)); *detach_failed = true; } } Loading Loading @@ -133,9 +134,8 @@ void dump_backtrace(int fd, int amfd, pid_t pid, pid_t tid, bool* detach_failed, dump_process_footer(&log, pid); } void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, int scope_flags, const char* prefix) { void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix) { for (size_t i = 0; i < backtrace->NumFrames(); i++) { _LOG(log, scope_flags, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str()); _LOG(log, logtype::BACKTRACE, "%s%s\n", prefix, backtrace->FormatFrameData(i).c_str()); } }
debuggerd/backtrace.h +1 −2 Original line number Diff line number Diff line Loading @@ -29,7 +29,6 @@ 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(Backtrace* backtrace, log_t* log, int scope_flags, const char* prefix); void dump_backtrace_to_log(Backtrace* backtrace, log_t* log, const char* prefix); #endif // _DEBUGGERD_BACKTRACE_H
debuggerd/debuggerd.cpp +17 −18 Original line number Diff line number Diff line Loading @@ -30,7 +30,6 @@ #include <sys/stat.h> #include <sys/poll.h> #include <log/logd.h> #include <log/logger.h> #include <cutils/sockets.h> Loading Loading @@ -62,7 +61,7 @@ static void wait_for_user_action(pid_t pid) { char exe[PATH_MAX]; int count; if ((count = readlink(path, exe, sizeof(exe) - 1)) == -1) { LOG("readlink('%s') failed: %s", path, strerror(errno)); LOG_ERROR("readlink('%s') failed: %s", path, strerror(errno)); strlcpy(exe, "unknown", sizeof(exe)); } else { exe[count] = '\0'; Loading @@ -79,7 +78,7 @@ static void wait_for_user_action(pid_t pid) { } // Explain how to attach the debugger. LOG( "********************************************************\n" LOG_ERROR( "********************************************************\n" "* Process %d has been suspended while crashing.\n" "* To attach gdbserver for a gdb connection on port 5039\n" "* and start gdbclient:\n" Loading @@ -104,7 +103,7 @@ static void wait_for_user_action(pid_t pid) { uninit_getevent(); } LOG("debuggerd resuming process %d", pid); LOG_ERROR("debuggerd resuming process %d", pid); } static int get_process_info(pid_t tid, pid_t* out_pid, uid_t* out_uid, uid_t* out_gid) { Loading Loading @@ -140,7 +139,7 @@ static int read_request(int fd, debugger_request_t* out_request) { socklen_t len = sizeof(cr); int status = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &cr, &len); if (status != 0) { LOG("cannot get credentials\n"); LOG_ERROR("cannot get credentials\n"); return -1; } Loading @@ -153,7 +152,7 @@ static int read_request(int fd, debugger_request_t* out_request) { pollfds[0].revents = 0; status = TEMP_FAILURE_RETRY(poll(pollfds, 1, 3000)); if (status != 1) { LOG("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid); LOG_ERROR("timed out reading tid (from pid=%d uid=%d)\n", cr.pid, cr.uid); return -1; } Loading @@ -161,14 +160,14 @@ static int read_request(int fd, debugger_request_t* out_request) { memset(&msg, 0, sizeof(msg)); status = TEMP_FAILURE_RETRY(read(fd, &msg, sizeof(msg))); if (status < 0) { LOG("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid); LOG_ERROR("read failure? %s (pid=%d uid=%d)\n", strerror(errno), cr.pid, cr.uid); return -1; } if (status == sizeof(debugger_msg_t)) { XLOG("crash request of size %d abort_msg_address=0x%" PRIPTR "\n", status, msg.abort_msg_address); } else { LOG("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid); LOG_ERROR("invalid crash request of size %d (from pid=%d uid=%d)\n", status, cr.pid, cr.uid); return -1; } Loading @@ -186,7 +185,7 @@ static int read_request(int fd, debugger_request_t* out_request) { struct stat s; snprintf(buf, sizeof buf, "/proc/%d/task/%d", out_request->pid, out_request->tid); if (stat(buf, &s)) { LOG("tid %d does not exist in pid %d. ignoring debug request\n", LOG_ERROR("tid %d does not exist in pid %d. ignoring debug request\n", out_request->tid, out_request->pid); return -1; } Loading @@ -197,7 +196,7 @@ static int read_request(int fd, debugger_request_t* out_request) { status = get_process_info(out_request->tid, &out_request->pid, &out_request->uid, &out_request->gid); if (status < 0) { LOG("tid %d does not exist. ignoring explicit dump request\n", out_request->tid); LOG_ERROR("tid %d does not exist. ignoring explicit dump request\n", out_request->tid); return -1; } } else { Loading Loading @@ -238,12 +237,12 @@ static void handle_request(int fd) { // See details in bionic/libc/linker/debugger.c, in function // debugger_signal_handler(). if (ptrace(PTRACE_ATTACH, request.tid, 0, 0)) { LOG("ptrace attach failed: %s\n", strerror(errno)); LOG_ERROR("ptrace attach failed: %s\n", strerror(errno)); } else { bool detach_failed = false; bool attach_gdb = should_attach_gdb(&request); if (TEMP_FAILURE_RETRY(write(fd, "\0", 1)) != 1) { LOG("failed responding to client: %s\n", strerror(errno)); LOG_ERROR("failed responding to client: %s\n", strerror(errno)); } else { char* tombstone_path = NULL; Loading Loading @@ -275,7 +274,7 @@ static void handle_request(int fd) { XLOG("stopped -- continuing\n"); status = ptrace(PTRACE_CONT, request.tid, 0, 0); if (status) { LOG("ptrace continue failed: %s\n", strerror(errno)); LOG_ERROR("ptrace continue failed: %s\n", strerror(errno)); } continue; // loop again } Loading Loading @@ -307,7 +306,7 @@ static void handle_request(int fd) { default: XLOG("stopped -- unexpected signal\n"); LOG("process stopped due to unexpected signal %d\n", signal); LOG_ERROR("process stopped due to unexpected signal %d\n", signal); break; } break; Loading @@ -330,7 +329,7 @@ static void handle_request(int fd) { // detach so we can attach gdbserver if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) { LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); detach_failed = true; } Loading @@ -342,7 +341,7 @@ static void handle_request(int fd) { } else { // just detach if (ptrace(PTRACE_DETACH, request.tid, 0, 0)) { LOG("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); LOG_ERROR("ptrace detach from %d failed: %s\n", request.tid, strerror(errno)); detach_failed = true; } } Loading @@ -354,7 +353,7 @@ static void handle_request(int fd) { // actual parent won't receive a death notification via wait(2). At this point // there's not much we can do about that. if (detach_failed) { LOG("debuggerd committing suicide to free the zombie!\n"); LOG_ERROR("debuggerd committing suicide to free the zombie!\n"); kill(getpid(), SIGKILL); } } Loading Loading @@ -400,7 +399,7 @@ static int do_server() { return 1; fcntl(s, F_SETFD, FD_CLOEXEC); LOG("debuggerd: " __DATE__ " " __TIME__ "\n"); LOG_ERROR("debuggerd: " __DATE__ " " __TIME__ "\n"); for (;;) { sockaddr addr; Loading