summaryrefslogtreecommitdiffstats
path: root/runtime/runtime_linux.cc
diff options
context:
space:
mode:
authorAndreas Gampe <agampe@google.com>2015-01-13 19:48:14 -0800
committerAndreas Gampe <agampe@google.com>2015-01-14 14:08:47 -0800
commit038bb2252ed1d7132f45006507e389b7ba1617ce (patch)
tree3f087fcb6c6a50c860882258c90193c44c2194ec /runtime/runtime_linux.cc
parent07ab4ec97221d882322a1ce064557202150f44ea (diff)
downloadart-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.cc19
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);
}