Implement JDWP InvokeMethod and breakpoints on exception throwing.
Change-Id: I1142bee843104f0850fd7270752104d5d73a44f0
diff --git a/src/thread.cc b/src/thread.cc
index 53155b6..26eaf68 100644
--- a/src/thread.cc
+++ b/src/thread.cc
@@ -1347,10 +1347,10 @@
void Thread::DeliverException() {
const bool kDebugExceptionDelivery = false;
- Throwable *exception = GetException(); // Get exception from thread
+ Throwable* exception = GetException(); // Get exception from thread
CHECK(exception != NULL);
// Don't leave exception visible while we try to find the handler, which may cause class
- // resolution
+ // resolution.
ClearException();
if (kDebugExceptionDelivery) {
DumpStack(LOG(INFO) << "Delivering exception: " << PrettyTypeOf(exception) << std::endl);
@@ -1360,22 +1360,27 @@
CatchBlockStackVisitor catch_finder(exception->GetClass(), long_jump_context);
WalkStackUntilUpCall(&catch_finder, true);
+ Method** sp;
+ uintptr_t throw_native_pc;
+ Method* throw_method = GetCurrentMethod(&throw_native_pc, &sp);
+ uintptr_t catch_native_pc = catch_finder.handler_pc_;
+ Method* catch_method = catch_finder.handler_frame_.GetMethod();
+ Dbg::PostException(sp, throw_method, throw_native_pc, catch_method, catch_native_pc, exception);
+
if (kDebugExceptionDelivery) {
- Method* handler_method = catch_finder.handler_frame_.GetMethod();
- if (handler_method == NULL) {
+ if (catch_method == NULL) {
LOG(INFO) << "Handler is upcall";
} else {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
const DexFile& dex_file =
- class_linker->FindDexFile(handler_method->GetDeclaringClass()->GetDexCache());
- int line_number = dex_file.GetLineNumFromPC(handler_method,
- handler_method->ToDexPC(catch_finder.handler_pc_));
- LOG(INFO) << "Handler: " << PrettyMethod(handler_method)
- << " (line: " << line_number << ")";
+ class_linker->FindDexFile(catch_method->GetDeclaringClass()->GetDexCache());
+ int line_number = dex_file.GetLineNumFromPC(catch_method,
+ catch_method->ToDexPC(catch_finder.handler_pc_));
+ LOG(INFO) << "Handler: " << PrettyMethod(catch_method) << " (line: " << line_number << ")";
}
}
SetException(exception);
- long_jump_context->SetSP(reinterpret_cast<intptr_t>(catch_finder.handler_frame_.GetSP()));
+ long_jump_context->SetSP(reinterpret_cast<uintptr_t>(catch_finder.handler_frame_.GetSP()));
long_jump_context->SetPC(catch_finder.handler_pc_);
long_jump_context->DoLongJump();
}
@@ -1389,25 +1394,24 @@
return result;
}
-const Method* Thread::GetCurrentMethod() const {
- Method* m = top_of_managed_stack_.GetMethod();
+Method* Thread::GetCurrentMethod(uintptr_t* pc, Method*** sp) const {
+ Frame f = top_of_managed_stack_;
+ Method* m = f.GetMethod();
// We use JNI internally for exception throwing, so it's possible to arrive
// here via a "FromCode" function, in which case there's a synthetic
// callee-save method at the top of the stack. These shouldn't be user-visible,
// so if we find one, skip it and return the compiled method underneath.
if (m != NULL && m->IsCalleeSaveMethod()) {
- Frame f = top_of_managed_stack_;
f.Next();
m = f.GetMethod();
}
- return m;
-}
-
-uint32_t Thread::GetCurrentReturnPc() const {
- if (top_of_managed_stack_.GetMethod() == NULL) {
- return 0;
+ if (pc != NULL) {
+ *pc = ManglePc(f.GetReturnPC());
}
- return ManglePc(top_of_managed_stack_.GetReturnPC());
+ if (sp != NULL) {
+ *sp = f.GetSP();
+ }
+ return m;
}
bool Thread::HoldsLock(Object* object) {