summaryrefslogtreecommitdiffstats
path: root/runtime/debugger.cc
diff options
context:
space:
mode:
authorSebastien Hertz <shertz@google.com>2015-05-26 11:53:39 +0200
committerSebastien Hertz <shertz@google.com>2015-05-26 16:36:57 +0200
commit54d65738eecc1fa79ed528ff2f6b9b4f7a4743be (patch)
tree6ea5d01df3d370c24a8401c5a1ee8a3c7bf58407 /runtime/debugger.cc
parent8ae14d8ed082b1d479b8488831d74acb06cd31c8 (diff)
downloadart-54d65738eecc1fa79ed528ff2f6b9b4f7a4743be.zip
art-54d65738eecc1fa79ed528ff2f6b9b4f7a4743be.tar.gz
art-54d65738eecc1fa79ed528ff2f6b9b4f7a4743be.tar.bz2
JDWP: fix breakpoint on catch statement
Setting a breakpoint on a catch statement in the source actually installs the breakpoint on a DEX move-exception instruction. At this point, an exception is pending in the current thread. The issue is no exception must be pending in the current thread to report the breakpoint event. This is required to be able to call JNI functions to create JDWP ids. This CL fixes it by clearing the pending exception before reporting event and restore it after reporting the event. Bug: 21382373 (cherry picked from commit de48aa6708a3d5dacf7db3d64965e23261fb15d3) Change-Id: Ie107eb47b6f2559c4fa5297f4033e07baad06f38
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 0eb7f2b..ef1aa6a 100644
--- a/runtime/debugger.cc
+++ b/runtime/debugger.cc
@@ -2806,7 +2806,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,