2323
2424#include < jvmti.h>
2525
26- #include < string.h>
26+ #include < cstring>
27+ #include < cstdlib>
2728
2829static jclass MAIN_CLS;
2930static jmethodID TARGET_ID;
31+ static jclass EXCEPTION_CLS;
3032
3133static const char * TARGET_CLASS_NAME = " TestSharedCloseJvmti$EventDuringScopedAccessRunner" ;
3234static const char * TARGET_METHOD_NAME = " target" ;
@@ -35,6 +37,8 @@ static const char* TARGET_METHOD_SIG = "()V";
3537static const char * INTERCEPT_CLASS_NAME = " Ljdk/internal/foreign/MemorySessionImpl;" ;
3638static const char * INTERCEPT_METHOD_NAME = " checkValidStateRaw" ;
3739
40+ static const char * EXCEPTION_CLASS_NAME = " Ljdk/internal/misc/ScopedMemoryAccess$ScopedAccessError;" ;
41+
3842void start (jvmtiEnv*, JNIEnv* jni_env, jthread) {
3943
4044 jclass cls = jni_env->FindClass (TARGET_CLASS_NAME);
@@ -50,6 +54,14 @@ void start(jvmtiEnv*, JNIEnv* jni_env, jthread) {
5054 jni_env->ExceptionDescribe ();
5155 return ;
5256 }
57+
58+ jclass ex_cls = jni_env->FindClass (EXCEPTION_CLASS_NAME);
59+ if (ex_cls == nullptr ) {
60+ jni_env->ExceptionDescribe ();
61+ return ;
62+ }
63+
64+ EXCEPTION_CLS = (jclass) jni_env->NewGlobalRef (ex_cls);
5365}
5466
5567void 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
6072 return ;
6173 }
6274
63- if (strcmp (method_name, INTERCEPT_METHOD_NAME) != 0 ) {
64- jvmti_env->Deallocate ((unsigned char *) method_name);
75+ bool is_intercept_method = strcmp (method_name, INTERCEPT_METHOD_NAME) == 0 ;
76+ jvmti_env->Deallocate ((unsigned char *) method_name);
77+ if (!is_intercept_method) {
6578 return ;
6679 }
6780
6881 jclass cls;
6982 err = jvmti_env->GetMethodDeclaringClass (method, &cls);
7083 if (err != JVMTI_ERROR_NONE) {
71- jvmti_env->Deallocate ((unsigned char *) method_name);
7284 return ;
7385 }
7486
7587 char * class_sig = nullptr ;
7688 err = jvmti_env->GetClassSignature (cls, &class_sig, nullptr );
7789 if (err != JVMTI_ERROR_NONE) {
78- jvmti_env->Deallocate ((unsigned char *) method_name);
7990 return ;
8091 }
8192
82- if ( strcmp (class_sig, INTERCEPT_CLASS_NAME) != 0 ) {
83- jvmti_env->Deallocate ((unsigned char *) method_name );
84- jvmti_env-> Deallocate (( unsigned char *) class_sig);
93+ bool is_intercept_class = strcmp (class_sig, INTERCEPT_CLASS_NAME) == 0 ;
94+ jvmti_env->Deallocate ((unsigned char *) class_sig );
95+ if (!is_intercept_class) {
8596 return ;
8697 }
8798
8899 jni_env->CallStaticVoidMethod (MAIN_CLS, TARGET_ID);
89- if (jni_env->ExceptionOccurred ()) {
100+ jthrowable ex = jni_env->ExceptionOccurred ();
101+ if (ex != nullptr ) {
102+ // we can not return with a pending exception from this JMVTI callback,
103+ // and there is no way to propagate it to the caller so that the memory
104+ // access will be interrupted.
105+ // We log the exception for testing purposes end then terminate the process.
90106 jni_env->ExceptionDescribe ();
107+ if (jni_env->IsInstanceOf (ex, EXCEPTION_CLS)) {
108+ exit (0 ); // success
109+ }
110+ // else, another exception was thrown. Let the java logic handle the lack of
111+ // ScopedAccessError
91112 }
92-
93- jvmti_env->Deallocate ((unsigned char *) method_name);
94- jvmti_env->Deallocate ((unsigned char *) class_sig);
95113}
96114
97115JNIEXPORT jint JNICALL
0 commit comments