8279358: vmTestbase/nsk/jvmti/scenarios/jni_interception/JI03/ji03t003/TestDescription.java fails with usage tracker

Reviewed-by: cjplummer, lmesnik
This commit is contained in:
Alex Menkov 2022-06-07 20:32:46 +00:00
parent 1aa87e0078
commit b12e7f1bf9
10 changed files with 169 additions and 78 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -44,6 +44,6 @@
* @library /vmTestbase
* /test/lib
* @build nsk.jvmti.RedefineClasses.redefclass031r
* @run main/othervm/native -agentlib:redefclass031 nsk.jvmti.RedefineClasses.redefclass031
* @run main/othervm/native -agentlib:redefclass031 nsk.jvmti.RedefineClasses.redefclass031 -v
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,12 +39,26 @@ static jvmtiEventCallbacks callbacks;
static int watch_ev = 0; /* ignore JVMTI events by default */
static int gen_ev = 0; /* number of generated events */
static int result = PASSED; /* total result of the test */
static jthread test_thread = NULL;
static jrawMonitorID watch_ev_monitor;
static void set_watch_ev(int value) {
static void set_watch_ev(JNIEnv *env, int value) {
jvmti->RawMonitorEnter(watch_ev_monitor);
if (value) {
jvmtiError err = jvmti->GetCurrentThread(&test_thread);
if (err != JVMTI_ERROR_NONE) {
printf("Failed to get current thread: %s (%d)\n", TranslateError(err), err);
result = STATUS_FAILED;
} else {
test_thread = env->NewGlobalRef(test_thread);
}
} else if (test_thread != NULL) {
env->DeleteGlobalRef(test_thread);
test_thread = NULL;
}
watch_ev = value;
jvmti->RawMonitorExit(watch_ev_monitor);
@ -54,9 +68,31 @@ void JNICALL
NativeMethodBind(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thr, jmethodID methodID, void * pAddress, void ** pNewAddress) {
jvmti->RawMonitorEnter(watch_ev_monitor);
if (watch_ev && isThreadExpected(jvmti_env, thr)) {
printf("#### JVMTI_EVENT_NATIVE_METHOD_BIND occured ####\n");
gen_ev++;
if (watch_ev) {
// we are interested only in events on the test thread and VMThread.
// In case of VMThread we most likely get crash (VMThread is not a Java Thread),
// but lets check GetThreadInfo - it returns error for non-Java threads.
if (env->IsSameObject(test_thread, thr)) {
printf("#### JVMTI_EVENT_NATIVE_METHOD_BIND occured on test thread ####\n");
gen_ev++;
} else {
jvmtiThreadInfo inf;
jvmtiError err = jvmti_env->GetThreadInfo(thr, &inf);
if (err != JVMTI_ERROR_NONE) {
printf("#### JVMTI_EVENT_NATIVE_METHOD_BIND: Failed to get thread info: %s (%d) ####\n",
TranslateError(err), err);
result = STATUS_FAILED;
} else {
printf("got JVMTI_EVENT_NATIVE_METHOD_BIND event on thread '%s', ignoring", inf.name);
jvmti_env->Deallocate((unsigned char *)inf.name);
if (inf.thread_group != NULL) {
env->DeleteLocalRef(inf.thread_group);
}
if (inf.context_class_loader != NULL) {
env->DeleteLocalRef(inf.context_class_loader);
}
}
}
}
jvmti->RawMonitorExit(watch_ev_monitor);
@ -153,7 +189,7 @@ Java_nsk_jvmti_RedefineClasses_redefclass031_makeRedefinition(JNIEnv *env,
classDef.class_byte_count = env->GetArrayLength(classBytes);
classDef.class_bytes = (unsigned char *) env->GetByteArrayElements(classBytes, NULL);
set_watch_ev(1); /* watch JVMTI events */
set_watch_ev(env, 1); /* watch JVMTI events */
if (vrb == 1)
printf(">>>>>>>> Invoke RedefineClasses():\n\tnew class byte count=%d\n",
@ -168,7 +204,7 @@ Java_nsk_jvmti_RedefineClasses_redefclass031_makeRedefinition(JNIEnv *env,
else if (vrb == 1)
printf("Check #1 PASSED: RedefineClasses() is successfully done\n");
set_watch_ev(0); /* again ignore JVMTI events */
set_watch_ev(env, 0); /* again ignore JVMTI events */
if (gen_ev) {
printf("TEST FAILED: %d unexpected JVMTI events were generated by the function RedefineClasses()\n",

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -42,6 +42,6 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm/native -agentlib:ji01t001 nsk.jvmti.scenarios.jni_interception.JI01.ji01t001
* @run main/othervm/native -agentlib:ji01t001=-verbose nsk.jvmti.scenarios.jni_interception.JI01.ji01t001
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -45,6 +45,9 @@ static jrawMonitorID eventLock;
static jvmtiEventCallbacks callbacks;
static jint result = NSK_STATUS_PASSED;
// test thread
static jthread testThread = NULL;
/* the original JNI function table */
static jniNativeInterface *orig_jni_functions = NULL;
@ -54,10 +57,27 @@ static jniNativeInterface *redir_jni_functions = NULL;
/* number of the redirected JNI function calls */
static volatile int fnd_calls = 0;
void setTestThread(JNIEnv *env) {
jthread curThread = NULL;
NSK_JVMTI_VERIFY(jvmti->GetCurrentThread(&curThread));
testThread = env->NewGlobalRef(curThread);
}
void resetTestThread(JNIEnv *env) {
env->DeleteGlobalRef(testThread);
testThread = NULL;
}
bool isOnTestThread(JNIEnv *env) {
jthread curThread = NULL;
NSK_JVMTI_VERIFY(jvmti->GetCurrentThread(&curThread));
return env->IsSameObject(testThread, curThread);
}
/* ====================================================================== */
/** redirected JNI functions **/
jclass JNICALL MyFindClass(JNIEnv *env, const char *name) {
if (isThreadExpected(jvmti, NULL)) {
if (isOnTestThread(env) && strcmp(name, classSig) == 0) {
fnd_calls++;
NSK_DISPLAY1("MyFindClass: the function was called successfully: number of calls so far = %d\n", fnd_calls);
@ -192,6 +212,9 @@ static void checkCall(JNIEnv *env
{
jclass cls;
setTestThread(env);
fnd_calls = 0;
NSK_TRACE(
(cls = env->FindClass(classSig))
);
@ -200,9 +223,11 @@ static void checkCall(JNIEnv *env
env->ExceptionClear()
);
// The check should pass if the actual number of invocations is not less that the expected number (fnd_calls >= exFndCalls).
resetTestThread(env);
// The check should pass if the actual number of invocations is the same as the expected number (fnd_calls == exFndCalls).
// If the invocation is not expected (exFndCalls == 0), fnd_calls should be also == 0.
if ((exFndCalls > 0 && fnd_calls >= exFndCalls) || (fnd_calls == exFndCalls)) {
if (fnd_calls == exFndCalls) {
NSK_DISPLAY5("CHECK PASSED: %s: the %s JNI function FindClass() has been %s during %s phase\n\t%d intercepted call(s) as expected\n"
, callBackFunc
, (step == 1) ? "tested" : "original"
@ -210,13 +235,6 @@ static void checkCall(JNIEnv *env
, msg
, fnd_calls
);
if (fnd_calls != exFndCalls) {
NSK_COMPLAIN2("WARNING: the number of occured calls (%d) exceeds the expected number of calls (%d).\n"
, fnd_calls
, exFndCalls
);
}
} else {
result = NSK_STATUS_FAILED;
@ -244,12 +262,10 @@ VMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread) {
);
// check JNI function table interception
fnd_calls = 0;
NSK_TRACE(doRedirect(jvmti, phase));
NSK_TRACE(checkCall(env, 1, "VMInit", TranslatePhase(phase), 1));
// check restored JNI function table
fnd_calls = 0;
NSK_TRACE(doRestore(jvmti));
NSK_TRACE(checkCall(env, 2, "VMInit", TranslatePhase(phase), 0));
@ -268,12 +284,10 @@ VMDeath(jvmtiEnv *jvmti, JNIEnv *env) {
);
// check JNI function table interception
fnd_calls = 0;
NSK_TRACE(doRedirect(jvmti, phase));
NSK_TRACE(checkCall(env, 1, "VMDeath", TranslatePhase(phase), 1));
// check restored JNI function table
fnd_calls = 0;
NSK_TRACE(doRestore(jvmti));
NSK_TRACE(checkCall(env, 2, "VMDeath", TranslatePhase(phase), 0));

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,6 +41,6 @@
*
* @library /vmTestbase
* /test/lib
* @run main/othervm/native -agentlib:ji03t003 nsk.jvmti.scenarios.jni_interception.JI03.ji03t003
* @run main/othervm/native -agentlib:ji03t003=-verbose nsk.jvmti.scenarios.jni_interception.JI03.ji03t003 -verbose
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,6 +39,8 @@ extern "C" {
static jvmtiEnv *jvmti = NULL;
static jint result = PASSED;
static int verbose = 0;
// test thread
static jthread testThread = NULL;
static const char *javaField = "exc";
static const char *excClassSig =
@ -55,14 +57,37 @@ int throw_calls = 0;
int thrownew_calls = 0;
int excoccur_calls = 0;
void setTestThread(JNIEnv *env) {
jthread curThread = NULL;
NSK_JVMTI_VERIFY(jvmti->GetCurrentThread(&curThread));
testThread = env->NewGlobalRef(curThread);
}
void resetTestThread(JNIEnv *env) {
env->DeleteGlobalRef(testThread);
testThread = NULL;
}
bool isOnTestThread(JNIEnv *env) {
jthread curThread = NULL;
NSK_JVMTI_VERIFY(jvmti->GetCurrentThread(&curThread));
return env->IsSameObject(testThread, curThread);
}
/** redirected JNI functions **/
jint JNICALL MyThrow(JNIEnv *env, jthrowable thrw) {
jint res;
throw_calls++;
if (verbose)
printf("\nMyThrow: the function called successfully: number of calls=%d\n",
throw_calls);
if (isOnTestThread(env)) {
throw_calls++;
if (verbose) {
printf("\nMyThrow: the function called successfully: number of calls=%d\n", throw_calls);
}
} else {
if (verbose) {
printf("\nMyThrow: the function called on non-test thread, ignoring\n");
}
}
res = orig_jni_functions->Throw(env, thrw);
@ -74,10 +99,16 @@ jint JNICALL MyThrow(JNIEnv *env, jthrowable thrw) {
jint JNICALL MyThrowNew(JNIEnv *env, jclass cls, const char *msg) {
jint res;
thrownew_calls++;
if (verbose)
printf("\nMyThrowNew: the function called successfully: number of calls=%d\n",
thrownew_calls);
if (isOnTestThread(env)) {
thrownew_calls++;
if (verbose) {
printf("\nMyThrowNew: the function called successfully: number of calls=%d\n", thrownew_calls);
}
} else {
if (verbose) {
printf("\nMyThrowNew: the function called on non-test thread, ignoring\n");
}
}
res = orig_jni_functions->ThrowNew(env, cls, msg);
@ -87,11 +118,15 @@ jint JNICALL MyThrowNew(JNIEnv *env, jclass cls, const char *msg) {
}
jthrowable JNICALL MyExceptionOccurred(JNIEnv *env) {
if (isThreadExpected(jvmti, NULL)) {
if (isOnTestThread(env)) {
excoccur_calls++;
if (verbose)
printf("\nMyExceptionOccurred: the function called successfully: number of calls=%d\n",
excoccur_calls);
if (verbose) {
printf("\nMyExceptionOccurred: the function called successfully: number of calls=%d\n", excoccur_calls);
}
} else {
if (verbose) {
printf("\nMyExceptionOccurred: the function called on non-test thread, ignoring\n");
}
}
return orig_jni_functions->ExceptionOccurred(env);
@ -284,6 +319,8 @@ Java_nsk_jvmti_scenarios_jni_1interception_JI03_ji03t003_check(JNIEnv *env, jobj
javaField);
thrw = env->GetObjectClass(thrwObj);
setTestThread(env);
/* 1: check the JNI function table interception */
if (verbose)
printf("\na) Checking the JNI function table interception ...\n");
@ -301,6 +338,8 @@ Java_nsk_jvmti_scenarios_jni_1interception_JI03_ji03t003_check(JNIEnv *env, jobj
env->DeleteLocalRef(thrw);
env->DeleteLocalRef(thrwObj);
resetTestThread(env);
return result;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -39,8 +39,8 @@
* @library /vmTestbase
* /test/lib
* @run main/othervm/native
* -agentlib:ma10t001=-waittime=5
* -agentlib:ma10t001a=-waittime=5
* -agentlib:ma10t001=-waittime=5,-verbose
* -agentlib:ma10t001a=-waittime=5,-verbose
* nsk.jvmti.scenarios.multienv.MA10.ma10t001
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -41,8 +41,39 @@ static jlong timeout = 0;
static int ExceptionEventsCount = 0;
static int ExceptionCatchEventsCount = 0;
// test thread
static const char *testThreadName = "Debuggee Thread";
/* ========================================================================== */
void releaseThreadInfo(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jvmtiThreadInfo *info) {
jvmti_env->Deallocate((unsigned char *)info->name);
if (info->thread_group != NULL) {
jni_env->DeleteLocalRef(info->thread_group);
}
if (info->context_class_loader != NULL) {
jni_env->DeleteLocalRef(info->context_class_loader);
}
}
static bool isTestThread(const char *msg, jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread) {
jvmtiThreadInfo inf;
jvmtiError err = jvmti_env->GetThreadInfo(thread, &inf);
if (err != JVMTI_ERROR_NONE) {
printf("%s: Failed to get thread info: %s (%d)\n", msg, TranslateError(err), err);
return false;
}
bool result = strcmp(testThreadName, inf.name) == 0;
if (!result) {
NSK_DISPLAY2("%s: event on unexpected thread %s\n", msg, inf.name);
}
releaseThreadInfo(jvmti_env, jni_env, &inf);
return result;
}
/** callback functions **/
static void JNICALL
@ -52,7 +83,7 @@ Exception(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread,
jclass klass = NULL;
char *signature = NULL;
if (!isThreadExpected(jvmti_env, thread)) {
if (!isTestThread("Exception", jvmti_env, jni_env, thread)) {
return;
}
@ -77,7 +108,7 @@ ExceptionCatch(jvmtiEnv *jvmti_env, JNIEnv *jni_env, jthread thread,
jclass klass = NULL;
char *signature = NULL;
if (!isThreadExpected(jvmti_env, thread)) {
if (!isTestThread("ExceptionCatch", jvmti_env, jni_env, thread)) {
return;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -581,33 +581,6 @@ void nsk_jvmti_agentFailed() {
agentFailed = NSK_TRUE;
}
int isThreadExpected(jvmtiEnv *jvmti, jthread thread) {
static const char *vm_jfr_buffer_thread_name = "VM JFR Buffer Thread";
static const char *jfr_request_timer_thread_name = "JFR request timer";
static const char *graal_management_bean_registration_thread_name =
"HotSpotGraalManagement Bean Registration";
static const char *graal_compiler_thread_name_prefix = "JVMCI CompilerThread";
static const size_t prefixLength = strlen(graal_compiler_thread_name_prefix);
jvmtiThreadInfo threadinfo;
NSK_JVMTI_VERIFY(jvmti->GetThreadInfo(thread, &threadinfo));
if (strcmp(threadinfo.name, vm_jfr_buffer_thread_name) == 0)
return 0;
if (strcmp(threadinfo.name, jfr_request_timer_thread_name) == 0)
return 0;
if (strcmp(threadinfo.name, graal_management_bean_registration_thread_name) == 0)
return 0;
if ((strlen(threadinfo.name) > prefixLength) &&
strncmp(threadinfo.name, graal_compiler_thread_name_prefix, prefixLength) == 0)
return 0;
return 1;
}
#define SLEEP_DELAY 10L
int suspendThreadAtMethod(jvmtiEnv *jvmti, jclass cls, jobject thread, jmethodID testMethod) {

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@ -369,8 +369,6 @@ void nsk_jvmti_getFileName(int redefineCnt, const char * dir, char * buf, size_
*/
void nsk_jvmti_agentFailed();
int isThreadExpected(jvmtiEnv *jvmti, jthread thread);
/**
* This method makes the thread to be suspended at the right place when the top frame
* belongs to the test rather than to incidental Java code (classloading, JVMCI, etc).