diff options
author | Josh Gao <jmgao@google.com> | 2018-02-22 11:38:33 -0800 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2018-02-22 16:31:38 -0800 |
commit | 70adac6a8a8469b6a4c248417bba33fa8381b9ad (patch) | |
tree | 7474d0f38e7acf8291be530c7b1dd9bdf8179583 /debuggerd/handler/debuggerd_fallback.cpp | |
parent | cdf778f5d92ab8748897a4d95693524d3273c23a (diff) |
debuggerd_fallback: don't recursively abort.
Calls to abort() will always result in our signal handler being called,
because abort will manually unblock SIGABRT before raising it. This
can lead to deadlock when handling address space exhaustion in the
fallback handler. To fix this, switch our mutex to a recursive mutex,
and manually keep track of our lock count.
Bug: http://b/72929749
Test: debuggerd_test --gtest_filter="CrasherTest.seccomp_crash_oom"
Change-Id: I609f263ce93550350b17757189326b627129d4a7
Diffstat (limited to 'debuggerd/handler/debuggerd_fallback.cpp')
-rw-r--r-- | debuggerd/handler/debuggerd_fallback.cpp | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/debuggerd/handler/debuggerd_fallback.cpp b/debuggerd/handler/debuggerd_fallback.cpp index 364fca5e8..dea2e17eb 100644 --- a/debuggerd/handler/debuggerd_fallback.cpp +++ b/debuggerd/handler/debuggerd_fallback.cpp @@ -37,6 +37,7 @@ #include <atomic> #include <memory> +#include <mutex> #include <android-base/file.h> #include <android-base/unique_fd.h> @@ -298,11 +299,13 @@ exit: static void crash_handler(siginfo_t* info, ucontext_t* ucontext, void* abort_message) { // Only allow one thread to handle a crash at a time (this can happen multiple times without // exit, since tombstones can be requested without a real crash happening.) - static pthread_mutex_t crash_mutex = PTHREAD_MUTEX_INITIALIZER; - int ret = pthread_mutex_lock(&crash_mutex); - if (ret != 0) { - async_safe_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret)); - return; + static std::recursive_mutex crash_mutex; + static int lock_count; + + crash_mutex.lock(); + if (lock_count++ > 0) { + async_safe_format_log(ANDROID_LOG_ERROR, "libc", "recursed signal handler call, exiting"); + _exit(1); } unique_fd tombstone_socket, output_fd; @@ -313,7 +316,8 @@ static void crash_handler(siginfo_t* info, ucontext_t* ucontext, void* abort_mes tombstoned_notify_completion(tombstone_socket.get()); } - pthread_mutex_unlock(&crash_mutex); + --lock_count; + crash_mutex.unlock(); } extern "C" void debuggerd_fallback_handler(siginfo_t* info, ucontext_t* ucontext, |