summaryrefslogtreecommitdiff
path: root/runtime/debugger.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/debugger.cc')
-rw-r--r--runtime/debugger.cc20
1 files changed, 20 insertions, 0 deletions
diff --git a/runtime/debugger.cc b/runtime/debugger.cc
index c3c0395f5b..0752c59a90 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -2807,7 +2807,27 @@ void Dbg::PostLocationEvent(mirror::ArtMethod* m, int dex_pc, mirror::Object* th
JDWP::EventLocation location;
SetEventLocation(&location, m, dex_pc);
+ // We need to be sure no exception is pending when calling JdwpState::PostLocationEvent.
+ // This is required to be able to call JNI functions to create JDWP ids. To achieve this,
+ // we temporarily clear the current thread's exception (if any) and will restore it after
+ // the call.
+ // Note: the only way to get a pending exception here is to suspend on a move-exception
+ // instruction.
+ Thread* const self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Throwable> pending_exception(hs.NewHandle(self->GetException()));
+ self->ClearException();
+ if (kIsDebugBuild && pending_exception.Get() != nullptr) {
+ const DexFile::CodeItem* code_item = location.method->GetCodeItem();
+ const Instruction* instr = Instruction::At(&code_item->insns_[location.dex_pc]);
+ CHECK_EQ(Instruction::MOVE_EXCEPTION, instr->Opcode());
+ }
+
gJdwpState->PostLocationEvent(&location, this_object, event_flags, return_value);
+
+ if (pending_exception.Get() != nullptr) {
+ self->SetException(pending_exception.Get());
+ }
}
void Dbg::PostFieldAccessEvent(mirror::ArtMethod* m, int dex_pc,