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/1927-exception-event/exception_event.cc b/test/1927-exception-event/exception_event.cc
new file mode 100644
index 0000000..3197bcd
--- /dev/null
+++ b/test/1927-exception-event/exception_event.cc
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+#include <pthread.h>
+
+#include <cstdio>
+#include <iostream>
+#include <vector>
+
+#include "android-base/logging.h"
+#include "jni.h"
+#include "jvmti.h"
+
+#include "scoped_local_ref.h"
+#include "scoped_primitive_array.h"
+
+// Test infrastructure
+#include "jvmti_helper.h"
+#include "test_env.h"
+
+namespace art {
+namespace Test1927ExceptionEvent {
+
+static void ThrowNative(JNIEnv* env) {
+ ScopedLocalRef<jclass> exception(env, env->FindClass("art/Test1927$TestException"));
+ env->ThrowNew(exception.get(), "from native");
+}
+
+static void CallMethod(JNIEnv* env, jclass test, const char* name) {
+ jmethodID m = env->GetStaticMethodID(test, name, "()V");
+ env->CallStaticVoidMethod(test, m);
+}
+
+static void ClearAndPrintException(JNIEnv* env, jclass test) {
+ jthrowable e = env->ExceptionOccurred();
+ env->ExceptionClear();
+ jmethodID m = env->GetStaticMethodID(test, "printException", "(Ljava/lang/Throwable;)V");
+ env->CallStaticVoidMethod(test, m, e);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_terminal_1N(JNIEnv* env, jclass) {
+ ThrowNative(env);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N(JNIEnv* env, jclass test) {
+ ThrowNative(env);
+ ClearAndPrintException(env, test);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N_1J(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "terminal_J");
+ ClearAndPrintException(env, test);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N_1N(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "terminal_N");
+ ClearAndPrintException(env, test);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_intermediate_1N_1J(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "terminal_J");
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_intermediate_1N_1N(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "terminal_N");
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N_1J_1J(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "intermediate_J_J");
+ ClearAndPrintException(env, test);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N_1J_1N(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "intermediate_J_N");
+ ClearAndPrintException(env, test);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N_1N_1J(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "intermediate_N_J");
+ ClearAndPrintException(env, test);
+}
+
+extern "C" JNIEXPORT void JNICALL Java_art_Test1927_test_1N_1N_1N(JNIEnv* env, jclass test) {
+ CallMethod(env, test, "intermediate_N_N");
+ ClearAndPrintException(env, test);
+}
+
+} // namespace Test1927ExceptionEvent
+} // namespace art
diff --git a/test/1927-exception-event/expected.txt b/test/1927-exception-event/expected.txt
new file mode 100644
index 0000000..be8f39c
--- /dev/null
+++ b/test/1927-exception-event/expected.txt
@@ -0,0 +1,278 @@
+class art.Test1927$TestException
+Running test_J
+main: public static void art.Test1927.test_J() @ line = 110 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.test_J() @ line = 110
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 239
+ Will be caught by: public static void art.Test1927.test_J() @ line = 111
+main: public static void art.Test1927.test_J() @ line = 111 caught class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J() @ line = 111
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 239
+Caught exception: art.Test1927$TestException: from java
+Running test_N()
+Caught exception: art.Test1927$TestException: from native
+Running test_J_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static void art.Test1927.test_J_J() @ line = 121
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 243
+ Will be caught by: public static void art.Test1927.test_J_J() @ line = 122
+main: public static void art.Test1927.test_J_J() @ line = 122 caught class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J_J() @ line = 122
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 243
+Caught exception: art.Test1927$TestException: from java
+Running test_J_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static void art.Test1927.test_J_N() @ line = 129
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 245
+ Will be caught by: public static void art.Test1927.test_J_N() @ line = 130
+main: public static void art.Test1927.test_J_N() @ line = 130 caught class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J_N() @ line = 130
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 245
+Caught exception: art.Test1927$TestException: from native
+Running test_N_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static native void art.Test1927.test_N_J() @ line = -1
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 247
+ Will be caught by: <UNKNOWN>
+Caught exception: art.Test1927$TestException: from java
+Running test_N_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static native void art.Test1927.test_N_N() @ line = -1
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 249
+ Will be caught by: <UNKNOWN>
+Caught exception: art.Test1927$TestException: from native
+Running test_J_J_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static void art.Test1927.intermediate_J_J() @ line = 138
+ public static void art.Test1927.test_J_J_J() @ line = 145
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 251
+ Will be caught by: public static void art.Test1927.test_J_J_J() @ line = 146
+main: public static void art.Test1927.test_J_J_J() @ line = 146 caught class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J_J_J() @ line = 146
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 251
+Caught exception: art.Test1927$TestException: from java
+Running test_J_J_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static void art.Test1927.intermediate_J_N() @ line = 139
+ public static void art.Test1927.test_J_J_N() @ line = 153
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 253
+ Will be caught by: public static void art.Test1927.test_J_J_N() @ line = 154
+main: public static void art.Test1927.test_J_J_N() @ line = 154 caught class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J_J_N() @ line = 154
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 253
+Caught exception: art.Test1927$TestException: from native
+Running test_J_N_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static native void art.Test1927.intermediate_N_J() @ line = -1
+ public static void art.Test1927.test_J_N_J() @ line = 161
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 255
+ Will be caught by: public static void art.Test1927.test_J_N_J() @ line = 162
+main: public static void art.Test1927.test_J_N_J() @ line = 162 caught class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J_N_J() @ line = 162
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 255
+Caught exception: art.Test1927$TestException: from java
+Running test_J_N_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static native void art.Test1927.intermediate_N_N() @ line = -1
+ public static void art.Test1927.test_J_N_N() @ line = 169
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 257
+ Will be caught by: public static void art.Test1927.test_J_N_N() @ line = 170
+main: public static void art.Test1927.test_J_N_N() @ line = 170 caught class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionCatchEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable) @ line = 43
+ public static void art.Test1927.test_J_N_N() @ line = 170
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 257
+Caught exception: art.Test1927$TestException: from native
+Running test_N_J_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static void art.Test1927.intermediate_J_J() @ line = 138
+ public static native void art.Test1927.test_N_J_J() @ line = -1
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 259
+ Will be caught by: <UNKNOWN>
+Caught exception: art.Test1927$TestException: from java
+Running test_N_J_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static void art.Test1927.intermediate_J_N() @ line = 139
+ public static native void art.Test1927.test_N_J_N() @ line = -1
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 261
+ Will be caught by: <UNKNOWN>
+Caught exception: art.Test1927$TestException: from native
+Running test_N_N_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static native void art.Test1927.intermediate_N_J() @ line = -1
+ public static native void art.Test1927.test_N_N_J() @ line = -1
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 263
+ Will be caught by: <UNKNOWN>
+Caught exception: art.Test1927$TestException: from java
+Running test_N_N_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static native void art.Test1927.intermediate_N_N() @ line = -1
+ public static native void art.Test1927.test_N_N_N() @ line = -1
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 265
+ Will be caught by: <UNKNOWN>
+Caught exception: art.Test1927$TestException: from native
+Running test_extra_N_J_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static void art.Test1927.intermediate_J_J() @ line = 138
+ public static native void art.Test1927.test_N_J_J() @ line = -1
+ public static void art.Test1927.test_extra_N_J_J() @ line = 182
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 267
+ Will be caught by: public static void art.Test1927.test_extra_N_J_J() @ line = 183
+Caught exception: art.Test1927$TestException: from java
+Running test_extra_N_J_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static void art.Test1927.intermediate_J_N() @ line = 139
+ public static native void art.Test1927.test_N_J_N() @ line = -1
+ public static void art.Test1927.test_extra_N_J_N() @ line = 189
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 269
+ Will be caught by: public static void art.Test1927.test_extra_N_J_N() @ line = 190
+Caught exception: art.Test1927$TestException: from native
+Running test_extra_N_N_J()
+main: public static void art.Test1927.terminal_J() @ line = 103 throws class art.Test1927$TestException: from java
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static void art.Test1927.terminal_J() @ line = 103
+ public static native void art.Test1927.intermediate_N_J() @ line = -1
+ public static native void art.Test1927.test_N_N_J() @ line = -1
+ public static void art.Test1927.test_extra_N_N_J() @ line = 196
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 271
+ Will be caught by: public static void art.Test1927.test_extra_N_N_J() @ line = 197
+Caught exception: art.Test1927$TestException: from java
+Running test_extra_N_N_N()
+main: public static native void art.Test1927.terminal_N() @ line = -1 throws class art.Test1927$TestException: from native
+ 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.Test1927.PrintStack() @ line = 28
+ public static void art.Test1927.ExceptionEvent(java.lang.Thread,java.lang.reflect.Executable,long,java.lang.Throwable,java.lang.reflect.Executable,long) @ line = 66
+ public static native void art.Test1927.terminal_N() @ line = -1
+ public static native void art.Test1927.intermediate_N_N() @ line = -1
+ public static native void art.Test1927.test_N_N_N() @ line = -1
+ public static void art.Test1927.test_extra_N_N_N() @ line = 203
+ public static void art.Test1927.run() throws java.lang.Exception @ line = 273
+ Will be caught by: public static void art.Test1927.test_extra_N_N_N() @ line = 204
+Caught exception: art.Test1927$TestException: from native
diff --git a/test/1927-exception-event/info.txt b/test/1927-exception-event/info.txt
new file mode 100644
index 0000000..a74167f
--- /dev/null
+++ b/test/1927-exception-event/info.txt
@@ -0,0 +1,3 @@
+Test basic JVMTI exception event functionality
+
+Ensures that we can receive exception and exception catch events from JVMTI.
diff --git a/test/1927-exception-event/run b/test/1927-exception-event/run
new file mode 100755
index 0000000..51875a7
--- /dev/null
+++ b/test/1927-exception-event/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/1927-exception-event/src/Main.java b/test/1927-exception-event/src/Main.java
new file mode 100644
index 0000000..5b9b31b
--- /dev/null
+++ b/test/1927-exception-event/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.Test1927.run();
+ }
+}
diff --git a/test/1927-exception-event/src/art/Breakpoint.java b/test/1927-exception-event/src/art/Breakpoint.java
new file mode 100644
index 0000000..bbb89f7
--- /dev/null
+++ b/test/1927-exception-event/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/1927-exception-event/src/art/Exceptions.java b/test/1927-exception-event/src/art/Exceptions.java
new file mode 100644
index 0000000..2c959ec
--- /dev/null
+++ b/test/1927-exception-event/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/1927-exception-event/src/art/StackTrace.java b/test/1927-exception-event/src/art/StackTrace.java
new file mode 100644
index 0000000..b12c3df
--- /dev/null
+++ b/test/1927-exception-event/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/1927-exception-event/src/art/Suspension.java b/test/1927-exception-event/src/art/Suspension.java
new file mode 100644
index 0000000..16e62cc
--- /dev/null
+++ b/test/1927-exception-event/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/1927-exception-event/src/art/Test1927.java b/test/1927-exception-event/src/art/Test1927.java
new file mode 100644
index 0000000..c2d13bb
--- /dev/null
+++ b/test/1927-exception-event/src/art/Test1927.java
@@ -0,0 +1,277 @@
+/*
+ * 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.Objects;
+import java.lang.reflect.Executable;
+import java.lang.reflect.Method;
+
+public class Test1927 {
+ private static boolean PRINT_FULL_EXCEPTION = false;
+ private static void PrintStack() {
+ System.out.println("\tCurrent Stack:");
+ for (StackTrace.StackFrameData e : StackTrace.GetStackTrace(Thread.currentThread())) {
+ if (Objects.equals(e.method.getDeclaringClass().getPackage(), Test1927.class.getPackage())) {
+ System.out.println("\t\t" + e.method + " @ line = " +
+ Breakpoint.locationToLine(e.method, e.current_location));
+ }
+ }
+ }
+
+ public static void ExceptionCatchEvent(Thread thr,
+ Executable catch_method,
+ long catch_location,
+ Throwable exception) {
+ System.out.println(thr.getName() + ": " + catch_method + " @ line = " +
+ Breakpoint.locationToLine(catch_method, catch_location) + " caught " +
+ exception.getClass() + ": " + exception.getMessage());
+ PrintStack();
+ if (PRINT_FULL_EXCEPTION) {
+ System.out.print("exception is: ");
+ exception.printStackTrace(System.out);
+ }
+ }
+
+ public static void ExceptionEvent(Thread thr,
+ Executable throw_method,
+ long throw_location,
+ Throwable exception,
+ Executable catch_method,
+ long catch_location) {
+ System.out.println(thr.getName() + ": " + throw_method + " @ line = " +
+ Breakpoint.locationToLine(throw_method, throw_location) + " throws " +
+ exception.getClass() + ": " + exception.getMessage());
+ String catch_message;
+ if (catch_method == null) {
+ catch_message = "<UNKNOWN>";
+ } else {
+ catch_message = catch_method.toString() + " @ line = " +
+ Breakpoint.locationToLine(catch_method, catch_location);
+ }
+ PrintStack();
+ System.out.println("\tWill be caught by: " + catch_message);
+ if (PRINT_FULL_EXCEPTION) {
+ System.out.print("exception is: ");
+ exception.printStackTrace(System.out);
+ }
+ }
+
+ public static class TestException extends Error {
+ public TestException(String s) { super(s); }
+ public TestException() { super("from java"); }
+ }
+
+ // Possibilities
+ // ( -> is a JNI/Java call.)
+ // Furthest left catches/clears the exception
+ // Furthest right throws it.
+ // J
+ // N
+ // J -> J
+ // J -> N
+ // N -> J
+ // N -> N
+ // J -> J -> J
+ // J -> J -> N
+ // J -> N -> J
+ // J -> N -> N
+ // N -> J -> J
+ // N -> J -> N
+ // N -> N -> J
+ // N -> N -> N
+ // extra -> N -> J -> J
+ // extra -> N -> J -> N
+ // extra -> N -> N -> J
+ // extra -> N -> N -> N
+
+ public static void terminal_J() {
+ throw new TestException();
+ }
+
+ public static native void terminal_N();
+
+ public static void test_J() {
+ try {
+ throw new TestException();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ // Do test_J but native
+ public static native void test_N();
+
+ public static void test_J_J() {
+ try {
+ terminal_J();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static void test_J_N() {
+ try {
+ terminal_N();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static native void test_N_J();
+ public static native void test_N_N();
+
+ public static void intermediate_J_J() { terminal_J(); }
+ public static void intermediate_J_N() { terminal_N(); }
+ public static native void intermediate_N_J();
+ public static native void intermediate_N_N();
+
+ public static void test_J_J_J() {
+ try {
+ intermediate_J_J();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static void test_J_J_N() {
+ try {
+ intermediate_J_N();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static void test_J_N_J() {
+ try {
+ intermediate_N_J();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static void test_J_N_N() {
+ try {
+ intermediate_N_N();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static native void test_N_J_J();
+ public static native void test_N_J_N();
+ public static native void test_N_N_J();
+ public static native void test_N_N_N();
+
+ public static void test_extra_N_J_J() {
+ try {
+ test_N_J_J();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+ public static void test_extra_N_J_N() {
+ try {
+ test_N_J_N();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+ public static void test_extra_N_N_J() {
+ try {
+ test_N_N_J();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+ public static void test_extra_N_N_N() {
+ try {
+ test_N_N_N();
+ } catch (TestException e) {
+ printException(e);
+ }
+ }
+
+ public static void printException(Throwable e) {
+ System.out.println("Caught exception: " + e);
+ if (PRINT_FULL_EXCEPTION) {
+ e.printStackTrace(System.out);
+ }
+ }
+
+ public static void run() throws Exception {
+ // Make sure classes are loaded first.
+ System.out.println(TestException.class.toString());
+ Exceptions.setupExceptionTracing(
+ Test1927.class,
+ TestException.class,
+ Test1927.class.getDeclaredMethod(
+ "ExceptionEvent",
+ Thread.class,
+ Executable.class,
+ Long.TYPE,
+ Throwable.class,
+ Executable.class,
+ Long.TYPE),
+ Test1927.class.getDeclaredMethod(
+ "ExceptionCatchEvent",
+ Thread.class,
+ Executable.class,
+ Long.TYPE,
+ Throwable.class));
+ Exceptions.enableExceptionEvent(Thread.currentThread());
+ Exceptions.enableExceptionCatchEvent(Thread.currentThread());
+ System.out.println("Running test_J");
+ test_J();
+ System.out.println("Running test_N()");
+ test_N();
+ System.out.println("Running test_J_J()");
+ test_J_J();
+ System.out.println("Running test_J_N()");
+ test_J_N();
+ System.out.println("Running test_N_J()");
+ test_N_J();
+ System.out.println("Running test_N_N()");
+ test_N_N();
+ System.out.println("Running test_J_J_J()");
+ test_J_J_J();
+ System.out.println("Running test_J_J_N()");
+ test_J_J_N();
+ System.out.println("Running test_J_N_J()");
+ test_J_N_J();
+ System.out.println("Running test_J_N_N()");
+ test_J_N_N();
+ System.out.println("Running test_N_J_J()");
+ test_N_J_J();
+ System.out.println("Running test_N_J_N()");
+ test_N_J_N();
+ System.out.println("Running test_N_N_J()");
+ test_N_N_J();
+ System.out.println("Running test_N_N_N()");
+ test_N_N_N();
+ System.out.println("Running test_extra_N_J_J()");
+ test_extra_N_J_J();
+ System.out.println("Running test_extra_N_J_N()");
+ test_extra_N_J_N();
+ System.out.println("Running test_extra_N_N_J()");
+ test_extra_N_N_J();
+ System.out.println("Running test_extra_N_N_N()");
+ test_extra_N_N_N();
+ Exceptions.disableExceptionCatchEvent(Thread.currentThread());
+ Exceptions.disableExceptionEvent(Thread.currentThread());
+ }
+}