diff --git a/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java b/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java index 922538e7a9298..3f54f617eac52 100644 --- a/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java +++ b/test/hotspot/jtreg/runtime/Thread/TestBreakSignalThreadDump.java @@ -28,21 +28,45 @@ * @summary Check that Ctrl-\ or Ctrl-Break (on Windows) causes HotSpot VM to print a full thread dump. * @library /vmTestbase * /test/lib - * @run driver TestBreakSignalThreadDump + * @run driver TestBreakSignalThreadDump nolibjsig noxrs */ /* * @test id=with_jsig * @bug 8292695 * @summary Check that Ctrl-\ causes HotSpot VM to print a full thread dump when signal chaining is used. - * @requires os.family == "linux" | os.family == "mac" + * @requires os.family != "windows" * @library /vmTestbase * /test/lib - * @run driver TestBreakSignalThreadDump load_libjsig + * @run driver TestBreakSignalThreadDump libjsig noxrs */ +/* + * @test id=xrs + * @bug 8292695 + * @summary Check that when -Xrs is set, Ctrl-\ or Ctrl-Break (on Windows) causes HotSpot VM to quit (possibly with a core dump). + * TODO: Due to https://bugs.openjdk.org/browse/JDK-8234262, this does not work. Not sure why "main/othervm -Xrs" does not work around the problem. + * @library /vmTestbase + * /test/lib + * @run main/othervm -Xrs TestBreakSignalThreadDump nolibjsig xrs + */ + +/* + * @test id=xrs_with_jsig + * @bug 8292695 + * @summary Check that that when -Xrs is set and signal chaining is used, Ctrl-\ causes HotSpot VM to quit (possibly with a core dump). + * TODO: Due to https://bugs.openjdk.org/browse/JDK-8234262, this does not work. Not sure why "main/othervm -Xrs" does not work around the problem. + * @requires os.family != "windows" + * @library /vmTestbase + * /test/lib + * @run main/othervm -Xrs TestBreakSignalThreadDump libjsig xrs + */ + + import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; import java.util.Map; import jdk.test.lib.Platform; import jdk.test.lib.Utils; @@ -52,30 +76,63 @@ public class TestBreakSignalThreadDump { - static class TestProcess { + public static class TestProcess { static { System.loadLibrary("ProcessUtils"); } public static void main(String[] argv) throws Exception { ProcessUtils.sendCtrlBreak(); + // Wait a bit, as JVM processes the break signal asynchronously. + Thread.sleep(1000); System.out.println("Done!"); } } + public static void main(String[] argv) throws Exception { + if (argv.length != 2) { + System.err.println("Usage: TestBreakSignalThreadDump "); + throw new Exception("Incorrect commandline format."); + } + boolean libjsig = argv[0].equals("libjsig"); + boolean xrs = argv[1].equals("xrs"); + String main = "TestBreakSignalThreadDump$TestProcess"; - ProcessBuilder pb = ProcessTools.createTestJvm("-Djava.library.path=" + Utils.TEST_NATIVE_PATH, main); + List command = new ArrayList<>(4); + if (xrs) { + command.add("-Xrs"); + } + command.addAll(List.of( + // Set -Xmx4m to avoid producing a large core dump. + "-Xmx4m", + "-Djava.library.path=" + Utils.TEST_NATIVE_PATH, + main + )); + ProcessBuilder pb = ProcessTools.createTestJvm(command); - if (argv.length > 0 && argv[0].equals("load_libjsig")) { + System.out.println("\n" + String.join(" ", pb.command()) + "\n\n"); + + if (libjsig) { prepend_jsig_lib(pb.environment()); } OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); - output.shouldContain("Full thread dump "); - output.shouldContain("java.lang.Thread.State: RUNNABLE"); - output.shouldContain("Done!"); + if (xrs) { + // JNI code should have loaded and executed successfully. + output.shouldNotContain("UnsatisfiedLinkError"); + // The subprocess should have terminated abnormally, without printing thread dump or "Done!". + output.shouldNotHaveExitValue(0); + output.shouldNotContain("Full thread dump "); + output.shouldNotContain("java.lang.Thread.State: RUNNABLE"); + output.shouldNotContain("Done!"); + } else { + // The subprocess should exit normally with thread dump printed. + output.shouldHaveExitValue(0); + output.shouldContain("Full thread dump "); + output.shouldContain("java.lang.Thread.State: RUNNABLE"); + output.shouldContain("Done!"); + } } private static void prepend_jsig_lib(Map env) { diff --git a/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp b/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp index 0388af34e741b..9bbf0785ecb33 100644 --- a/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp +++ b/test/hotspot/jtreg/vmTestbase/vm/share/ProcessUtils.cpp @@ -95,6 +95,13 @@ JNIEXPORT jboolean JNICALL Java_vm_share_ProcessUtils_sendCtrlBreak } return JNI_TRUE; #else /* _WIN32 */ + struct sigaction oact; + sigaction(SIGQUIT, (struct sigaction*)NULL, &oact); + printf("SIG_IGN = %x\n", SIG_IGN); + printf("SIG_DFL = %x\n", SIG_DFL); + printf("oact.sa_sigaction = %x\n", oact.sa_sigaction); + printf("oact.sa_handler = %x\n", oact.sa_handler); + if (kill(getpid(), SIGQUIT) < 0) return JNI_FALSE; return JNI_TRUE;