diff options
author | 2018-03-28 21:17:43 -0700 | |
---|---|---|
committer | 2018-03-29 15:42:46 -0700 | |
commit | cdd53140b77bf724a4d7451d4b495dbd90875372 (patch) | |
tree | 45215b9d5de49579ba40f01a1bcbbaca42032975 | |
parent | 7da5cea7288cd2dc412b1ea3568a800baeab778e (diff) |
ART: Experiment with timeout dumping
In an attempt to diagnose some timeout dumping issues, allow a recursive
unexpected signal. Also print the new signal number irrespectively.
Test: m test-art-host
Test: manual: send timeout signal to run-test
Test: manual: send timeout signal to run-test, then send sigbus to run-test
Change-Id: Idf198b264a7e5868bdf444f323921c946584c650
-rw-r--r-- | runtime/runtime_common.cc | 94 |
1 files changed, 70 insertions, 24 deletions
diff --git a/runtime/runtime_common.cc b/runtime/runtime_common.cc index 41bfb58d93..010c6e7571 100644 --- a/runtime/runtime_common.cc +++ b/runtime/runtime_common.cc @@ -370,30 +370,11 @@ static bool IsTimeoutSignal(int signal_number) { #pragma GCC diagnostic ignored "-Wframe-larger-than=" #endif -void HandleUnexpectedSignalCommon(int signal_number, - siginfo_t* info, - void* raw_context, - bool handle_timeout_signal, - bool dump_on_stderr) { - static bool handling_unexpected_signal = false; - if (handling_unexpected_signal) { - LogHelper::LogLineLowStack(__FILE__, - __LINE__, - ::android::base::FATAL_WITHOUT_ABORT, - "HandleUnexpectedSignal reentered\n"); - if (handle_timeout_signal) { - if (IsTimeoutSignal(signal_number)) { - // Ignore a recursive timeout. - return; - } - } - _exit(1); - } - handling_unexpected_signal = true; - - gAborting++; // set before taking any locks - MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_); - +static void HandleUnexpectedSignalCommonDump(int signal_number, + siginfo_t* info, + void* raw_context, + bool handle_timeout_signal, + bool dump_on_stderr) { auto logger = [&](auto& stream) { bool has_address = (signal_number == SIGILL || signal_number == SIGBUS || signal_number == SIGFPE || signal_number == SIGSEGV); @@ -452,6 +433,71 @@ void HandleUnexpectedSignalCommon(int signal_number, } } +void HandleUnexpectedSignalCommon(int signal_number, + siginfo_t* info, + void* raw_context, + bool handle_timeout_signal, + bool dump_on_stderr) { + // Local _static_ storing the currently handled signal (or -1). + static int handling_unexpected_signal = -1; + + // Whether the dump code should be run under the unexpected-signal lock. For diagnostics we + // allow recursive unexpected-signals in certain cases - avoid a deadlock. + bool grab_lock = true; + + if (handling_unexpected_signal != -1) { + LogHelper::LogLineLowStack(__FILE__, + __LINE__, + ::android::base::FATAL_WITHOUT_ABORT, + "HandleUnexpectedSignal reentered\n"); + // Print the signal number. Don't use any standard functions, just some arithmetic. Just best + // effort, with a minimal buffer. + if (0 < signal_number && signal_number < 100) { + char buf[] = { ' ', + 'S', + static_cast<char>('0' + (signal_number / 10)), + static_cast<char>('0' + (signal_number % 10)), + '\n', + 0 }; + LogHelper::LogLineLowStack(__FILE__, + __LINE__, + ::android::base::FATAL_WITHOUT_ABORT, + buf); + } + if (handle_timeout_signal) { + if (IsTimeoutSignal(signal_number)) { + // Ignore a recursive timeout. + return; + } + } + // If we were handling a timeout signal, try to go on. Otherwise hard-exit. + // This relies on the expectation that we'll only ever get one timeout signal. + if (!handle_timeout_signal || handling_unexpected_signal != GetTimeoutSignal()) { + _exit(1); + } + grab_lock = false; // The "outer" handling instance already holds the lock. + } + handling_unexpected_signal = signal_number; + + gAborting++; // set before taking any locks + + if (grab_lock) { + MutexLock mu(Thread::Current(), *Locks::unexpected_signal_lock_); + + HandleUnexpectedSignalCommonDump(signal_number, + info, + raw_context, + handle_timeout_signal, + dump_on_stderr); + } else { + HandleUnexpectedSignalCommonDump(signal_number, + info, + raw_context, + handle_timeout_signal, + dump_on_stderr); + } +} + #if defined(__APPLE__) #pragma GCC diagnostic pop #endif |