Revert "Revert "JVMTI Exception and ExceptionCatch events""
Fixed error where we were incorrectly not updating a ShadowFrame
dex_pc causing deoptimization errors.
Bug: 62821960
Bug: 65049545
Test: ./test.py --host -j50
Test: ./art/tools/run-libcore-tests.sh \
--mode=host --variant-X32 --debug
This reverts commit 959742483885779f106e000df6dd422fc8657931.
Change-Id: I91ab2bc3e645ddf0359c189b19a59a3ecf0d8921
diff --git a/test/1929-exception-catch-exception/expected.txt b/test/1929-exception-catch-exception/expected.txt
new file mode 100644
index 0000000..7c23a31
--- /dev/null
+++ b/test/1929-exception-catch-exception/expected.txt
@@ -0,0 +1,302 @@
+Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$DoNothingHandler"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$DoNothingHandler"
+main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 caught class art.Test1929$TestException: throwCatchBaseTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchBaseTestException() @ line = 140
+ public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Doing nothing!
+Caught art.Test1929$TestException: "throwCatchBaseTestException"
+Test "art.Test1929$DoThrowCatchBaseTestException": No error caught with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$DoNothingHandler"
+main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161
+ public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197
+ public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$DoNothingHandler"
+main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchTestException() @ line = 207
+ public void art.Test1929$DoThrowCatchTestException.run() @ line = 216
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Doing nothing!
+Caught art.Test1929$TestException: "throwCatchTestException"
+Test "art.Test1929$DoThrowCatchTestException": No error caught with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$DoNothingHandler"
+main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179
+ public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222
+ public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$DoNothingHandler"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$DoNothingHandler"
+Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$ThrowCatchBase"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$ThrowCatchBase"
+main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 caught class art.Test1929$TestException: throwCatchBaseTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchBaseTestException() @ line = 140
+ public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Throwing BaseTestException and catching it!
+Caught art.Test1929$BaseTestException: "ThrowBaseHandler during throw from public static void art.Test1929.throwCatchBaseTestException() @ line = 140"
+Caught art.Test1929$TestException: "throwCatchBaseTestException"
+Test "art.Test1929$DoThrowCatchBaseTestException": No error caught with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowCatchBase"
+main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161
+ public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197
+ public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$ThrowCatchBase"
+main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchTestException() @ line = 207
+ public void art.Test1929$DoThrowCatchTestException.run() @ line = 216
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Throwing BaseTestException and catching it!
+Caught art.Test1929$BaseTestException: "ThrowBaseHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 207"
+Caught art.Test1929$TestException: "throwCatchTestException"
+Test "art.Test1929$DoThrowCatchTestException": No error caught with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowCatchBase"
+main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179
+ public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222
+ public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$ThrowCatchBase"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$ThrowCatchBase"
+Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 caught class art.Test1929$TestException: throwCatchBaseTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchBaseTestException() @ line = 140
+ public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Throwing BaseTestException!
+Test "art.Test1929$DoThrowCatchBaseTestException": Caught error art.Test1929$BaseTestException:"ThrowBaseHandler during throw from public static void art.Test1929.throwCatchBaseTestException() @ line = 140" with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161
+ public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197
+ public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchTestException() @ line = 207
+ public void art.Test1929$DoThrowCatchTestException.run() @ line = 216
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Throwing BaseTestException!
+Test "art.Test1929$DoThrowCatchTestException": Caught error art.Test1929$BaseTestException:"ThrowBaseHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 207" with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179
+ public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222
+ public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$ThrowBaseTestExceptionHandler"
+Test "art.Test1929$DoThrowClass": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: doThrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowClass": Caught error art.Test1929$TestException:"doThrow" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowClass": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchBaseTestException": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+main: public static void art.Test1929.throwCatchBaseTestException() @ line = 140 caught class art.Test1929$TestException: throwCatchBaseTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchBaseTestException() @ line = 140
+ public void art.Test1929$DoThrowCatchBaseTestException.run() @ line = 149
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Throwing TestExceptionNoRethrow!
+Test "art.Test1929$DoThrowCatchBaseTestException": Caught error art.Test1929$TestExceptionNoRethrow:"ThrowTestExceptionNoRethrowHandler during throw from public static void art.Test1929.throwCatchBaseTestException() @ line = 140" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchBaseTestException": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+main: public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161 caught class art.Test1929$TestException: throwCatchBaseTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchBaseTestExceptionTwiceImpl() @ line = 161
+ public static void art.Test1929.throwCatchBaseTestExceptionTwice() @ line = 197
+ public void art.Test1929$DoThrowCatchBaseTestExceptionTwice.run() @ line = 201
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchBaseTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": No error caught with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchBaseTestExceptionTwice": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchTestException": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+main: public static void art.Test1929.throwCatchTestException() @ line = 207 caught class art.Test1929$TestException: throwCatchTestException
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.throwCatchTestException() @ line = 207
+ public void art.Test1929$DoThrowCatchTestException.run() @ line = 216
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+ Throwing TestExceptionNoRethrow!
+Test "art.Test1929$DoThrowCatchTestException": Caught error art.Test1929$TestExceptionNoRethrow:"ThrowTestExceptionNoRethrowHandler during throw from public static void art.Test1929.throwCatchTestException() @ line = 207" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchTestException": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+main: public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179 caught class art.Test1929$TestException: throwCatchTestExceptionTwice
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929$Impl.throwCatchTestExceptionTwiceImpl() @ line = 179
+ public static void art.Test1929.throwCatchTestExceptionTwice() @ line = 222
+ public void art.Test1929$DoThrowCatchTestExceptionTwice.run() @ line = 226
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 280
+Caught art.Test1929$TestException: "throwCatchTestExceptionTwice"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": No error caught with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionTwice": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Running breakpoint with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+main: public static void art.Test1929.run() throws java.lang.Exception @ line = 283 caught class art.Test1929$TestException: throwCatchTestExceptionNoRethrow
+ Current Stack:
+ private static native art.StackTrace$StackFrameData[] art.StackTrace.nativeGetStackTrace(java.lang.Thread) @ line = -1
+ public static art.StackTrace$StackFrameData[] art.StackTrace.GetStackTrace(java.lang.Thread) @ line = 60
+ private static void art.Test1929.PrintStack() @ line = 52
+ public static void art.Test1929.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 65
+ public static void art.Test1929.run() throws java.lang.Exception @ line = 283
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Caught error art.Test1929$TestException:"throwCatchTestExceptionNoRethrow" with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
+Test "art.Test1929$DoThrowCatchTestExceptionNoRethrow": Finished running with handler "art.Test1929$ThrowTestExceptionNoRethrowHandler"
diff --git a/test/1929-exception-catch-exception/info.txt b/test/1929-exception-catch-exception/info.txt
new file mode 100644
index 0000000..2d9b3a0
--- /dev/null
+++ b/test/1929-exception-catch-exception/info.txt
@@ -0,0 +1 @@
+Test JVMTI behavior when throwing exceptions during the Exception catch Event.
diff --git a/test/1929-exception-catch-exception/run b/test/1929-exception-catch-exception/run
new file mode 100755
index 0000000..51875a7
--- /dev/null
+++ b/test/1929-exception-catch-exception/run
@@ -0,0 +1,18 @@
+#!/bin/bash
+#
+# Copyright 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Ask for stack traces to be dumped to a file rather than to stdout.
+./default-run "$@" --jvmti
diff --git a/test/1929-exception-catch-exception/smali/art/Test1929$Impl.smali b/test/1929-exception-catch-exception/smali/art/Test1929$Impl.smali
new file mode 100644
index 0000000..4edd56f
--- /dev/null
+++ b/test/1929-exception-catch-exception/smali/art/Test1929$Impl.smali
@@ -0,0 +1,363 @@
+# Copyright (C) 2017 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# The standard dx/jack/d8 all would leave the move-exception instructions outside of either catch
+# block. This is different from the RI which will leave the corresponding aload.
+#
+# See b/65203529 for more information.
+
+.class public final Lart/Test1929$Impl;
+.super Ljava/lang/Object;
+.source "Test1929.java"
+
+
+# annotations
+.annotation system Ldalvik/annotation/EnclosingClass;
+ value = Lart/Test1929;
+.end annotation
+
+.annotation system Ldalvik/annotation/InnerClass;
+ accessFlags = 0x19
+ name = "Impl"
+.end annotation
+
+
+# direct methods
+.method private constructor <init>()V
+ .registers 1
+
+ .prologue
+ .line 152
+ invoke-direct {p0}, Ljava/lang/Object;-><init>()V
+
+ return-void
+.end method
+
+.method public static throwCatchBaseTestExceptionTwiceImpl()V
+ .registers 4
+
+ .prologue
+ .line 156
+ :try_start_0
+ new-instance v1, Lart/Test1929$TestException;
+
+ const-string v2, "throwCatchBaseTestExceptionTwice"
+
+ invoke-direct {v1, v2}, Lart/Test1929$TestException;-><init>(Ljava/lang/String;)V
+
+ throw v1
+ :try_end_8
+ .catch Lart/Test1929$BaseTestException; {:try_start_0 .. :try_end_8} :catch_8
+
+ .line 157
+ :catch_8
+ # This try needs to include the move-exception
+ :try_start_9
+ move-exception v0
+
+ .line 158
+ .local v0, "t":Lart/Test1929$BaseTestException;
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ new-instance v2, Ljava/lang/StringBuilder;
+
+ invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
+
+ const-string v3, "Caught "
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
+
+ move-result-object v3
+
+ invoke-virtual {v3}, Ljava/lang/Class;->getName()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, ": \""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Lart/Test1929$BaseTestException;->getMessage()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, "\""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
+
+ move-result-object v2
+
+ invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
+
+ .line 159
+ sget-boolean v1, Lart/Test1929;->PRINT_FULL_EXCEPTION:Z
+
+ if-eqz v1, :cond_46
+
+ .line 160
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ invoke-virtual {v0, v1}, Lart/Test1929$BaseTestException;->printStackTrace(Ljava/io/PrintStream;)V
+ :try_end_46
+ .catch Lart/Test1929$BaseTestException; {:try_start_9 .. :try_end_46} :catch_47
+
+ .line 169
+ :cond_46
+ :goto_46
+ return-void
+
+ .line 163
+ :catch_47
+ move-exception v0
+
+ .line 164
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ new-instance v2, Ljava/lang/StringBuilder;
+
+ invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
+
+ const-string v3, "2nd Caught "
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
+
+ move-result-object v3
+
+ invoke-virtual {v3}, Ljava/lang/Class;->getName()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, ": \""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Lart/Test1929$BaseTestException;->getMessage()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, "\""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
+
+ move-result-object v2
+
+ invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
+
+ .line 165
+ sget-boolean v1, Lart/Test1929;->PRINT_FULL_EXCEPTION:Z
+
+ if-eqz v1, :cond_46
+
+ .line 166
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ invoke-virtual {v0, v1}, Lart/Test1929$BaseTestException;->printStackTrace(Ljava/io/PrintStream;)V
+
+ goto :goto_46
+.end method
+
+.method public static throwCatchTestExceptionTwiceImpl()V
+ .registers 4
+
+ .prologue
+ .line 174
+ :try_start_0
+ new-instance v1, Lart/Test1929$TestException;
+
+ const-string v2, "throwCatchTestExceptionTwice"
+
+ invoke-direct {v1, v2}, Lart/Test1929$TestException;-><init>(Ljava/lang/String;)V
+
+ throw v1
+ :try_end_8
+ .catch Lart/Test1929$TestException; {:try_start_0 .. :try_end_8} :catch_8
+
+ .line 175
+ :catch_8
+ # This try needs to include the move-exception
+ :try_start_9
+ move-exception v0
+
+ .line 176
+ .local v0, "t":Lart/Test1929$TestException;
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ new-instance v2, Ljava/lang/StringBuilder;
+
+ invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
+
+ const-string v3, "Caught "
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
+
+ move-result-object v3
+
+ invoke-virtual {v3}, Ljava/lang/Class;->getName()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, ": \""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Lart/Test1929$TestException;->getMessage()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, "\""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
+
+ move-result-object v2
+
+ invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
+
+ .line 177
+ sget-boolean v1, Lart/Test1929;->PRINT_FULL_EXCEPTION:Z
+
+ if-eqz v1, :cond_46
+
+ .line 178
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ invoke-virtual {v0, v1}, Lart/Test1929$TestException;->printStackTrace(Ljava/io/PrintStream;)V
+ :try_end_46
+ .catch Lart/Test1929$TestException; {:try_start_9 .. :try_end_46} :catch_47
+
+ .line 187
+ :cond_46
+ :goto_46
+ return-void
+
+ .line 181
+ :catch_47
+ move-exception v0
+
+ .line 182
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ new-instance v2, Ljava/lang/StringBuilder;
+
+ invoke-direct {v2}, Ljava/lang/StringBuilder;-><init>()V
+
+ const-string v3, "2nd Caught "
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;
+
+ move-result-object v3
+
+ invoke-virtual {v3}, Ljava/lang/Class;->getName()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, ": \""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v0}, Lart/Test1929$TestException;->getMessage()Ljava/lang/String;
+
+ move-result-object v3
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ const-string v3, "\""
+
+ invoke-virtual {v2, v3}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
+
+ move-result-object v2
+
+ invoke-virtual {v2}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
+
+ move-result-object v2
+
+ invoke-virtual {v1, v2}, Ljava/io/PrintStream;->println(Ljava/lang/String;)V
+
+ .line 183
+ sget-boolean v1, Lart/Test1929;->PRINT_FULL_EXCEPTION:Z
+
+ if-eqz v1, :cond_46
+
+ .line 184
+ sget-object v1, Ljava/lang/System;->out:Ljava/io/PrintStream;
+
+ invoke-virtual {v0, v1}, Lart/Test1929$TestException;->printStackTrace(Ljava/io/PrintStream;)V
+
+ goto :goto_46
+.end method
diff --git a/test/1929-exception-catch-exception/src/Main.java b/test/1929-exception-catch-exception/src/Main.java
new file mode 100644
index 0000000..4651bac
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/Main.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+public class Main {
+ public static void main(String[] args) throws Exception {
+ art.Test1929.run();
+ }
+}
diff --git a/test/1929-exception-catch-exception/src/art/Breakpoint.java b/test/1929-exception-catch-exception/src/art/Breakpoint.java
new file mode 100644
index 0000000..bbb89f7
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Breakpoint.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.lang.reflect.Executable;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.Objects;
+
+public class Breakpoint {
+ public static class Manager {
+ public static class BP {
+ public final Executable method;
+ public final long location;
+
+ public BP(Executable method) {
+ this(method, getStartLocation(method));
+ }
+
+ public BP(Executable method, long location) {
+ this.method = method;
+ this.location = location;
+ }
+
+ @Override
+ public boolean equals(Object other) {
+ return (other instanceof BP) &&
+ method.equals(((BP)other).method) &&
+ location == ((BP)other).location;
+ }
+
+ @Override
+ public String toString() {
+ return method.toString() + " @ " + getLine();
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(method, location);
+ }
+
+ public int getLine() {
+ try {
+ LineNumber[] lines = getLineNumberTable(method);
+ int best = -1;
+ for (LineNumber l : lines) {
+ if (l.location > location) {
+ break;
+ } else {
+ best = l.line;
+ }
+ }
+ return best;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+ }
+
+ private Set<BP> breaks = new HashSet<>();
+
+ public void setBreakpoints(BP... bs) {
+ for (BP b : bs) {
+ if (breaks.add(b)) {
+ Breakpoint.setBreakpoint(b.method, b.location);
+ }
+ }
+ }
+ public void setBreakpoint(Executable method, long location) {
+ setBreakpoints(new BP(method, location));
+ }
+
+ public void clearBreakpoints(BP... bs) {
+ for (BP b : bs) {
+ if (breaks.remove(b)) {
+ Breakpoint.clearBreakpoint(b.method, b.location);
+ }
+ }
+ }
+ public void clearBreakpoint(Executable method, long location) {
+ clearBreakpoints(new BP(method, location));
+ }
+
+ public void clearAllBreakpoints() {
+ clearBreakpoints(breaks.toArray(new BP[0]));
+ }
+ }
+
+ public static void startBreakpointWatch(Class<?> methodClass,
+ Executable breakpointReached,
+ Thread thr) {
+ startBreakpointWatch(methodClass, breakpointReached, false, thr);
+ }
+
+ /**
+ * Enables the trapping of breakpoint events.
+ *
+ * If allowRecursive == true then breakpoints will be sent even if one is currently being handled.
+ */
+ public static native void startBreakpointWatch(Class<?> methodClass,
+ Executable breakpointReached,
+ boolean allowRecursive,
+ Thread thr);
+ public static native void stopBreakpointWatch(Thread thr);
+
+ public static final class LineNumber implements Comparable<LineNumber> {
+ public final long location;
+ public final int line;
+
+ private LineNumber(long loc, int line) {
+ this.location = loc;
+ this.line = line;
+ }
+
+ public boolean equals(Object other) {
+ return other instanceof LineNumber && ((LineNumber)other).line == line &&
+ ((LineNumber)other).location == location;
+ }
+
+ public int compareTo(LineNumber other) {
+ int v = Integer.valueOf(line).compareTo(Integer.valueOf(other.line));
+ if (v != 0) {
+ return v;
+ } else {
+ return Long.valueOf(location).compareTo(Long.valueOf(other.location));
+ }
+ }
+ }
+
+ public static native void setBreakpoint(Executable m, long loc);
+ public static void setBreakpoint(Executable m, LineNumber l) {
+ setBreakpoint(m, l.location);
+ }
+
+ public static native void clearBreakpoint(Executable m, long loc);
+ public static void clearBreakpoint(Executable m, LineNumber l) {
+ clearBreakpoint(m, l.location);
+ }
+
+ private static native Object[] getLineNumberTableNative(Executable m);
+ public static LineNumber[] getLineNumberTable(Executable m) {
+ Object[] nativeTable = getLineNumberTableNative(m);
+ long[] location = (long[])(nativeTable[0]);
+ int[] lines = (int[])(nativeTable[1]);
+ if (lines.length != location.length) {
+ throw new Error("Lines and locations have different lengths!");
+ }
+ LineNumber[] out = new LineNumber[lines.length];
+ for (int i = 0; i < lines.length; i++) {
+ out[i] = new LineNumber(location[i], lines[i]);
+ }
+ return out;
+ }
+
+ public static native long getStartLocation(Executable m);
+
+ public static int locationToLine(Executable m, long location) {
+ try {
+ Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
+ int best = -1;
+ for (Breakpoint.LineNumber l : lines) {
+ if (l.location > location) {
+ break;
+ } else {
+ best = l.line;
+ }
+ }
+ return best;
+ } catch (Exception e) {
+ return -1;
+ }
+ }
+
+ public static long lineToLocation(Executable m, int line) throws Exception {
+ try {
+ Breakpoint.LineNumber[] lines = Breakpoint.getLineNumberTable(m);
+ for (Breakpoint.LineNumber l : lines) {
+ if (l.line == line) {
+ return l.location;
+ }
+ }
+ throw new Exception("Unable to find line " + line + " in " + m);
+ } catch (Exception e) {
+ throw new Exception("Unable to get line number info for " + m, e);
+ }
+ }
+}
+
diff --git a/test/1929-exception-catch-exception/src/art/Exceptions.java b/test/1929-exception-catch-exception/src/art/Exceptions.java
new file mode 100644
index 0000000..2c959ec
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Exceptions.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
+public class Exceptions {
+ public static native void setupExceptionTracing(
+ Class<?> methodClass,
+ Class<?> exceptionClass,
+ Method exceptionEventMethod,
+ Method exceptionCaughtEventMethod);
+
+ public static native void enableExceptionCatchEvent(Thread thr);
+ public static native void enableExceptionEvent(Thread thr);
+ public static native void disableExceptionCatchEvent(Thread thr);
+ public static native void disableExceptionEvent(Thread thr);
+}
diff --git a/test/1929-exception-catch-exception/src/art/StackTrace.java b/test/1929-exception-catch-exception/src/art/StackTrace.java
new file mode 100644
index 0000000..b12c3df
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/StackTrace.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Executable;
+
+public class StackTrace {
+ public static class StackFrameData {
+ public final Thread thr;
+ public final Executable method;
+ public final long current_location;
+ public final int depth;
+
+ public StackFrameData(Thread thr, Executable e, long loc, int depth) {
+ this.thr = thr;
+ this.method = e;
+ this.current_location = loc;
+ this.depth = depth;
+ }
+ @Override
+ public String toString() {
+ return String.format(
+ "StackFrameData { thr: '%s', method: '%s', loc: %d, depth: %d }",
+ this.thr,
+ this.method,
+ this.current_location,
+ this.depth);
+ }
+ }
+
+ public static native int GetStackDepth(Thread thr);
+
+ private static native StackFrameData[] nativeGetStackTrace(Thread thr);
+
+ public static StackFrameData[] GetStackTrace(Thread thr) {
+ // The RI seems to give inconsistent (and sometimes nonsensical) results if the thread is not
+ // suspended. The spec says that not being suspended is fine but since we want this to be
+ // consistent we will suspend for the RI.
+ boolean suspend_thread =
+ !System.getProperty("java.vm.name").equals("Dalvik") &&
+ !thr.equals(Thread.currentThread());
+ if (suspend_thread) {
+ Suspension.suspend(thr);
+ }
+ StackFrameData[] out = nativeGetStackTrace(thr);
+ if (suspend_thread) {
+ Suspension.resume(thr);
+ }
+ return out;
+ }
+}
+
diff --git a/test/1929-exception-catch-exception/src/art/Suspension.java b/test/1929-exception-catch-exception/src/art/Suspension.java
new file mode 100644
index 0000000..16e62cc
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Suspension.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+public class Suspension {
+ // Suspends a thread using jvmti.
+ public native static void suspend(Thread thr);
+
+ // Resumes a thread using jvmti.
+ public native static void resume(Thread thr);
+
+ public native static boolean isSuspended(Thread thr);
+
+ public native static int[] suspendList(Thread... threads);
+ public native static int[] resumeList(Thread... threads);
+}
diff --git a/test/1929-exception-catch-exception/src/art/Test1929.java b/test/1929-exception-catch-exception/src/art/Test1929.java
new file mode 100644
index 0000000..07d2087
--- /dev/null
+++ b/test/1929-exception-catch-exception/src/art/Test1929.java
@@ -0,0 +1,300 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package art;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Objects;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+
+public class Test1929 {
+ public static boolean PRINT_FULL_EXCEPTION = false;
+ public static ExceptionHandler HANDLER = null;
+ public static Collection<Executable> TEST_METHODS;
+
+ public static void doNothing() {};
+ static {
+ try {
+ TEST_METHODS = Arrays.asList(
+ Test1929.class.getDeclaredMethod("doThrow"),
+ Test1929.class.getDeclaredMethod("throwCatchBaseTestException"),
+ Test1929.class.getDeclaredMethod("throwCatchBaseTestExceptionTwice"),
+ Test1929.class.getDeclaredMethod("throwCatchTestException"),
+ Test1929.class.getDeclaredMethod("throwCatchTestExceptionTwice"),
+ Test1929.class.getDeclaredMethod("throwCatchTestExceptionNoRethrow"));
+ } catch (Exception e) {
+ throw new Error("Unable to list test methods!", e);
+ }
+ }
+
+ public static interface ExceptionHandler {
+ public void exceptionOccurred(
+ Executable m, long loc, Throwable exception);
+ }
+
+ private static void PrintStack() {
+ System.out.println("\tCurrent Stack:");
+ for (StackTrace.StackFrameData e : StackTrace.GetStackTrace(Thread.currentThread())) {
+ if (Objects.equals(e.method.getDeclaringClass().getPackage(), Test1929.class.getPackage())) {
+ System.out.println("\t\t" + e.method + " @ line = " +
+ Breakpoint.locationToLine(e.method, e.current_location));
+ }
+ }
+ }
+
+ public static void ExceptionCatchEvent(
+ Thread thr, Executable method, long location, Throwable exception) {
+ System.out.println(thr.getName() + ": " + method + " @ line = " +
+ Breakpoint.locationToLine(method, location) + " caught " +
+ exception.getClass() + ": " + exception.getMessage());
+ PrintStack();
+ if (PRINT_FULL_EXCEPTION) {
+ System.out.print("exception is: ");
+ exception.printStackTrace(System.out);
+ }
+ if (HANDLER != null && TEST_METHODS.contains(method)) {
+ HANDLER.exceptionOccurred(method, location, exception);
+ }
+ }
+
+ public static class BaseTestException extends Error {
+ public BaseTestException(String e) { super(e); }
+ public BaseTestException(String e, Throwable t) { super(e, t); }
+ }
+ public static class TestException extends BaseTestException {
+ public TestException(String e) { super(e); }
+ public TestException(String e, Throwable t) { super(e, t); }
+ }
+
+ public static class TestExceptionNoRethrow extends TestException {
+ public TestExceptionNoRethrow(String e) { super(e); }
+ public TestExceptionNoRethrow(String e, Throwable t) { super(e, t); }
+ }
+
+ public static class DoNothingHandler implements ExceptionHandler {
+ public void exceptionOccurred(Executable m, long loc, Throwable exception) {
+ System.out.println("\tDoing nothing!");
+ return;
+ }
+ }
+
+ public static class ThrowCatchBase implements ExceptionHandler {
+ public void exceptionOccurred(Executable m, long loc, Throwable exception) {
+ System.out.println("\tThrowing BaseTestException and catching it!");
+ try {
+ throw new BaseTestException("ThrowBaseHandler during throw from " + m + " @ line = " +
+ Breakpoint.locationToLine(m, loc), exception);
+ } catch (BaseTestException t) {
+ System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ }
+ }
+ public static class ThrowBaseTestExceptionHandler implements ExceptionHandler {
+ public void exceptionOccurred(Executable m, long loc, Throwable exception) {
+ System.out.println("\tThrowing BaseTestException!");
+ throw new BaseTestException("ThrowBaseHandler during throw from " + m + " @ line = " +
+ Breakpoint.locationToLine(m, loc), exception);
+ }
+ }
+
+ public static class ThrowTestExceptionNoRethrowHandler implements ExceptionHandler {
+ public void exceptionOccurred(Executable m, long loc, Throwable exception) {
+ if (exception instanceof TestExceptionNoRethrow) {
+ System.out.println("\tInstance of TestExceptionNoRethrow was thrown. Not throwing again.");
+ } else {
+ System.out.println("\tThrowing TestExceptionNoRethrow!");
+ throw new TestExceptionNoRethrow("ThrowTestExceptionNoRethrowHandler during throw from " +
+ m + " @ line = " + Breakpoint.locationToLine(m, loc), exception);
+ }
+ }
+ }
+ public static void doThrow() {
+ throw new TestException("doThrow");
+ }
+
+ public static class DoThrowClass implements Runnable {
+ public void run() { doThrow(); }
+ }
+
+ public static void throwCatchBaseTestException() {
+ try {
+ throw new TestException("throwCatchBaseTestException");
+ } catch (BaseTestException t) {
+ System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ }
+
+ public static class DoThrowCatchBaseTestException implements Runnable {
+ public void run() { throwCatchBaseTestException(); }
+ }
+
+ // dx/d8/jack all do an optimization around catch blocks that (while legal) breaks assumptions
+ // this test relies on so we have the actual implementation be corrected smali. This does work
+ // for RI however.
+ public static final class Impl {
+ private Impl() {}
+ public static void throwCatchBaseTestExceptionTwiceImpl() {
+ try {
+ try {
+ throw new TestException("throwCatchBaseTestExceptionTwice");
+ } catch (BaseTestException t) {
+ System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ } catch (BaseTestException t) {
+ System.out.println("2nd Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ }
+
+ public static void throwCatchTestExceptionTwiceImpl() {
+ try {
+ try {
+ throw new TestException("throwCatchTestExceptionTwice");
+ } catch (TestException t) {
+ System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ } catch (TestException t) {
+ System.out.println("2nd Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ }
+ }
+
+ public static void throwCatchBaseTestExceptionTwice() {
+ // The implementation of this has to change depending upon the runtime slightly due to compiler
+ // optimizations present in DX/D8/Jack.
+ Impl.throwCatchBaseTestExceptionTwiceImpl();
+ }
+
+ public static class DoThrowCatchBaseTestExceptionTwice implements Runnable {
+ public void run() { throwCatchBaseTestExceptionTwice(); }
+ }
+
+ public static void throwCatchTestException() {
+ try {
+ throw new TestException("throwCatchTestException");
+ } catch (TestException t) {
+ System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ }
+
+ public static class DoThrowCatchTestException implements Runnable {
+ public void run() { throwCatchTestException(); }
+ }
+
+ public static void throwCatchTestExceptionTwice() {
+ // The implementation of this has to change depending upon the runtime slightly due to compiler
+ // optimizations present in DX/D8/Jack.
+ Impl.throwCatchTestExceptionTwiceImpl();
+ }
+
+ public static class DoThrowCatchTestExceptionTwice implements Runnable {
+ public void run() { throwCatchTestExceptionTwice(); }
+ }
+
+ public static void throwCatchTestExceptionNoRethrow() {
+ try {
+ throw new TestException("throwCatchTestExceptionNoRethrow");
+ } catch (TestExceptionNoRethrow t) {
+ System.out.println("Caught " + t.getClass().getName() + ": \"" + t.getMessage() + "\"");
+ if (PRINT_FULL_EXCEPTION) {
+ t.printStackTrace(System.out);
+ }
+ }
+ }
+
+ public static class DoThrowCatchTestExceptionNoRethrow implements Runnable {
+ public void run() { throwCatchTestExceptionNoRethrow(); }
+ }
+
+ public static void run() throws Exception {
+ // Set up breakpoints
+ Exceptions.setupExceptionTracing(
+ Test1929.class,
+ TestException.class,
+ null,
+ Test1929.class.getDeclaredMethod(
+ "ExceptionCatchEvent",
+ Thread.class,
+ Executable.class,
+ Long.TYPE,
+ Throwable.class));
+ Exceptions.enableExceptionCatchEvent(Thread.currentThread());
+
+ ExceptionHandler[] handlers = new ExceptionHandler[] {
+ new DoNothingHandler(),
+ new ThrowCatchBase(),
+ new ThrowBaseTestExceptionHandler(),
+ new ThrowTestExceptionNoRethrowHandler(),
+ };
+
+ Runnable[] tests = new Runnable[] {
+ new DoThrowClass(),
+ new DoThrowCatchBaseTestException(),
+ new DoThrowCatchBaseTestExceptionTwice(),
+ new DoThrowCatchTestException(),
+ new DoThrowCatchTestExceptionTwice(),
+ new DoThrowCatchTestExceptionNoRethrow(),
+ };
+
+ for (ExceptionHandler handler : handlers) {
+ for (Runnable test : tests) {
+ try {
+ HANDLER = handler;
+ System.out.printf("Test \"%s\": Running breakpoint with handler \"%s\"\n",
+ test.getClass().getName(), handler.getClass().getName());
+ test.run();
+ System.out.printf("Test \"%s\": No error caught with handler \"%s\"\n",
+ test.getClass().getName(), handler.getClass().getName());
+ } catch (Throwable e) {
+ System.out.printf("Test \"%s\": Caught error %s:\"%s\" with handler \"%s\"\n",
+ test.getClass().getName(),
+ e.getClass().getName(),
+ e.getMessage(),
+ handler.getClass().getName());
+ if (PRINT_FULL_EXCEPTION) {
+ e.printStackTrace(System.out);
+ }
+ }
+ System.out.printf("Test \"%s\": Finished running with handler \"%s\"\n",
+ test.getClass().getName(), handler.getClass().getName());
+ HANDLER = null;
+ }
+ }
+ Exceptions.disableExceptionCatchEvent(Thread.currentThread());
+ }
+}