Merge "Show signal sender for SI_FROMUSER signals."

This commit is contained in:
android-build-prod (mdb) 2018-04-26 21:16:57 +00:00 committed by Gerrit Code Review
commit b802255b06
4 changed files with 54 additions and 36 deletions

View File

@ -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);
}
/*

View File

@ -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

View File

@ -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);
}
dump_probable_cause(log, si);
_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, thread_info.siginfo);
}
static void dump_thread_info(log_t* log, const ThreadInfo& thread_info) {
@ -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) {
@ -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);

View File

@ -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:
@ -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";
@ -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";
@ -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";
@ -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";
@ -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)
@ -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:
@ -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";