summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Treehugger Robot <treehugger-gerrit@google.com> 2016-11-20 00:37:56 +0000
committer Gerrit Code Review <noreply-gerritcodereview@google.com> 2016-11-20 00:37:57 +0000
commitaf524438b8a76264a23ec2d748e11eeded02abc7 (patch)
treef202c1fe8aa1ae1a8b4f3d609ad4a011f7ffca4b
parentab07cbe238fc41cc074bd2af87a0b3fcdddedf27 (diff)
parentf8f36c246ee46522a7446e6f3a155e0fc5c7b859 (diff)
Merge changes I240f8bb7,I27defaa7,Ib82d64cc
* changes: ART: Do not DCHECK in verifier when already aborting ART: Add debug exception check to JIT ART: Extend DumpRecursiveAbort
-rw-r--r--runtime/jit/jit.cc9
-rw-r--r--runtime/runtime.cc17
-rw-r--r--runtime/verifier/method_verifier.cc14
3 files changed, 33 insertions, 7 deletions
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;
}
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());
+ }
}
};
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) {