am 8abf44c4: Merge "Make libc signal handler output more like debuggerd."

* commit '8abf44c415bb3b02b6a3198196c92266442a0c32':
  Make libc signal handler output more like debuggerd.
This commit is contained in:
Elliott Hughes 2014-04-21 13:41:35 +00:00 committed by Android Git Automerger
commit a3d82df005

View File

@ -29,6 +29,7 @@
#include "linker.h" #include "linker.h"
#include <errno.h> #include <errno.h>
#include <inttypes.h>
#include <signal.h> #include <signal.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -78,12 +79,11 @@ static int socket_abstract_client(const char* name, int type) {
return -1; return -1;
} }
/* This is used for abstract socket namespace, we need // This is used for abstract socket namespace, we need
* an initial '\0' at the start of the Unix socket path. // an initial '\0' at the start of the Unix socket path.
* //
* Note: The path in this case is *not* supposed to be // Note: The path in this case is *not* supposed to be
* '\0'-terminated. ("man 7 unix" for the gory details.) // '\0'-terminated. ("man 7 unix" for the gory details.)
*/
memset(&addr, 0, sizeof(addr)); memset(&addr, 0, sizeof(addr));
addr.sun_family = AF_LOCAL; addr.sun_family = AF_LOCAL;
addr.sun_path[0] = 0; addr.sun_path[0] = 0;
@ -115,18 +115,36 @@ static int socket_abstract_client(const char* name, int type) {
* could allocate memory or hold a lock. * could allocate memory or hold a lock.
*/ */
static void log_signal_summary(int signum, const siginfo_t* info) { static void log_signal_summary(int signum, const siginfo_t* info) {
const char* signal_name; const char* signal_name = "???";
bool has_address = false;
switch (signum) { switch (signum) {
case SIGILL: signal_name = "SIGILL"; break; case SIGILL:
case SIGABRT: signal_name = "SIGABRT"; break; signal_name = "SIGILL";
case SIGBUS: signal_name = "SIGBUS"; break; has_address = true;
case SIGFPE: signal_name = "SIGFPE"; break; break;
case SIGSEGV: signal_name = "SIGSEGV"; break; case SIGABRT:
signal_name = "SIGABRT";
break;
case SIGBUS:
signal_name = "SIGBUS";
has_address = true;
break;
case SIGFPE:
signal_name = "SIGFPE";
has_address = true;
break;
case SIGSEGV:
signal_name = "SIGSEGV";
has_address = true;
break;
#if defined(SIGSTKFLT) #if defined(SIGSTKFLT)
case SIGSTKFLT: signal_name = "SIGSTKFLT"; break; case SIGSTKFLT:
signal_name = "SIGSTKFLT";
break;
#endif #endif
case SIGPIPE: signal_name = "SIGPIPE"; break; case SIGPIPE:
default: signal_name = "???"; break; signal_name = "SIGPIPE";
break;
} }
char thread_name[MAX_TASK_NAME_LEN + 1]; // one more for termination char thread_name[MAX_TASK_NAME_LEN + 1]; // one more for termination
@ -139,17 +157,22 @@ static void log_signal_summary(int signum, const siginfo_t* info) {
} }
// "info" will be NULL if the siginfo_t information was not available. // "info" will be NULL if the siginfo_t information was not available.
// Many signals don't have an address or a code.
char code_desc[32]; // ", code -6"
char addr_desc[32]; // ", fault addr 0x1234"
addr_desc[0] = code_desc[0] = 0;
if (info != NULL) { if (info != NULL) {
__libc_format_log(ANDROID_LOG_FATAL, "libc", // For a rethrown signal, this si_code will be right and the one debuggerd shows will
"Fatal signal %d (%s) at %p (code=%d), thread %d (%s)", // always be SI_TKILL.
signum, signal_name, info->si_addr, info->si_code, snprintf(code_desc, sizeof(code_desc), ", code %d", info->si_code);
gettid(), thread_name); if (has_address) {
} else { snprintf(addr_desc, sizeof(addr_desc), ", fault addr %p", info->si_addr);
__libc_format_log(ANDROID_LOG_FATAL, "libc",
"Fatal signal %d (%s), thread %d (%s)",
signum, signal_name, gettid(), thread_name);
} }
} }
__libc_format_log(ANDROID_LOG_FATAL, "libc",
"Fatal signal %d (%s)%s%s in tid %d (%s)",
signum, signal_name, code_desc, addr_desc, gettid(), thread_name);
}
/* /*
* Returns true if the handler for signal "signum" has SA_SIGINFO set. * Returns true if the handler for signal "signum" has SA_SIGINFO set.