aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Ferris <cferris@google.com>2015-01-28 16:13:56 -0800
committerChristopher Ferris <cferris@google.com>2015-01-28 16:20:26 -0800
commit8ea53fa87e63dac824c274216d84d7eda973805c (patch)
tree891a54d818d8dbf5c4c11c36eef19bc791b97b83
parent9e82c4be359a4637f21988b66b6d25abbfb79ddb (diff)
downloadandroid_bionic-8ea53fa87e63dac824c274216d84d7eda973805c.tar.gz
android_bionic-8ea53fa87e63dac824c274216d84d7eda973805c.tar.bz2
android_bionic-8ea53fa87e63dac824c274216d84d7eda973805c.zip
Only one crashing thread should contact debuggerd.
If two or more threads crash at the same time, only let one talk to debuggerd. It's possible for a race to occur that two threads send data to debuggerd, the second one will cause errors in debuggerd since the process will die once debuggerd lets the crashing pid start again. Bug: 19183955 Change-Id: I17dfce46102117ab4a870f7381bd526488d37fb5
-rw-r--r--linker/debugger.cpp21
1 files changed, 20 insertions, 1 deletions
diff --git a/linker/debugger.cpp b/linker/debugger.cpp
index c889544d1..6fe9524e7 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));