Skip to content

Commit

Permalink
8289612: Change hotspot/jtreg tests to not use Thread.stop
Browse files Browse the repository at this point in the history
Reviewed-by: dholmes, dcubed
  • Loading branch information
lmesnik committed Jul 18, 2022
1 parent b65f7ec commit 5a96a5d
Show file tree
Hide file tree
Showing 7 changed files with 140 additions and 48 deletions.
Expand Up @@ -25,11 +25,13 @@
* @test
* @bug 8283044
* @summary Stress delivery of asynchronous exceptions while target is at monitorenter
* @build AsyncExceptionOnMonitorEnter
* @library /test/hotspot/jtreg/testlibrary
* @run main/othervm AsyncExceptionOnMonitorEnter 0
* @run main/othervm/native -agentlib:AsyncExceptionOnMonitorEnter AsyncExceptionOnMonitorEnter 1
*/

import jvmti.JVMTIUtils;

import java.util.concurrent.Semaphore;

public class AsyncExceptionOnMonitorEnter extends Thread {
Expand Down Expand Up @@ -142,11 +144,11 @@ public static void main(String[] args) {
Thread.sleep(300);

while (true) {
worker2.stop();
JVMTIUtils.stopThread(worker2);
if (TEST_MODE != 1) {
// Don't stop() worker1 with JVMTI raw monitors since if the monitor is
// not released worker2 will deadlock on enter
worker1.stop();
JVMTIUtils.stopThread(worker1);
}

if (!worker1.isAlive() && !worker2.isAlive()) {
Expand Down Expand Up @@ -197,4 +199,3 @@ public static void usage() {
System.exit(1);
}
}

22 changes: 13 additions & 9 deletions test/hotspot/jtreg/runtime/Thread/AsyncExceptionTest.java
Expand Up @@ -26,15 +26,16 @@
* @bug 8283044
* @requires vm.compiler1.enabled | vm.compiler2.enabled
* @summary Stress delivery of asynchronous exceptions.
* @library /test/lib /test/hotspot/jtreg
* @build AsyncExceptionTest
* @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -Xcomp
* @library /test/hotspot/jtreg/testlibrary
* @run main/othervm -Xcomp
-XX:CompileCommand=dontinline,AsyncExceptionTest::internalRun2
-XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun1
-XX:CompileCommand=compileonly,AsyncExceptionTest::internalRun2
AsyncExceptionTest
*/

import jvmti.JVMTIUtils;

import java.util.concurrent.CountDownLatch;

public class AsyncExceptionTest extends Thread {
Expand All @@ -53,13 +54,17 @@ public void run() {
try {
internalRun1();
} catch (ThreadDeath td) {
throw new RuntimeException("Catched ThreadDeath in run() instead of internalRun2() or internalRun1(). receivedThreadDeathinInternal1=" + receivedThreadDeathinInternal1 + "; receivedThreadDeathinInternal2=" + receivedThreadDeathinInternal2);
throw new RuntimeException("Caught ThreadDeath in run() instead of internalRun2() or internalRun1().\n"
+ "receivedThreadDeathinInternal1=" + receivedThreadDeathinInternal1
+ "; receivedThreadDeathinInternal2=" + receivedThreadDeathinInternal2);
} catch (NoClassDefFoundError ncdfe) {
// ignore because we're testing Thread.stop() which can cause it
// ignore because we're testing StopThread() which can cause it
}

if (receivedThreadDeathinInternal2 == false && receivedThreadDeathinInternal1 == false) {
throw new RuntimeException("Didn't catched ThreadDeath in internalRun2() nor in internalRun1(). receivedThreadDeathinInternal1=" + receivedThreadDeathinInternal1 + "; receivedThreadDeathinInternal2=" + receivedThreadDeathinInternal2);
throw new RuntimeException("Didn't catch ThreadDeath in internalRun2() nor in internalRun1().\n"
+ "receivedThreadDeathinInternal1=" + receivedThreadDeathinInternal1
+ "; receivedThreadDeathinInternal2=" + receivedThreadDeathinInternal2);
}
exitSyncObj.countDown();
}
Expand Down Expand Up @@ -120,7 +125,7 @@ public static void main(String[] args) {
thread.startSyncObj.await();
while (true) {
// Send async exception and wait until it is thrown
thread.stop();
JVMTIUtils.stopThread(thread);
thread.exitSyncObj.await();
Thread.sleep(100);

Expand All @@ -133,7 +138,7 @@ public static void main(String[] args) {
} catch (InterruptedException e) {
throw new Error("Unexpected: " + e);
} catch (NoClassDefFoundError ncdfe) {
// Ignore because we're testing Thread.stop() which can
// Ignore because we're testing StopThread which can
// cause it. Yes, a NoClassDefFoundError that happens
// in a worker thread can subsequently be seen in the
// main thread.
Expand Down Expand Up @@ -165,4 +170,3 @@ public static void usage() {
System.exit(1);
}
}

@@ -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
Expand Down Expand Up @@ -75,8 +75,6 @@ public static void main(String[] args) throws Throwable {
t.setName("NewName");
System.out.println("Calling interrupt ...");
t.interrupt();
System.out.println("Calling stop ...");
t.stop();

// Now the ThreadMXBean functions

Expand Down
42 changes: 42 additions & 0 deletions test/hotspot/jtreg/testlibrary/jvmti/JVMTIUtils.java
@@ -0,0 +1,42 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

package jvmti;

public class JVMTIUtils {

private static native int init();

static {
System.loadLibrary("JvmtiUtils");
if (init() != 0) {
throw new RuntimeException("Error during native lib utilization.");
}
}

private static native void stopThread(Thread t, Throwable ex);

public static void stopThread(Thread t) {
stopThread(t, new ThreadDeath());
}
}
61 changes: 61 additions & 0 deletions test/hotspot/jtreg/testlibrary/jvmti/libJvmtiUtils.cpp
@@ -0,0 +1,61 @@
/*
* Copyright (c) 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/

#include <string.h>
#include "jvmti.h"
#include "jvmti_common.h"

extern "C" {

static jvmtiEnv* jvmti = NULL;

JNIEXPORT jint JNICALL
Java_jvmti_JVMTIUtils_init(JNIEnv *jni, jclass cls) {
JavaVM* jvm;
jni->GetJavaVM(&jvm);

if (jvm->GetEnv((void **) (&jvmti), JVMTI_VERSION) != JNI_OK) {
return JNI_ERR;
}
jvmtiCapabilities caps;
memset(&caps, 0, sizeof (caps));
caps.can_signal_thread = 1;
jvmtiError err = jvmti->AddCapabilities(&caps);
if (err != JVMTI_ERROR_NONE) {
LOG("error in JVMTI AddCapabilities: %d\n", err);
return JNI_ERR;
}
return JNI_OK;
}

JNIEXPORT void JNICALL
Java_jvmti_JVMTIUtils_stopThread(JNIEnv *jni, jclass cls, jthread thread, jobject exception) {
jvmtiError err = jvmti->StopThread(thread, exception);
if (err == JVMTI_ERROR_THREAD_NOT_ALIVE) {
LOG("JVMTI_ERROR_THREAD_NOT_ALIVE happened");
return;
}
check_jvmti_status(jni, err, "Error during StopThread()");
}

}
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2002, 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
Expand Down Expand Up @@ -113,8 +113,6 @@ public void run() {
tArray[i].start();

tArray[0].join(); // wait for the javaHeapEater Thread to finish
tArray[1].stop(); // Once javaHeapEater is finished, stop the
// the cHeapEater thread.
} catch (Exception e) {
throw new TestFailure("Test Failed.", e);
}
Expand Down
46 changes: 17 additions & 29 deletions test/hotspot/jtreg/vmTestbase/nsk/stress/stack/stack002.java
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 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
Expand Down Expand Up @@ -74,26 +74,27 @@ public static int run(String args[], PrintStream out) {
Timer timer = new Timer(tester);
timer.start();
tester.start();
while (timer.isAlive())
while (timer.isAlive()) {
try {
timer.join();
} catch (InterruptedException e) {
e.printStackTrace(out);
return 2;
}
// if (tester.isAlive())
// return 2;
}
out.println("Maximal depth: " + tester.maxdepth);
return 0;
}

private static class Tester extends Thread {
int maxdepth;
PrintStream out;
public volatile boolean stop;

public Tester(PrintStream out) {
this.out = out;
maxdepth = 0;
stop = false;
}

public void run() {
Expand All @@ -103,24 +104,14 @@ public void run() {
void recurse(int depth) {
maxdepth = depth;
try {
if (stop) {
return;
}
recurse(depth + 1);
// } catch (StackOverflowError e) {
//
// OutOfMemoryError is also eligible to indicate stack overflow:
//
} catch (Error error) {
if (!(error instanceof StackOverflowError) &&
!(error instanceof OutOfMemoryError))
throw error;

/***
*** Originally, I supposed that VM crashes because of unexpected
*** native stack overflow (println() invokes native method).
*** However, I found that HS 1.3 and HS 2.0 crash even on
*** invocation of Java (not native) method.
***
out.println("StackOverflowError, depth=" + depth);
***/
recurse(depth + 1);
}
}
Expand All @@ -136,18 +127,15 @@ public Timer(Tester tester) {
public void run() {
long started;
started = System.currentTimeMillis();
while (System.currentTimeMillis() - started < timeout)
; /***
*** The test hangs on JDK 1.2.2 Classic VM if sleep() is invoked.
***
try {
this.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(tester.out);
return;
};
***/
tester.stop();
while (System.currentTimeMillis() - started < timeout) {
try {
this.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace(tester.out);
return;
};
}
tester.stop = true;
}
}
}

1 comment on commit 5a96a5d

@openjdk-notifier
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.