summaryrefslogtreecommitdiffstats
path: root/debuggerd/handler/debuggerd_handler.cpp
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2017-03-01 17:23:22 -0800
committerJosh Gao <jmgao@google.com>2017-03-09 11:26:05 -0800
commite1aa0ca58a2a356039047ffcc8a98d85d1bce8ed (patch)
tree46c90399acd3b3fa76538e26b528ee005cbb8872 /debuggerd/handler/debuggerd_handler.cpp
parent4e5e797d26272dc08b6336def8d7878443881f0e (diff)
downloadsystem_core-e1aa0ca58a2a356039047ffcc8a98d85d1bce8ed.tar.gz
system_core-e1aa0ca58a2a356039047ffcc8a98d85d1bce8ed.tar.bz2
system_core-e1aa0ca58a2a356039047ffcc8a98d85d1bce8ed.zip
debuggerd_handler: implement missing fallback functionality.
Allow the fallback implementation to dump traces and create tombstones in seccomped processes. Bug: http://b/35858739 Test: debuggerd -b `pidof media.codec`; killall -ABRT media.codec Change-Id: I381b283de39a66d8900f1c320d32497d6f2b4ec4
Diffstat (limited to 'debuggerd/handler/debuggerd_handler.cpp')
-rw-r--r--debuggerd/handler/debuggerd_handler.cpp38
1 files changed, 19 insertions, 19 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp
index 67c26e2f4..c09c2f31f 100644
--- a/debuggerd/handler/debuggerd_handler.cpp
+++ b/debuggerd/handler/debuggerd_handler.cpp
@@ -62,7 +62,7 @@
#define CRASH_DUMP_PATH "/system/bin/" CRASH_DUMP_NAME
-extern "C" bool debuggerd_fallback(ucontext_t*, siginfo_t*, void*);
+extern "C" void debuggerd_fallback_handler(siginfo_t*, ucontext_t*, void*);
static debuggerd_callbacks_t g_callbacks;
@@ -323,21 +323,11 @@ static void resend_signal(siginfo_t* info, bool crash_dump_started) {
fatal_errno("failed to resend signal during crash");
}
}
-
- if (info->si_signo == DEBUGGER_SIGNAL) {
- pthread_mutex_unlock(&crash_mutex);
- }
}
// Handler that does crash dumping by forking and doing the processing in the child.
// Do this by ptracing the relevant thread, and then execing debuggerd to do the actual dump.
static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* context) {
- int ret = pthread_mutex_lock(&crash_mutex);
- if (ret != 0) {
- __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
- return;
- }
-
// It's possible somebody cleared the SA_SIGINFO flag, which would mean
// our "info" arg holds an undefined value.
if (!have_siginfo(signal_number)) {
@@ -359,24 +349,29 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
// check to allow all si_code values in calls coming from inside the house.
}
- log_signal_summary(signal_number, info);
-
void* abort_message = nullptr;
if (g_callbacks.get_abort_message) {
abort_message = g_callbacks.get_abort_message();
}
if (prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0) == 1) {
- ucontext_t* ucontext = static_cast<ucontext_t*>(context);
- if (signal_number == DEBUGGER_SIGNAL || !debuggerd_fallback(ucontext, info, abort_message)) {
- // The process has NO_NEW_PRIVS enabled, so we can't transition to the crash_dump context.
- __libc_format_log(ANDROID_LOG_INFO, "libc",
- "Suppressing debuggerd output because prctl(PR_GET_NO_NEW_PRIVS)==1");
- }
+ // This check might be racy if another thread sets NO_NEW_PRIVS, but this should be unlikely,
+ // you can only set NO_NEW_PRIVS to 1, and the effect should be at worst a single missing
+ // ANR trace.
+ debuggerd_fallback_handler(info, static_cast<ucontext_t*>(context), abort_message);
resend_signal(info, false);
return;
}
+ // Only allow one thread to handle a signal at a time.
+ int ret = pthread_mutex_lock(&crash_mutex);
+ if (ret != 0) {
+ __libc_format_log(ANDROID_LOG_INFO, "libc", "pthread_mutex_lock failed: %s", strerror(ret));
+ return;
+ }
+
+ log_signal_summary(signal_number, info);
+
// Populate si_value with the abort message address, if found.
if (abort_message) {
info->si_value.sival_ptr = abort_message;
@@ -427,6 +422,11 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c
}
resend_signal(info, thread_info.crash_dump_started);
+ if (info->si_signo == DEBUGGER_SIGNAL) {
+ // If the signal is fatal, don't unlock the mutex to prevent other crashing threads from
+ // starting to dump right before our death.
+ pthread_mutex_unlock(&crash_mutex);
+ }
}
void debuggerd_init(debuggerd_callbacks_t* callbacks) {