Loading debuggerd/handler/debuggerd_handler.cpp +11 −9 Original line number Diff line number Diff line Loading @@ -169,24 +169,26 @@ static void log_signal_summary(const siginfo_t* info) { return; } const char* signal_name = get_signame(info->si_signo); bool has_address = signal_has_si_addr(info->si_signo, info->si_code); // Many signals don't have an address. // Many signals don't have an address or sender. char addr_desc[32] = ""; // ", fault addr 0x1234" if (has_address) { if (signal_has_si_addr(info)) { async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr); } pid_t self_pid = __getpid(); char sender_desc[32] = {}; // " from pid 1234, uid 666" if (signal_has_sender(info, self_pid)) { get_signal_sender(sender_desc, sizeof(sender_desc), info); } char main_thread_name[MAX_TASK_NAME_LEN + 1]; if (!get_main_thread_name(main_thread_name, sizeof(main_thread_name))) { strncpy(main_thread_name, "<unknown>", sizeof(main_thread_name)); } async_safe_format_log( ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s), code %d (%s)%s in tid %d (%s), pid %d (%s)", info->si_signo, signal_name, info->si_code, get_sigcode(info->si_signo, info->si_code), addr_desc, __gettid(), thread_name, __getpid(), main_thread_name); async_safe_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s), code %d (%s%s)%s in tid %d (%s), pid %d (%s)", info->si_signo, get_signame(info), info->si_code, get_sigcode(info), sender_desc, addr_desc, __gettid(), thread_name, self_pid, main_thread_name); } /* Loading debuggerd/libdebuggerd/include/libdebuggerd/utility.h +5 −3 Original line number Diff line number Diff line Loading @@ -74,8 +74,10 @@ void read_with_default(const char* path, char* buf, size_t len, const char* defa void drop_capabilities(); bool signal_has_si_addr(int si_signo, int si_code); const char* get_signame(int sig); const char* get_sigcode(int signo, int code); bool signal_has_sender(const siginfo_t*, pid_t caller_pid); bool signal_has_si_addr(const siginfo_t*); void get_signal_sender(char* buf, size_t n, const siginfo_t*); const char* get_signame(const siginfo_t*); const char* get_sigcode(const siginfo_t*); #endif // _DEBUGGERD_UTILITY_H debuggerd/libdebuggerd/tombstone.cpp +14 −8 Original line number Diff line number Diff line Loading @@ -102,18 +102,24 @@ static void dump_probable_cause(log_t* log, const siginfo_t* si) { if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str()); } static void dump_signal_info(log_t* log, const siginfo_t* si) { static void dump_signal_info(log_t* log, const ThreadInfo& thread_info) { char addr_desc[32]; // ", fault addr 0x1234" if (signal_has_si_addr(si->si_signo, si->si_code)) { snprintf(addr_desc, sizeof(addr_desc), "%p", si->si_addr); if (signal_has_si_addr(thread_info.siginfo)) { snprintf(addr_desc, sizeof(addr_desc), "%p", thread_info.siginfo->si_addr); } else { snprintf(addr_desc, sizeof(addr_desc), "--------"); } _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n", si->si_signo, get_signame(si->si_signo), si->si_code, get_sigcode(si->si_signo, si->si_code), addr_desc); char sender_desc[32] = {}; // " from pid 1234, uid 666" if (signal_has_sender(thread_info.siginfo, thread_info.pid)) { get_signal_sender(sender_desc, sizeof(sender_desc), thread_info.siginfo); } _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s%s), fault addr %s\n", thread_info.siginfo->si_signo, get_signame(thread_info.siginfo), thread_info.siginfo->si_code, get_sigcode(thread_info.siginfo), sender_desc, addr_desc); dump_probable_cause(log, si); dump_probable_cause(log, thread_info.siginfo); } static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { Loading Loading @@ -412,7 +418,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, dump_thread_info(log, thread_info); if (thread_info.siginfo) { dump_signal_info(log, thread_info.siginfo); dump_signal_info(log, thread_info); } if (primary_thread) { Loading Loading @@ -442,7 +448,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, if (map) { uint64_t addr = 0; siginfo_t* si = thread_info.siginfo; if (signal_has_si_addr(si->si_signo, si->si_code)) { if (signal_has_si_addr(si)) { addr = reinterpret_cast<uint64_t>(si->si_addr); } dump_all_maps(log, map, process_memory, addr); Loading debuggerd/libdebuggerd/utility.cpp +24 −16 Original line number Diff line number Diff line Loading @@ -254,13 +254,13 @@ void drop_capabilities() { } } bool signal_has_si_addr(int si_signo, int si_code) { bool signal_has_si_addr(const siginfo_t* si) { // Manually sent signals won't have si_addr. if (si_code == SI_USER || si_code == SI_QUEUE || si_code == SI_TKILL) { if (si->si_code == SI_USER || si->si_code == SI_QUEUE || si->si_code == SI_TKILL) { return false; } switch (si_signo) { switch (si->si_signo) { case SIGBUS: case SIGFPE: case SIGILL: Loading @@ -272,8 +272,16 @@ bool signal_has_si_addr(int si_signo, int si_code) { } } const char* get_signame(int sig) { switch (sig) { bool signal_has_sender(const siginfo_t* si, pid_t caller_pid) { return SI_FROMUSER(si) && (si->si_pid != 0) && (si->si_pid != caller_pid); } void get_signal_sender(char* buf, size_t n, const siginfo_t* si) { snprintf(buf, n, " from pid %d, uid %d", si->si_pid, si->si_uid); } const char* get_signame(const siginfo_t* si) { switch (si->si_signo) { case SIGABRT: return "SIGABRT"; case SIGBUS: return "SIGBUS"; case SIGFPE: return "SIGFPE"; Loading @@ -290,11 +298,11 @@ const char* get_signame(int sig) { } } const char* get_sigcode(int signo, int code) { const char* get_sigcode(const siginfo_t* si) { // Try the signal-specific codes... switch (signo) { switch (si->si_signo) { case SIGILL: switch (code) { switch (si->si_code) { case ILL_ILLOPC: return "ILL_ILLOPC"; case ILL_ILLOPN: return "ILL_ILLOPN"; case ILL_ILLADR: return "ILL_ILLADR"; Loading @@ -307,7 +315,7 @@ const char* get_sigcode(int signo, int code) { static_assert(NSIGILL == ILL_BADSTK, "missing ILL_* si_code"); break; case SIGBUS: switch (code) { switch (si->si_code) { case BUS_ADRALN: return "BUS_ADRALN"; case BUS_ADRERR: return "BUS_ADRERR"; case BUS_OBJERR: return "BUS_OBJERR"; Loading @@ -317,7 +325,7 @@ const char* get_sigcode(int signo, int code) { static_assert(NSIGBUS == BUS_MCEERR_AO, "missing BUS_* si_code"); break; case SIGFPE: switch (code) { switch (si->si_code) { case FPE_INTDIV: return "FPE_INTDIV"; case FPE_INTOVF: return "FPE_INTOVF"; case FPE_FLTDIV: return "FPE_FLTDIV"; Loading @@ -330,7 +338,7 @@ const char* get_sigcode(int signo, int code) { static_assert(NSIGFPE == FPE_FLTSUB, "missing FPE_* si_code"); break; case SIGSEGV: switch (code) { switch (si->si_code) { case SEGV_MAPERR: return "SEGV_MAPERR"; case SEGV_ACCERR: return "SEGV_ACCERR"; #if defined(SEGV_BNDERR) Loading @@ -350,21 +358,21 @@ const char* get_sigcode(int signo, int code) { break; #if defined(SYS_SECCOMP) // Our glibc is too old, and we build this for the host too. case SIGSYS: switch (code) { switch (si->si_code) { case SYS_SECCOMP: return "SYS_SECCOMP"; } static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code"); break; #endif case SIGTRAP: switch (code) { switch (si->si_code) { case TRAP_BRKPT: return "TRAP_BRKPT"; case TRAP_TRACE: return "TRAP_TRACE"; case TRAP_BRANCH: return "TRAP_BRANCH"; case TRAP_HWBKPT: return "TRAP_HWBKPT"; } if ((code & 0xff) == SIGTRAP) { switch ((code >> 8) & 0xff) { if ((si->si_code & 0xff) == SIGTRAP) { switch ((si->si_code >> 8) & 0xff) { case PTRACE_EVENT_FORK: return "PTRACE_EVENT_FORK"; case PTRACE_EVENT_VFORK: Loading @@ -387,7 +395,7 @@ const char* get_sigcode(int signo, int code) { break; } // Then the other codes... switch (code) { switch (si->si_code) { case SI_USER: return "SI_USER"; case SI_KERNEL: return "SI_KERNEL"; case SI_QUEUE: return "SI_QUEUE"; Loading Loading
debuggerd/handler/debuggerd_handler.cpp +11 −9 Original line number Diff line number Diff line Loading @@ -169,24 +169,26 @@ static void log_signal_summary(const siginfo_t* info) { return; } const char* signal_name = get_signame(info->si_signo); bool has_address = signal_has_si_addr(info->si_signo, info->si_code); // Many signals don't have an address. // Many signals don't have an address or sender. char addr_desc[32] = ""; // ", fault addr 0x1234" if (has_address) { if (signal_has_si_addr(info)) { async_safe_format_buffer(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr); } pid_t self_pid = __getpid(); char sender_desc[32] = {}; // " from pid 1234, uid 666" if (signal_has_sender(info, self_pid)) { get_signal_sender(sender_desc, sizeof(sender_desc), info); } char main_thread_name[MAX_TASK_NAME_LEN + 1]; if (!get_main_thread_name(main_thread_name, sizeof(main_thread_name))) { strncpy(main_thread_name, "<unknown>", sizeof(main_thread_name)); } async_safe_format_log( ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s), code %d (%s)%s in tid %d (%s), pid %d (%s)", info->si_signo, signal_name, info->si_code, get_sigcode(info->si_signo, info->si_code), addr_desc, __gettid(), thread_name, __getpid(), main_thread_name); async_safe_format_log(ANDROID_LOG_FATAL, "libc", "Fatal signal %d (%s), code %d (%s%s)%s in tid %d (%s), pid %d (%s)", info->si_signo, get_signame(info), info->si_code, get_sigcode(info), sender_desc, addr_desc, __gettid(), thread_name, self_pid, main_thread_name); } /* Loading
debuggerd/libdebuggerd/include/libdebuggerd/utility.h +5 −3 Original line number Diff line number Diff line Loading @@ -74,8 +74,10 @@ void read_with_default(const char* path, char* buf, size_t len, const char* defa void drop_capabilities(); bool signal_has_si_addr(int si_signo, int si_code); const char* get_signame(int sig); const char* get_sigcode(int signo, int code); bool signal_has_sender(const siginfo_t*, pid_t caller_pid); bool signal_has_si_addr(const siginfo_t*); void get_signal_sender(char* buf, size_t n, const siginfo_t*); const char* get_signame(const siginfo_t*); const char* get_sigcode(const siginfo_t*); #endif // _DEBUGGERD_UTILITY_H
debuggerd/libdebuggerd/tombstone.cpp +14 −8 Original line number Diff line number Diff line Loading @@ -102,18 +102,24 @@ static void dump_probable_cause(log_t* log, const siginfo_t* si) { if (!cause.empty()) _LOG(log, logtype::HEADER, "Cause: %s\n", cause.c_str()); } static void dump_signal_info(log_t* log, const siginfo_t* si) { static void dump_signal_info(log_t* log, const ThreadInfo& thread_info) { char addr_desc[32]; // ", fault addr 0x1234" if (signal_has_si_addr(si->si_signo, si->si_code)) { snprintf(addr_desc, sizeof(addr_desc), "%p", si->si_addr); if (signal_has_si_addr(thread_info.siginfo)) { snprintf(addr_desc, sizeof(addr_desc), "%p", thread_info.siginfo->si_addr); } else { snprintf(addr_desc, sizeof(addr_desc), "--------"); } _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s), fault addr %s\n", si->si_signo, get_signame(si->si_signo), si->si_code, get_sigcode(si->si_signo, si->si_code), addr_desc); char sender_desc[32] = {}; // " from pid 1234, uid 666" if (signal_has_sender(thread_info.siginfo, thread_info.pid)) { get_signal_sender(sender_desc, sizeof(sender_desc), thread_info.siginfo); } _LOG(log, logtype::HEADER, "signal %d (%s), code %d (%s%s), fault addr %s\n", thread_info.siginfo->si_signo, get_signame(thread_info.siginfo), thread_info.siginfo->si_code, get_sigcode(thread_info.siginfo), sender_desc, addr_desc); dump_probable_cause(log, si); dump_probable_cause(log, thread_info.siginfo); } static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) { Loading Loading @@ -412,7 +418,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, dump_thread_info(log, thread_info); if (thread_info.siginfo) { dump_signal_info(log, thread_info.siginfo); dump_signal_info(log, thread_info); } if (primary_thread) { Loading Loading @@ -442,7 +448,7 @@ static bool dump_thread(log_t* log, BacktraceMap* map, Memory* process_memory, if (map) { uint64_t addr = 0; siginfo_t* si = thread_info.siginfo; if (signal_has_si_addr(si->si_signo, si->si_code)) { if (signal_has_si_addr(si)) { addr = reinterpret_cast<uint64_t>(si->si_addr); } dump_all_maps(log, map, process_memory, addr); Loading
debuggerd/libdebuggerd/utility.cpp +24 −16 Original line number Diff line number Diff line Loading @@ -254,13 +254,13 @@ void drop_capabilities() { } } bool signal_has_si_addr(int si_signo, int si_code) { bool signal_has_si_addr(const siginfo_t* si) { // Manually sent signals won't have si_addr. if (si_code == SI_USER || si_code == SI_QUEUE || si_code == SI_TKILL) { if (si->si_code == SI_USER || si->si_code == SI_QUEUE || si->si_code == SI_TKILL) { return false; } switch (si_signo) { switch (si->si_signo) { case SIGBUS: case SIGFPE: case SIGILL: Loading @@ -272,8 +272,16 @@ bool signal_has_si_addr(int si_signo, int si_code) { } } const char* get_signame(int sig) { switch (sig) { bool signal_has_sender(const siginfo_t* si, pid_t caller_pid) { return SI_FROMUSER(si) && (si->si_pid != 0) && (si->si_pid != caller_pid); } void get_signal_sender(char* buf, size_t n, const siginfo_t* si) { snprintf(buf, n, " from pid %d, uid %d", si->si_pid, si->si_uid); } const char* get_signame(const siginfo_t* si) { switch (si->si_signo) { case SIGABRT: return "SIGABRT"; case SIGBUS: return "SIGBUS"; case SIGFPE: return "SIGFPE"; Loading @@ -290,11 +298,11 @@ const char* get_signame(int sig) { } } const char* get_sigcode(int signo, int code) { const char* get_sigcode(const siginfo_t* si) { // Try the signal-specific codes... switch (signo) { switch (si->si_signo) { case SIGILL: switch (code) { switch (si->si_code) { case ILL_ILLOPC: return "ILL_ILLOPC"; case ILL_ILLOPN: return "ILL_ILLOPN"; case ILL_ILLADR: return "ILL_ILLADR"; Loading @@ -307,7 +315,7 @@ const char* get_sigcode(int signo, int code) { static_assert(NSIGILL == ILL_BADSTK, "missing ILL_* si_code"); break; case SIGBUS: switch (code) { switch (si->si_code) { case BUS_ADRALN: return "BUS_ADRALN"; case BUS_ADRERR: return "BUS_ADRERR"; case BUS_OBJERR: return "BUS_OBJERR"; Loading @@ -317,7 +325,7 @@ const char* get_sigcode(int signo, int code) { static_assert(NSIGBUS == BUS_MCEERR_AO, "missing BUS_* si_code"); break; case SIGFPE: switch (code) { switch (si->si_code) { case FPE_INTDIV: return "FPE_INTDIV"; case FPE_INTOVF: return "FPE_INTOVF"; case FPE_FLTDIV: return "FPE_FLTDIV"; Loading @@ -330,7 +338,7 @@ const char* get_sigcode(int signo, int code) { static_assert(NSIGFPE == FPE_FLTSUB, "missing FPE_* si_code"); break; case SIGSEGV: switch (code) { switch (si->si_code) { case SEGV_MAPERR: return "SEGV_MAPERR"; case SEGV_ACCERR: return "SEGV_ACCERR"; #if defined(SEGV_BNDERR) Loading @@ -350,21 +358,21 @@ const char* get_sigcode(int signo, int code) { break; #if defined(SYS_SECCOMP) // Our glibc is too old, and we build this for the host too. case SIGSYS: switch (code) { switch (si->si_code) { case SYS_SECCOMP: return "SYS_SECCOMP"; } static_assert(NSIGSYS == SYS_SECCOMP, "missing SYS_* si_code"); break; #endif case SIGTRAP: switch (code) { switch (si->si_code) { case TRAP_BRKPT: return "TRAP_BRKPT"; case TRAP_TRACE: return "TRAP_TRACE"; case TRAP_BRANCH: return "TRAP_BRANCH"; case TRAP_HWBKPT: return "TRAP_HWBKPT"; } if ((code & 0xff) == SIGTRAP) { switch ((code >> 8) & 0xff) { if ((si->si_code & 0xff) == SIGTRAP) { switch ((si->si_code >> 8) & 0xff) { case PTRACE_EVENT_FORK: return "PTRACE_EVENT_FORK"; case PTRACE_EVENT_VFORK: Loading @@ -387,7 +395,7 @@ const char* get_sigcode(int signo, int code) { break; } // Then the other codes... switch (code) { switch (si->si_code) { case SI_USER: return "SI_USER"; case SI_KERNEL: return "SI_KERNEL"; case SI_QUEUE: return "SI_QUEUE"; Loading