diff options
author | Christopher Ferris <cferris@google.com> | 2015-01-29 01:49:20 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2015-01-29 01:49:21 +0000 |
commit | 43606bc1ce974e4ba42d7d2c3682ad5182e6fc96 (patch) | |
tree | 3c47c01a5db643219ebb5865e8c4fb0373df0c16 | |
parent | a9c3d0569f3b9511af445457cd455a7bb967b60e (diff) | |
parent | 8ea53fa87e63dac824c274216d84d7eda973805c (diff) | |
download | bionic-43606bc1ce974e4ba42d7d2c3682ad5182e6fc96.zip bionic-43606bc1ce974e4ba42d7d2c3682ad5182e6fc96.tar.gz bionic-43606bc1ce974e4ba42d7d2c3682ad5182e6fc96.tar.bz2 |
Merge "Only one crashing thread should contact debuggerd."
-rw-r--r-- | linker/debugger.cpp | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/linker/debugger.cpp b/linker/debugger.cpp index c889544..6fe9524 100644 --- a/linker/debugger.cpp +++ b/linker/debugger.cpp @@ -30,9 +30,11 @@ #include <errno.h> #include <inttypes.h> +#include <pthread.h> #include <signal.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <sys/mman.h> #include <sys/prctl.h> #include <sys/socket.h> @@ -212,6 +214,23 @@ static void send_debuggerd_packet(siginfo_t* info) { return; } + // Mutex to prevent multiple crashing threads from trying to talk + // to debuggerd at the same time. + static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER; + int ret = pthread_mutex_trylock(&crash_mutex); + if (ret != 0) { + if (ret == EBUSY) { + __libc_format_log(ANDROID_LOG_INFO, "libc", + "Another thread has contacted debuggerd first, stop and wait for process to die."); + // This will never complete since the lock is never released. + pthread_mutex_lock(&crash_mutex); + } else { + __libc_format_log(ANDROID_LOG_INFO, "libc", + "pthread_mutex_trylock failed: %s", strerror(ret)); + } + return; + } + int s = socket_abstract_client(DEBUGGER_SOCKET_NAME, SOCK_STREAM | SOCK_CLOEXEC); if (s == -1) { __libc_format_log(ANDROID_LOG_FATAL, "libc", "Unable to open connection to debuggerd: %s", @@ -228,7 +247,7 @@ static void send_debuggerd_packet(siginfo_t* info) { msg.tid = gettid(); msg.abort_msg_address = reinterpret_cast<uintptr_t>(g_abort_message); msg.original_si_code = (info != nullptr) ? info->si_code : 0; - int ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))); + ret = TEMP_FAILURE_RETRY(write(s, &msg, sizeof(msg))); if (ret == sizeof(msg)) { char debuggerd_ack; ret = TEMP_FAILURE_RETRY(read(s, &debuggerd_ack, 1)); |