From 9f1020305292a21fd14a402b189c765a125226ab Mon Sep 17 00:00:00 2001 From: Sebastien Hertz Date: Fri, 23 May 2014 08:59:42 +0200 Subject: Fix exception reporting from interpreter To comply with JDWP exception report rules, we must report an exception at the location of the throw (or the first instruction encountered after a native call). To do this, we use the CatchLocationFinder visitor to look for a catch handler until we reach a native frame or the top frame. Because interpreter handles pending exception on a method-by-method basis, we need a flag to remember we already reported the exception and avoid reporting it multiple times when unwinding methods. The drawback is we need to maintain the state of this flag. We clear it when the exception is cleared. In the case we temporarily clear the exception (when finding a catch handler for instance), we restore the flag to its previous value at the same time we restore the pending exception. Bump oat version to force recompilation because we modify Thread offsets. Bug: 14402770 Change-Id: Ic059c58f80b2023b118038301f8f0a24f1e18241 --- runtime/debugger.cc | 3 +++ 1 file changed, 3 insertions(+) (limited to 'runtime/debugger.cc') diff --git a/runtime/debugger.cc b/runtime/debugger.cc index 73ed590..a0cecb0 100644 --- a/runtime/debugger.cc +++ b/runtime/debugger.cc @@ -3430,6 +3430,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) { auto old_throw_method = hs.NewHandle(nullptr); auto old_exception = hs.NewHandle(nullptr); uint32_t old_throw_dex_pc; + bool old_exception_report_flag; { ThrowLocation old_throw_location; mirror::Throwable* old_exception_obj = soa.Self()->GetException(&old_throw_location); @@ -3437,6 +3438,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) { old_throw_method.Assign(old_throw_location.GetMethod()); old_exception.Assign(old_exception_obj); old_throw_dex_pc = old_throw_location.GetDexPc(); + old_exception_report_flag = soa.Self()->IsExceptionReportedToInstrumentation(); soa.Self()->ClearException(); } @@ -3491,6 +3493,7 @@ void Dbg::ExecuteMethod(DebugInvokeReq* pReq) { ThrowLocation gc_safe_throw_location(old_throw_this_object.Get(), old_throw_method.Get(), old_throw_dex_pc); soa.Self()->SetException(gc_safe_throw_location, old_exception.Get()); + soa.Self()->SetExceptionReportedToInstrumentation(old_exception_report_flag); } } -- cgit v1.1