summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2018-03-30 18:36:09 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2018-03-30 18:36:09 +0000
commit50c2668b11c3adbd62cc852460bf867b20329e95 (patch)
treebb50d00ff0890c2e10f351f462b47b56b01e78ea
parent846bcc010dc76b3bae8d79d62cf2f83cdaa28e0f (diff)
parentcdd53140b77bf724a4d7451d4b495dbd90875372 (diff)
Merge "ART: Experiment with timeout dumping"
-rw-r--r--runtime/runtime_common.cc94
1 files changed, 70 insertions, 24 deletions
diff --git a/runtime/runtime_common.cc b/runtime/runtime_common.cc
index 59af9187f9..eae2505ce9 100644
--- a/runtime/runtime_common.cc
+++ b/runtime/runtime_common.cc
@@ -371,30 +371,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);
@@ -453,6 +434,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