summaryrefslogtreecommitdiff
path: root/runtime/instrumentation.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/instrumentation.cc')
-rw-r--r--runtime/instrumentation.cc29
1 files changed, 29 insertions, 0 deletions
diff --git a/runtime/instrumentation.cc b/runtime/instrumentation.cc
index b3528d8d42..4d8c6872e8 100644
--- a/runtime/instrumentation.cc
+++ b/runtime/instrumentation.cc
@@ -110,6 +110,7 @@ Instrumentation::Instrumentation()
have_watched_frame_pop_listeners_(false),
have_branch_listeners_(false),
have_invoke_virtual_or_interface_listeners_(false),
+ have_exception_handled_listeners_(false),
deoptimized_methods_lock_("deoptimized methods lock", kDeoptimizedMethodsLock),
deoptimization_enabled_(false),
interpreter_handler_table_(kMainHandlerTable),
@@ -513,6 +514,11 @@ void Instrumentation::AddListener(InstrumentationListener* listener, uint32_t ev
watched_frame_pop_listeners_,
listener,
&have_watched_frame_pop_listeners_);
+ PotentiallyAddListenerTo(kExceptionHandled,
+ events,
+ exception_handled_listeners_,
+ listener,
+ &have_exception_handled_listeners_);
UpdateInterpreterHandlerTable();
}
@@ -595,6 +601,11 @@ void Instrumentation::RemoveListener(InstrumentationListener* listener, uint32_t
watched_frame_pop_listeners_,
listener,
&have_watched_frame_pop_listeners_);
+ PotentiallyRemoveListenerFrom(kExceptionHandled,
+ events,
+ exception_handled_listeners_,
+ listener,
+ &have_exception_handled_listeners_);
UpdateInterpreterHandlerTable();
}
@@ -1118,10 +1129,28 @@ void Instrumentation::ExceptionThrownEvent(Thread* thread,
listener->ExceptionThrown(thread, h_exception);
}
}
+ // See b/65049545 for discussion about this behavior.
+ thread->AssertNoPendingException();
thread->SetException(h_exception.Get());
}
}
+void Instrumentation::ExceptionHandledEvent(Thread* thread,
+ mirror::Throwable* exception_object) const {
+ Thread* self = Thread::Current();
+ StackHandleScope<1> hs(self);
+ Handle<mirror::Throwable> h_exception(hs.NewHandle(exception_object));
+ if (HasExceptionHandledListeners()) {
+ // We should have cleared the exception so that callers can detect a new one.
+ DCHECK(thread->GetException() == nullptr);
+ for (InstrumentationListener* listener : exception_handled_listeners_) {
+ if (listener != nullptr) {
+ listener->ExceptionHandled(thread, h_exception);
+ }
+ }
+ }
+}
+
// Computes a frame ID by ignoring inlined frames.
size_t Instrumentation::ComputeFrameId(Thread* self,
size_t frame_depth,