diff options
author | Andreas Gampe <agampe@google.com> | 2015-01-13 19:48:14 -0800 |
---|---|---|
committer | Andreas Gampe <agampe@google.com> | 2015-01-14 14:08:47 -0800 |
commit | 038bb2252ed1d7132f45006507e389b7ba1617ce (patch) | |
tree | 3f087fcb6c6a50c860882258c90193c44c2194ec /runtime/runtime_linux.cc | |
parent | 07ab4ec97221d882322a1ce064557202150f44ea (diff) | |
download | art-038bb2252ed1d7132f45006507e389b7ba1617ce.tar.gz art-038bb2252ed1d7132f45006507e389b7ba1617ce.tar.bz2 art-038bb2252ed1d7132f45006507e389b7ba1617ce.zip |
ART: Dump all threads on test timeout
Use SIGRTMIN+2 as a special signal to dump all threads similar to
SIGQUIT. Use nested timeouts to enforce a test timeout and dump
the threads in a deadlock.
Bug: 18933933
Change-Id: I4209047eeca07ff360d7c19922d5b5da64fd69a5
Diffstat (limited to 'runtime/runtime_linux.cc')
-rw-r--r-- | runtime/runtime_linux.cc | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/runtime/runtime_linux.cc b/runtime/runtime_linux.cc index a5a02042ac..a0adcd1082 100644 --- a/runtime/runtime_linux.cc +++ b/runtime/runtime_linux.cc @@ -28,6 +28,7 @@ #include "base/mutex.h" #include "base/stringprintf.h" #include "thread-inl.h" +#include "thread_list.h" #include "utils.h" namespace art { @@ -283,10 +284,22 @@ struct UContext { mcontext_t& context; }; +static int GetTimeoutSignal() { + return SIGRTMIN + 2; +} + +static bool IsTimeoutSignal(int signal_number) { + return signal_number == GetTimeoutSignal(); +} + void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_context) { static bool handlingUnexpectedSignal = false; if (handlingUnexpectedSignal) { LogMessage::LogLine(__FILE__, __LINE__, INTERNAL_FATAL, "HandleUnexpectedSignal reentered\n"); + if (IsTimeoutSignal(signal_number)) { + // Ignore a recursive timeout. + return; + } _exit(1); } handlingUnexpectedSignal = true; @@ -320,6 +333,10 @@ void HandleUnexpectedSignal(int signal_number, siginfo_t* info, void* raw_contex << "Backtrace:\n" << Dumpable<Backtrace>(thread_backtrace); Runtime* runtime = Runtime::Current(); if (runtime != nullptr) { + if (IsTimeoutSignal(signal_number)) { + // Special timeout signal. Try to dump all threads. + runtime->GetThreadList()->DumpForSigQuit(LOG(INTERNAL_FATAL)); + } gc::Heap* heap = runtime->GetHeap(); LOG(INTERNAL_FATAL) << "Fault message: " << runtime->GetFaultMessage(); if (kDumpHeapObjectOnSigsevg && heap != nullptr && info != nullptr) { @@ -374,6 +391,8 @@ void Runtime::InitPlatformSignalHandlers() { rc += sigaction(SIGSTKFLT, &action, NULL); #endif rc += sigaction(SIGTRAP, &action, NULL); + // Special dump-all timeout. + rc += sigaction(GetTimeoutSignal(), &action, NULL); CHECK_EQ(rc, 0); } |