Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

8289612: Change hotspot/jtreg tests to not use Thread.stop #9505

Closed
wants to merge 11 commits into from
Closed
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -25,18 +25,21 @@
* @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 {
private final static int DEF_TIME_MAX = 30; // default max # secs to test
private final static String PROG_NAME = "AsyncExceptionOnMonitorEnter";
private static int TEST_MODE = 0;

public static native int stopThread(Thread thread);
lmesnik marked this conversation as resolved.
Show resolved Hide resolved
public static native int createRawMonitor();
public static native int enterRawMonitor();
public static native int exitRawMonitor();
Expand Down Expand Up @@ -142,11 +145,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 +200,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("Catched ThreadDeath in run() instead of internalRun2() or internalRun1().\n"
lmesnik marked this conversation as resolved.
Show resolved Hide resolved
+ "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 catched ThreadDeath in internalRun2() nor in internalRun1().\n"
lmesnik marked this conversation as resolved.
Show resolved Hide resolved
+ "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);
}
}

Expand Up @@ -82,4 +82,4 @@ Agent_OnLoad(JavaVM *jvm, char *options, void *reserved) {
return JNI_OK;
}

}
}
@@ -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
lmesnik marked this conversation as resolved.
Show resolved Hide resolved
// the cHeapEater thread.
} catch (Exception e) {
throw new TestFailure("Test Failed.", e);
}
lmesnik marked this conversation as resolved.
Show resolved Hide resolved
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;
lmesnik marked this conversation as resolved.
Show resolved Hide resolved
}
}
}