ART: Fix wrong CHECK in GetCurrentLocationForThrow
Under certain circumstances kDexNoIndex is actually an encoded
dex pc. Change the setup of CurrentMethodVisitor to account for that.
Bug: 16556938
(cherry picked from commit f9df5c1639a9418fcdf70476556a4c30b210701e)
Change-Id: Icb1d42ccd22296e2e0c629ebbd7e4d8c7d87f07a
diff --git a/runtime/monitor_android.cc b/runtime/monitor_android.cc
index c46efd8..d89290b 100644
--- a/runtime/monitor_android.cc
+++ b/runtime/monitor_android.cc
@@ -79,7 +79,6 @@
// Emit the source code file name, <= 37 bytes.
uint32_t pc;
mirror::ArtMethod* m = self->GetCurrentMethod(&pc);
- CHECK_NE(pc, DexFile::kDexNoIndex); // TODO: Can we relax this check?
const char* filename;
uint32_t line_number;
TranslateLocation(m, pc, &filename, &line_number);
diff --git a/runtime/thread.cc b/runtime/thread.cc
index bbc5d99..e5f7aa4 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1972,9 +1972,10 @@
// Note: this visitor may return with a method set, but dex_pc_ being DexFile:kDexNoIndex. This is
// so we don't abort in a special situation (thinlocked monitor) when dumping the Java stack.
struct CurrentMethodVisitor FINAL : public StackVisitor {
- CurrentMethodVisitor(Thread* thread, Context* context)
+ CurrentMethodVisitor(Thread* thread, Context* context, bool fail_on_error)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- : StackVisitor(thread, context), this_object_(nullptr), method_(nullptr), dex_pc_(0) {}
+ : StackVisitor(thread, context), this_object_(nullptr), method_(nullptr), dex_pc_(0),
+ fail_on_error_(fail_on_error) {}
bool VisitFrame() OVERRIDE SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
mirror::ArtMethod* m = GetMethod();
if (m->IsRuntimeMethod()) {
@@ -1985,16 +1986,17 @@
this_object_ = GetThisObject();
}
method_ = m;
- dex_pc_ = GetDexPc(false); // We may not have a valid PC. Let the caller deal with it.
+ dex_pc_ = GetDexPc(fail_on_error_);
return false;
}
mirror::Object* this_object_;
mirror::ArtMethod* method_;
uint32_t dex_pc_;
+ const bool fail_on_error_;
};
mirror::ArtMethod* Thread::GetCurrentMethod(uint32_t* dex_pc) const {
- CurrentMethodVisitor visitor(const_cast<Thread*>(this), nullptr);
+ CurrentMethodVisitor visitor(const_cast<Thread*>(this), nullptr, false);
visitor.WalkStack(false);
if (dex_pc != nullptr) {
*dex_pc = visitor.dex_pc_;
@@ -2004,9 +2006,8 @@
ThrowLocation Thread::GetCurrentLocationForThrow() {
Context* context = GetLongJumpContext();
- CurrentMethodVisitor visitor(this, context);
+ CurrentMethodVisitor visitor(this, context, true);
visitor.WalkStack(false);
- CHECK_NE(visitor.dex_pc_, DexFile::kDexNoIndex); // TODO: Can we relax this?
ReleaseLongJumpContext(context);
return ThrowLocation(visitor.this_object_, visitor.method_, visitor.dex_pc_);
}