From 9fd470f87342dfe974c8ec8c74239a547e768650 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Fri, 18 Nov 2016 17:21:12 -0800 Subject: ART: Extend DumpRecursiveAbort Accept recursive dump request for deeper recursions. Otherwise, two or more threads aborting concurrently would ensure that there are no dumps. Test: m test-art-host Change-Id: Ib82d64cceba0de89e352d9b15bcd5708db82498c --- runtime/runtime.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/runtime/runtime.cc b/runtime/runtime.cc index 771ac273fa..1490f05a75 100644 --- a/runtime/runtime.cc +++ b/runtime/runtime.cc @@ -372,9 +372,7 @@ struct AbortState { void Dump(std::ostream& os) const { if (gAborting > 1) { os << "Runtime aborting --- recursively, so no thread-specific detail!\n"; - if (gAborting == 2) { - DumpRecursiveAbort(os); - } + DumpRecursiveAbort(os); return; } gAborting++; @@ -434,8 +432,17 @@ struct AbortState { // For recursive aborts. void DumpRecursiveAbort(std::ostream& os) const NO_THREAD_SAFETY_ANALYSIS { - // The only thing we'll attempt is dumping the native stack of the current thread. - DumpNativeStack(os, GetTid()); + // The only thing we'll attempt is dumping the native stack of the current thread. We will only + // try this if we haven't exceeded an arbitrary amount of recursions, to recover and actually + // die. + // Note: as we're using a global counter for the recursive abort detection, there is a potential + // race here and it is not OK to just print when the counter is "2" (one from + // Runtime::Abort(), one from previous Dump() call). Use a number that seems large enough. + static constexpr size_t kOnlyPrintWhenRecursionLessThan = 100u; + if (gAborting < kOnlyPrintWhenRecursionLessThan) { + gAborting++; + DumpNativeStack(os, GetTid()); + } } }; -- cgit v1.2.3-59-g8ed1b From 320ba91911c840528893e07b0af43d317cd4c9aa Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Fri, 18 Nov 2016 17:39:45 -0800 Subject: ART: Add debug exception check to JIT Check for a pending exception after JIT compilation finishes. Test: m ART_TEST_JIT=true test-art-host Change-Id: I27defaa733f360cb1dbabede62d4908777bc5d2b --- runtime/jit/jit.cc | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/runtime/jit/jit.cc b/runtime/jit/jit.cc index 803e9d5e61..dac2e60987 100644 --- a/runtime/jit/jit.cc +++ b/runtime/jit/jit.cc @@ -274,6 +274,15 @@ bool Jit::CompileMethod(ArtMethod* method, Thread* self, bool osr) { << ArtMethod::PrettyMethod(method_to_compile) << " osr=" << std::boolalpha << osr; } + if (kIsDebugBuild) { + if (self->IsExceptionPending()) { + mirror::Throwable* exception = self->GetException(); + LOG(FATAL) << "No pending exception expected after compiling " + << ArtMethod::PrettyMethod(method) + << ": " + << exception->Dump(); + } + } return success; } -- cgit v1.2.3-59-g8ed1b From f8f36c246ee46522a7446e6f3a155e0fc5c7b859 Mon Sep 17 00:00:00 2001 From: Andreas Gampe Date: Sat, 19 Nov 2016 14:51:52 -0800 Subject: ART: Do not DCHECK in verifier when already aborting Only log an error in FailOrAbort in the debug build when the runtime is already aborting. Test: m test-art-host Change-Id: I240f8bb7695e42d60b5805ebae2ab9dc72e5fdb1 --- runtime/verifier/method_verifier.cc | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/runtime/verifier/method_verifier.cc b/runtime/verifier/method_verifier.cc index d9e3ea7a0d..ed24611801 100644 --- a/runtime/verifier/method_verifier.cc +++ b/runtime/verifier/method_verifier.cc @@ -100,8 +100,18 @@ PcToRegisterLineTable::~PcToRegisterLineTable() {} ALWAYS_INLINE static inline bool FailOrAbort(MethodVerifier* verifier, bool condition, const char* error_msg, uint32_t work_insn_idx) { if (kIsDebugBuild) { - // In a debug build, abort if the error condition is wrong. - DCHECK(condition) << error_msg << work_insn_idx; + // In a debug build, abort if the error condition is wrong. Only warn if + // we are already aborting (as this verification is likely run to print + // lock information). + if (LIKELY(gAborting == 0)) { + DCHECK(condition) << error_msg << work_insn_idx; + } else { + if (!condition) { + LOG(ERROR) << error_msg << work_insn_idx; + verifier->Fail(VERIFY_ERROR_BAD_CLASS_HARD) << error_msg << work_insn_idx; + return true; + } + } } else { // In a non-debug build, just fail the class. if (!condition) { -- cgit v1.2.3-59-g8ed1b