8218401: WRONG_PHASE: vmTestbase/nsk/jvmti test crash
Reviewed-by: sspitsyn, jcbeyler
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp Thu Mar 21 12:28:58 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/Breakpoint/breakpoint001/breakpoint001.cpp Thu Mar 21 19:56:31 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -52,7 +52,7 @@
static jvmtiEnv *jvmti = NULL;
static jvmtiEventCallbacks callbacks;
-static int vm_started = 0;
+static volatile int callbacksEnabled = NSK_TRUE;
static jrawMonitorID agent_lock;
static void initCounters() {
@@ -82,7 +82,7 @@
jvmti->RawMonitorEnter(agent_lock);
- if (vm_started) {
+ if (callbacksEnabled) {
// GetClassSignature may be called only during the start or the live phase
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic)))
env->FatalError("failed to obtain a class signature\n");
@@ -196,11 +196,20 @@
VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
jvmti->RawMonitorEnter(agent_lock);
- vm_started = 1;
+ callbacksEnabled = NSK_TRUE;
jvmti->RawMonitorExit(agent_lock);
}
+
+void JNICALL
+VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
/************************/
JNIEXPORT jint JNICALL
@@ -268,6 +277,8 @@
callbacks.ClassLoad = &ClassLoad;
callbacks.Breakpoint = &Breakpoint;
callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
+
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))
return JNI_ERR;
@@ -275,6 +286,8 @@
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FramePop/framepop002/framepop002.cpp Thu Mar 21 12:28:58 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/FramePop/framepop002/framepop002.cpp Thu Mar 21 19:56:31 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -62,6 +62,9 @@
static int max_depth = 0;
static thr threads[MAX_THREADS];
+static volatile int callbacksEnabled = NSK_FALSE;
+static jrawMonitorID agent_lock;
+
static
int isTestThread(jvmtiEnv *jvmti_env, jthread thr) {
jvmtiError err;
@@ -211,12 +214,20 @@
if (watch_events == JNI_FALSE) return;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
err = jvmti_env->GetFrameCount(thr, &frameCount);
if (err != JVMTI_ERROR_NONE) {
printf("(GetFrameCount#entry) unexpected error: %s (%d)\n",
TranslateError(err), err);
printInfo(jvmti_env, thr, method, frameCount);
result = STATUS_FAILED;
+ jvmti->RawMonitorExit(agent_lock);
return;
}
@@ -259,6 +270,25 @@
}
}
}
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+void JNICALL VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_TRUE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+
+void JNICALL VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
+
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL FramePop(jvmtiEnv *jvmti_env, JNIEnv *env,
@@ -266,12 +296,19 @@
jvmtiError err;
jint frameCount;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
err = jvmti_env->GetFrameCount(thr, &frameCount);
if (err != JVMTI_ERROR_NONE) {
printf("(GetFrameCount#entry) unexpected error: %s (%d)\n",
TranslateError(err), err);
printInfo(jvmti_env, thr, method, frameCount);
result = STATUS_FAILED;
+ jvmti->RawMonitorExit(agent_lock);
return;
}
@@ -296,6 +333,8 @@
result = STATUS_FAILED;
}
}
+
+ jvmti->RawMonitorExit(agent_lock);
}
#ifdef STATIC_BUILD
@@ -355,12 +394,24 @@
caps.can_generate_method_entry_events) {
callbacks.MethodEntry = &MethodEntry;
callbacks.FramePop = &FramePop;
+ callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
+
err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
if (err != JVMTI_ERROR_NONE) {
printf("(SetEventCallbacks) unexpected error: %s (%d)\n",
TranslateError(err), err);
return JNI_ERR;
}
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
+ return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
+
+ if (jvmti->CreateRawMonitor("agent_lock", &agent_lock) != JVMTI_ERROR_NONE) {
+ return JNI_ERR;
+ }
+
} else {
printf("Warning: FramePop or MethodEntry event is not implemented\n");
}
--- a/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp Thu Mar 21 12:28:58 2019 -0700
+++ b/test/hotspot/jtreg/vmTestbase/nsk/jvmti/SingleStep/singlestep003/singlestep003.cpp Thu Mar 21 19:56:31 2019 +0000
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2003, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2003, 2019, 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
@@ -61,6 +61,9 @@
static jvmtiEnv *jvmti = NULL;
static jvmtiEventCallbacks callbacks;
+static volatile int callbacksEnabled = NSK_FALSE;
+static jrawMonitorID agent_lock;
+
static void setBP(jvmtiEnv *jvmti_env, JNIEnv *env, jclass klass) {
jmethodID mid;
@@ -76,6 +79,13 @@
ClassLoad(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread, jclass klass) {
char *sig, *generic;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
if (!NSK_JVMTI_VERIFY(jvmti_env->GetClassSignature(klass, &sig, &generic)))
env->FatalError("failed to obtain a class signature\n");
@@ -86,6 +96,27 @@
sig);
setBP(jvmti_env, env, klass);
}
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+void JNICALL
+VMStart(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_TRUE;
+
+ jvmti->RawMonitorExit(agent_lock);
+}
+
+
+void JNICALL
+VMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env) {
+ jvmti->RawMonitorEnter(agent_lock);
+
+ callbacksEnabled = NSK_FALSE;
+
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL
@@ -94,6 +125,13 @@
jclass klass;
char *sig, *generic;
+ jvmti->RawMonitorEnter(agent_lock);
+
+ if (!callbacksEnabled) {
+ jvmti->RawMonitorExit(agent_lock);
+ return;
+ }
+
NSK_DISPLAY0("Breakpoint event received\n");
if (!NSK_JVMTI_VERIFY(jvmti_env->GetMethodDeclaringClass(method, &klass)))
NSK_COMPLAIN0("TEST FAILURE: unable to get method declaring class\n\n");
@@ -113,6 +151,8 @@
NSK_COMPLAIN1("TEST FAILURE: unexpected breakpoint event in method of class \"%s\"\n\n",
sig);
}
+
+ jvmti->RawMonitorExit(agent_lock);
}
void JNICALL
@@ -276,16 +316,27 @@
callbacks.ClassLoad = &ClassLoad;
callbacks.Breakpoint = &Breakpoint;
callbacks.SingleStep = &SingleStep;
+ callbacks.VMStart = &VMStart;
+ callbacks.VMDeath = &VMDeath;
+
if (!NSK_JVMTI_VERIFY(jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks))))
return JNI_ERR;
NSK_DISPLAY0("setting event callbacks done\nenabling JVMTI events ...\n");
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL)))
+ return JNI_ERR;
+ if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL)))
+ return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_CLASS_LOAD, NULL)))
return JNI_ERR;
if (!NSK_JVMTI_VERIFY(jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_BREAKPOINT, NULL)))
return JNI_ERR;
NSK_DISPLAY0("enabling the events done\n\n");
+ if (jvmti->CreateRawMonitor("agent_lock", &agent_lock) != JVMTI_ERROR_NONE) {
+ return JNI_ERR;
+ }
+
return JNI_OK;
}