diff options
author | Andy McFadden <fadden@android.com> | 2012-10-02 15:23:20 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2012-10-02 15:23:20 -0700 |
commit | 98957db5536e93724c2e9e6bd19d5063f9d4dc2c (patch) | |
tree | 5eb31ce5e31c4a3bd30bd492bdb367d228edb633 | |
parent | 2e0452cbd1f5b981fbadb4021198d2c27ec1cde3 (diff) | |
parent | f84bc8d6f6368f1c846124a8168761ee8cc589c0 (diff) | |
download | bionic-98957db5536e93724c2e9e6bd19d5063f9d4dc2c.zip bionic-98957db5536e93724c2e9e6bd19d5063f9d4dc2c.tar.gz bionic-98957db5536e93724c2e9e6bd19d5063f9d4dc2c.tar.bz2 |
Merge "Test flags before using "info"" into jb-mr1-dev
-rw-r--r-- | linker/debugger.c | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/linker/debugger.c b/linker/debugger.c index dde66f3..e4d4ae9 100644 --- a/linker/debugger.c +++ b/linker/debugger.c @@ -29,14 +29,10 @@ #include <stdio.h> #include <stdlib.h> #include <unistd.h> -#include <ctype.h> +#include <stdbool.h> #include <signal.h> -#include <sys/mman.h> #include <sys/prctl.h> #include <errno.h> - -#include "linker.h" - #include <sys/socket.h> #include <sys/un.h> @@ -113,11 +109,15 @@ static int socket_abstract_client(const char *name, int type) #include <../libc/private/logd.h> /* - * Writes a summary of the signal to the log file. + * Writes a summary of the signal to the log file. We do this so that, if + * for some reason we're not able to contact debuggerd, there is still some + * indication of the failure in the log. * * We could be here as a result of native heap corruption, or while a * mutex is being held, so we don't want to use any libc functions that * could allocate memory or hold a lock. + * + * "info" will be NULL if the siginfo_t information was not available. */ static void logSignalSummary(int signum, const siginfo_t* info) { @@ -145,14 +145,46 @@ static void logSignalSummary(int signum, const siginfo_t* info) // implies that 16 byte names are not. threadname[MAX_TASK_NAME_LEN] = 0; } - format_buffer(buffer, sizeof(buffer), - "Fatal signal %d (%s) at 0x%08x (code=%d), thread %d (%s)", - signum, signame, info->si_addr, info->si_code, gettid(), threadname); + if (info != NULL) { + format_buffer(buffer, sizeof(buffer), + "Fatal signal %d (%s) at 0x%08x (code=%d), thread %d (%s)", + signum, signame, info->si_addr, info->si_code, gettid(), threadname); + } else { + format_buffer(buffer, sizeof(buffer), + "Fatal signal %d (%s), thread %d (%s)", + signum, signame, gettid(), threadname); + } __libc_android_log_write(ANDROID_LOG_FATAL, "libc", buffer); } /* + * Returns true if the handler for signal "signum" has SA_SIGINFO set. + */ +static bool haveSiginfo(int signum) +{ + struct sigaction oldact, newact; + + memset(&newact, 0, sizeof(newact)); + newact.sa_handler = SIG_DFL; + newact.sa_flags = SA_RESTART; + sigemptyset(&newact.sa_mask); + + if (sigaction(signum, &newact, &oldact) < 0) { + __libc_android_log_write(ANDROID_LOG_FATAL, "libc", + "Failed testing for SA_SIGINFO"); + return 0; + } + bool ret = (oldact.sa_flags & SA_SIGINFO) != 0; + + if (sigaction(signum, &oldact, NULL) < 0) { + __libc_android_log_write(ANDROID_LOG_FATAL, "libc", + "Restore failed in test for SA_SIGINFO"); + } + return ret; +} + +/* * Catches fatal signals so we can ask debuggerd to ptrace us before * we crash. */ @@ -162,6 +194,14 @@ void debugger_signal_handler(int n, siginfo_t* info, void* unused __attribute__( unsigned tid; int s; + /* + * It's possible somebody cleared the SA_SIGINFO flag, which would mean + * our "info" arg holds an undefined value. + */ + if (!haveSiginfo(n)) { + info = NULL; + } + logSignalSummary(n, info); tid = gettid(); |