diff --git a/test/jdk/java/foreign/sharedclosejvmti/TestSharedCloseJvmti.java b/test/jdk/java/foreign/sharedclosejvmti/TestSharedCloseJvmti.java index b2bfdd18b50b3..9fba092744e8d 100644 --- a/test/jdk/java/foreign/sharedclosejvmti/TestSharedCloseJvmti.java +++ b/test/jdk/java/foreign/sharedclosejvmti/TestSharedCloseJvmti.java @@ -81,7 +81,9 @@ public static void main(String[] args) throws Throwable { // run in separate thread so that waiting on // latch doesn't block main thread Thread.ofPlatform().name("Trigger").start(() -> { - SINK = segment.get(ValueLayout.JAVA_INT, 0); + SINK = segment.get(ValueLayout.JAVA_INT, 0); // should throw + System.err.println("No exception thrown during outer memory access"); + System.exit(1); }); // wait until trigger thread is in JVMTI event callback MAIN_LATCH.await(); @@ -107,7 +109,9 @@ private static void target() { } else { reentrant = true; try (Arena arena = Arena.ofConfined()) { - SINK = arena.allocate(4).get(ValueLayout.JAVA_INT, 0); + SINK = arena.allocate(4).get(ValueLayout.JAVA_INT, 0); // should throw + System.err.println("No exception thrown during reentrant memory access"); + System.exit(1); } reentrant = false; } diff --git a/test/jdk/java/foreign/sharedclosejvmti/libSharedCloseAgent.cpp b/test/jdk/java/foreign/sharedclosejvmti/libSharedCloseAgent.cpp index a82818e028049..97c10be3d3d58 100644 --- a/test/jdk/java/foreign/sharedclosejvmti/libSharedCloseAgent.cpp +++ b/test/jdk/java/foreign/sharedclosejvmti/libSharedCloseAgent.cpp @@ -23,10 +23,12 @@ #include -#include +#include +#include static jclass MAIN_CLS; static jmethodID TARGET_ID; +static jclass EXCEPTION_CLS; static const char* TARGET_CLASS_NAME = "TestSharedCloseJvmti$EventDuringScopedAccessRunner"; static const char* TARGET_METHOD_NAME = "target"; @@ -35,6 +37,8 @@ static const char* TARGET_METHOD_SIG = "()V"; static const char* INTERCEPT_CLASS_NAME = "Ljdk/internal/foreign/MemorySessionImpl;"; static const char* INTERCEPT_METHOD_NAME = "checkValidStateRaw"; +static const char* EXCEPTION_CLASS_NAME = "Ljdk/internal/misc/ScopedMemoryAccess$ScopedAccessError;"; + void start(jvmtiEnv*, JNIEnv* jni_env, jthread) { jclass cls = jni_env->FindClass(TARGET_CLASS_NAME); @@ -50,6 +54,14 @@ void start(jvmtiEnv*, JNIEnv* jni_env, jthread) { jni_env->ExceptionDescribe(); return; } + + jclass ex_cls = jni_env->FindClass(EXCEPTION_CLASS_NAME); + if (ex_cls == nullptr) { + jni_env->ExceptionDescribe(); + return; + } + + EXCEPTION_CLS = (jclass) jni_env->NewGlobalRef(ex_cls); } void method_exit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jmethodID method, @@ -60,38 +72,44 @@ void method_exit(jvmtiEnv *jvmti_env, JNIEnv* jni_env, jthread thread, jmethodID return; } - if (strcmp(method_name, INTERCEPT_METHOD_NAME) != 0) { - jvmti_env->Deallocate((unsigned char*) method_name); + bool is_intercept_method = strcmp(method_name, INTERCEPT_METHOD_NAME) == 0; + jvmti_env->Deallocate((unsigned char*) method_name); + if (!is_intercept_method) { return; } jclass cls; err = jvmti_env->GetMethodDeclaringClass(method, &cls); if (err != JVMTI_ERROR_NONE) { - jvmti_env->Deallocate((unsigned char*) method_name); return; } char* class_sig = nullptr; err = jvmti_env->GetClassSignature(cls, &class_sig, nullptr); if (err != JVMTI_ERROR_NONE) { - jvmti_env->Deallocate((unsigned char*) method_name); return; } - if (strcmp(class_sig, INTERCEPT_CLASS_NAME) != 0) { - jvmti_env->Deallocate((unsigned char*) method_name); - jvmti_env->Deallocate((unsigned char*) class_sig); + bool is_intercept_class = strcmp(class_sig, INTERCEPT_CLASS_NAME) == 0; + jvmti_env->Deallocate((unsigned char*) class_sig); + if (!is_intercept_class) { return; } jni_env->CallStaticVoidMethod(MAIN_CLS, TARGET_ID); - if (jni_env->ExceptionOccurred()) { + jthrowable ex = jni_env->ExceptionOccurred(); + if (ex != nullptr) { + // we can not return with a pending exception from this JMVTI callback, + // and there is no way to propagate it to the caller so that the memory + // access will be interrupted. + // We log the exception for testing purposes end then terminate the process. jni_env->ExceptionDescribe(); + if (jni_env->IsInstanceOf(ex, EXCEPTION_CLS)) { + exit(0); // success + } + // else, another exception was thrown. Let the java logic handle the lack of + // ScopedAccessError } - - jvmti_env->Deallocate((unsigned char*) method_name); - jvmti_env->Deallocate((unsigned char*) class_sig); } JNIEXPORT jint JNICALL