diff options
author | Josh Gao <jmgao@google.com> | 2018-08-27 14:52:33 -0700 |
---|---|---|
committer | Josh Gao <jmgao@google.com> | 2018-08-27 16:55:07 -0700 |
commit | 4843c186340585eaf20610d2538f85234cc63174 (patch) | |
tree | cb61d93db49006ce82d12ae939d2231b2b8eb420 /debuggerd/handler/debuggerd_handler.cpp | |
parent | c86b01baa1020716a634f264a6e96d88a5f2ad27 (diff) |
debuggerd_handler: receive abort messages via sigqueue(DEBUGGER_SIGNAL).
Make it possible for code such as fdsan that generates debugging
tombstones via raise(DEBUGGER_SIGNAL) to pass an abort message as well.
Bug: http://b/112770187
Test: debuggerd_test
Change-Id: Idc34263241c18033573e466da3a45aa6f716ddb3
Diffstat (limited to 'debuggerd/handler/debuggerd_handler.cpp')
-rw-r--r-- | debuggerd/handler/debuggerd_handler.cpp | 28 |
1 files changed, 19 insertions, 9 deletions
diff --git a/debuggerd/handler/debuggerd_handler.cpp b/debuggerd/handler/debuggerd_handler.cpp index 91e6f7111..15557b6d8 100644 --- a/debuggerd/handler/debuggerd_handler.cpp +++ b/debuggerd/handler/debuggerd_handler.cpp @@ -457,14 +457,14 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c info = nullptr; } - struct siginfo si = {}; + struct siginfo dummy_info = {}; if (!info) { - memset(&si, 0, sizeof(si)); - si.si_signo = signal_number; - si.si_code = SI_USER; - si.si_pid = __getpid(); - si.si_uid = getuid(); - info = &si; + memset(&dummy_info, 0, sizeof(dummy_info)); + dummy_info.si_signo = signal_number; + dummy_info.si_code = SI_USER; + dummy_info.si_pid = __getpid(); + dummy_info.si_uid = getuid(); + info = &dummy_info; } else if (info->si_code >= 0 || info->si_code == SI_TKILL) { // rt_tgsigqueueinfo(2)'s documentation appears to be incorrect on kernels // that contain commit 66dd34a (3.9+). The manpage claims to only allow @@ -473,8 +473,18 @@ static void debuggerd_signal_handler(int signal_number, siginfo_t* info, void* c } void* abort_message = nullptr; - if (signal_number != DEBUGGER_SIGNAL && g_callbacks.get_abort_message) { - abort_message = g_callbacks.get_abort_message(); + if (signal_number == DEBUGGER_SIGNAL) { + if (info->si_code == SI_QUEUE && info->si_pid == __getpid()) { + // Allow for the abort message to be explicitly specified via the sigqueue value. + // Keep the bottom bit intact for representing whether we want a backtrace or a tombstone. + uintptr_t value = reinterpret_cast<uintptr_t>(info->si_ptr); + abort_message = reinterpret_cast<void*>(value & ~1); + info->si_ptr = reinterpret_cast<void*>(value & 1); + } + } else { + if (g_callbacks.get_abort_message) { + abort_message = g_callbacks.get_abort_message(); + } } // If sival_int is ~0, it means that the fallback handler has been called |