From b7166c7719589613dbe742d0c80c7a0821b8e229 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Mon, 13 Oct 2025 11:25:55 +0000 Subject: [PATCH 01/39] fix and test --- src/hotspot/share/prims/jvmtiAgentList.cpp | 5 ++ .../TestEarlyDynamicLoadAttach.java | 60 ++++++++++++++++++ .../TestEarlyDynamicLoadJcmd.java | 52 +++++++++++++++ .../libEarlyDynamicAttach.c | 63 +++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java create mode 100644 test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java create mode 100644 test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c diff --git a/src/hotspot/share/prims/jvmtiAgentList.cpp b/src/hotspot/share/prims/jvmtiAgentList.cpp index 8da5b75be4611..05f7979747848 100644 --- a/src/hotspot/share/prims/jvmtiAgentList.cpp +++ b/src/hotspot/share/prims/jvmtiAgentList.cpp @@ -196,6 +196,11 @@ void JvmtiAgentList::load_xrun_agents() { // Invokes Agent_OnAttach for agents loaded dynamically during runtime. void JvmtiAgentList::load_agent(const char* agent_name, bool is_absolute_path, const char* options, outputStream* st) { + if (JvmtiEnvBase::get_phase() != JVMTI_PHASE_LIVE) { + st->print_cr("Not in live phase"); + return; + } + JvmtiAgent* const agent = new JvmtiAgent(agent_name, options, is_absolute_path, /* dynamic agent */ true); if (agent->load(st)) { add(agent); diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java new file mode 100644 index 0000000000000..077828c7b31ff --- /dev/null +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2025, 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. + */ + +/* + * @test TestEarlyDynamicLoadAttach + * @summary Test that dynamic attach (via VirtualMachine) fails gracefully when the JVM is not in live phase + * @requires vm.jvmti + * @library /test/lib /test/jdk + * @run driver/timeout=60 TestEarlyDynamicLoadAttach + */ + +import com.sun.tools.attach.VirtualMachine; +import java.io.File; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.JDKToolFinder; + +public class TestEarlyDynamicLoadAttach { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-XX:+StartAttachListener", + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicAttach"), + "-version"); + String javaPath = JDKToolFinder.getJDKTool("java"); + pb.environment().put("JAVA_PATH", javaPath); + pb.environment().put("CLASSPATH", System.getProperty("java.class.path")); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.stderrShouldContain("Not in live phase"); + } +} + +class AttachAgent { + public static void main(String... args) throws Exception { + VirtualMachine vm = VirtualMachine.attach(args[0]); + vm.loadAgent("some.jar"); + vm.detach(); + } +} diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java new file mode 100644 index 0000000000000..e3938ea515bea --- /dev/null +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2025, 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. + */ + +/* + * @test TestEarlyDynamicLoadJcmd + * @summary Test that jcmd fails gracefully when the JVM is not in live phase + * @requires vm.jvmti + * @library /test/lib /test/jdk + * @run driver/timeout=60 TestEarlyDynamicLoadJcmd + */ + +import java.io.File; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.JDKToolFinder; + +public class TestEarlyDynamicLoadJcmd { + public static void main(String[] args) throws Exception { + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( + "-XX:+StartAttachListener", + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicAttach"), + "-version"); + pb.environment().put("MODE", "jcmd"); + String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); + pb.environment().put("JCMD_PATH", jcmdPath); + + OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output.stdoutShouldContain("Not in live phase"); + output.stdoutShouldContain("jcmd result = 0"); + } +} diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c new file mode 100644 index 0000000000000..2a536af5cdb44 --- /dev/null +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2025, 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 +#include +#include +#include +#include +#include + +static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { + char cmd[256]; + snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), getpid()); + int res = system(cmd); + printf("jcmd result = %d\n", res); +} + +static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { + char cmd[1024]; + snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), + getpid()); + int res = system(cmd); + printf("attach result = %d\n", res); +} + +JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { + jvmtiEnv* jvmti; + if ((*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0) != 0) { + return 1; + } + + jvmtiEventCallbacks callbacks = {0}; + if (getenv("JCMD_PATH") != NULL) { + callbacks.VMStart = VMStartJcmd; + } else { + callbacks.VMStart = VMStartAttach; + } + + (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); + (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); + + return 0; +} \ No newline at end of file From 29f1a25b7c7c33add2b29f29841cc50bd8f48a41 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Mon, 13 Oct 2025 11:27:15 +0000 Subject: [PATCH 02/39] nl --- .../runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c index 2a536af5cdb44..cc87c37515ab4 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c @@ -60,4 +60,4 @@ JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); return 0; -} \ No newline at end of file +} From b821ba3f392d02c8b8b33f3dc8a29f4d5294c2e5 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Mon, 13 Oct 2025 12:46:23 +0000 Subject: [PATCH 03/39] cc --- .../TestEarlyDynamicLoadAttach.java | 2 +- .../TestEarlyDynamicLoadJcmd.java | 2 +- .../EarlyDynamicAttach/libEarlyDynamicAttach.c | 17 +++++++++++------ 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java index 077828c7b31ff..3c145e8b7c683 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java @@ -25,7 +25,7 @@ * @test TestEarlyDynamicLoadAttach * @summary Test that dynamic attach (via VirtualMachine) fails gracefully when the JVM is not in live phase * @requires vm.jvmti - * @library /test/lib /test/jdk + * @library /test/lib * @run driver/timeout=60 TestEarlyDynamicLoadAttach */ diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java index e3938ea515bea..e9507a54e9673 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java @@ -25,7 +25,7 @@ * @test TestEarlyDynamicLoadJcmd * @summary Test that jcmd fails gracefully when the JVM is not in live phase * @requires vm.jvmti - * @library /test/lib /test/jdk + * @library /test/lib * @run driver/timeout=60 TestEarlyDynamicLoadJcmd */ diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c index cc87c37515ab4..dce2533b74ff3 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c @@ -21,16 +21,21 @@ * questions. */ -#include #include -#include + #include -#include -#include +#include +#ifdef _WINDOWS +#include "process.h" +#define PID() _getpid() +#else +#include "unistd.h" +#define PID() getpid() +#endif // _WINDOWS static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[256]; - snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), getpid()); + snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); int res = system(cmd); printf("jcmd result = %d\n", res); } @@ -38,7 +43,7 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), - getpid()); + PID()); int res = system(cmd); printf("attach result = %d\n", res); } From 001e2f62bb3001b30b1f60f3c18733e3919c2ebf Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Mon, 13 Oct 2025 15:48:33 +0000 Subject: [PATCH 04/39] macro --- .../runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c index dce2533b74ff3..c935e5464e15a 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c @@ -25,13 +25,13 @@ #include #include -#ifdef _WINDOWS +#ifdef WINDOWS #include "process.h" #define PID() _getpid() #else #include "unistd.h" #define PID() getpid() -#endif // _WINDOWS +#endif // WINDOWS static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[256]; From 96e234035acd7b9063772f3d9f832db9619b6169 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Mon, 13 Oct 2025 23:59:50 +0000 Subject: [PATCH 05/39] fix check --- .../jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java | 2 +- .../jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java index 3c145e8b7c683..636811df0297f 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java @@ -47,7 +47,7 @@ public static void main(String[] args) throws Exception { pb.environment().put("CLASSPATH", System.getProperty("java.class.path")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.stderrShouldContain("Not in live phase"); + output.shouldHaveExitValue(0); } } diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java index e9507a54e9673..4629159224855 100644 --- a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java @@ -46,7 +46,6 @@ public static void main(String[] args) throws Exception { pb.environment().put("JCMD_PATH", jcmdPath); OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.stdoutShouldContain("Not in live phase"); - output.stdoutShouldContain("jcmd result = 0"); + output.shouldHaveExitValue(0); } } From cdd5a22c94f4ef02d5dddf344c90dff0f654f87d Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 14 Oct 2025 00:09:18 +0000 Subject: [PATCH 06/39] mv --- .../EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java | 0 .../EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java | 0 .../EarlyDynamicAttach/libEarlyDynamicAttach.c | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/hotspot/jtreg/{runtime/jni => serviceability}/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java (100%) rename test/hotspot/jtreg/{runtime/jni => serviceability}/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java (100%) rename test/hotspot/jtreg/{runtime/jni => serviceability}/EarlyDynamicAttach/libEarlyDynamicAttach.c (100%) diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java similarity index 100% rename from test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java rename to test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java similarity index 100% rename from test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java rename to test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java diff --git a/test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/libEarlyDynamicAttach.c similarity index 100% rename from test/hotspot/jtreg/runtime/jni/EarlyDynamicAttach/libEarlyDynamicAttach.c rename to test/hotspot/jtreg/serviceability/EarlyDynamicAttach/libEarlyDynamicAttach.c From e3df527fc2eb2b6faf6fc699597e5ed1607b065e Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 14 Oct 2025 00:10:06 +0000 Subject: [PATCH 07/39] nn --- .../EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java | 2 +- .../EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java index 636811df0297f..74197dc585c04 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java @@ -26,7 +26,7 @@ * @summary Test that dynamic attach (via VirtualMachine) fails gracefully when the JVM is not in live phase * @requires vm.jvmti * @library /test/lib - * @run driver/timeout=60 TestEarlyDynamicLoadAttach + * @run driver TestEarlyDynamicLoadAttach */ import com.sun.tools.attach.VirtualMachine; diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java index 4629159224855..baf8c06e06269 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java @@ -26,7 +26,7 @@ * @summary Test that jcmd fails gracefully when the JVM is not in live phase * @requires vm.jvmti * @library /test/lib - * @run driver/timeout=60 TestEarlyDynamicLoadJcmd + * @run driver TestEarlyDynamicLoadJcmd */ import java.io.File; From 941f9a679b7c3fee2e26cfad6f17b6a2608743c1 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 14 Oct 2025 00:14:17 +0000 Subject: [PATCH 08/39] mv --- .../TestEarlyDynamicLoadAttach.java | 2 +- .../TestEarlyDynamicLoadJcmd.java | 2 +- .../libEarlyDynamicLoad.c} | 0 3 files changed, 2 insertions(+), 2 deletions(-) rename test/hotspot/jtreg/serviceability/{EarlyDynamicAttach => EarlyDynamicLoad}/TestEarlyDynamicLoadAttach.java (97%) rename test/hotspot/jtreg/serviceability/{EarlyDynamicAttach => EarlyDynamicLoad}/TestEarlyDynamicLoadJcmd.java (97%) rename test/hotspot/jtreg/serviceability/{EarlyDynamicAttach/libEarlyDynamicAttach.c => EarlyDynamicLoad/libEarlyDynamicLoad.c} (100%) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java similarity index 97% rename from test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java rename to test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index 74197dc585c04..73a0a58597f88 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -40,7 +40,7 @@ public class TestEarlyDynamicLoadAttach { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-XX:+StartAttachListener", - "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicAttach"), + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String javaPath = JDKToolFinder.getJDKTool("java"); pb.environment().put("JAVA_PATH", javaPath); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java similarity index 97% rename from test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java rename to test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index baf8c06e06269..29312b558cec5 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -39,7 +39,7 @@ public class TestEarlyDynamicLoadJcmd { public static void main(String[] args) throws Exception { ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-XX:+StartAttachListener", - "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicAttach"), + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); pb.environment().put("MODE", "jcmd"); String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicAttach/libEarlyDynamicAttach.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c similarity index 100% rename from test/hotspot/jtreg/serviceability/EarlyDynamicAttach/libEarlyDynamicAttach.c rename to test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c From 49722e1b3ad5292374e2ca5edf832f9290ab9075 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 14 Oct 2025 08:13:05 +0000 Subject: [PATCH 09/39] summary --- .../EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 3 ++- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index 73a0a58597f88..35784d1a0cef5 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -23,7 +23,8 @@ /* * @test TestEarlyDynamicLoadAttach - * @summary Test that dynamic attach (via VirtualMachine) fails gracefully when the JVM is not in live phase + * @summary Test that dynamic attach (via VirtualMachine) fails gracefully when the JVM is not in live phase. + * The test sets up a callback for VMStart in Agent_OnLoad, which then tries to attach with VirtualMachine. * @requires vm.jvmti * @library /test/lib * @run driver TestEarlyDynamicLoadAttach diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index 29312b558cec5..832984d6d5899 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -23,7 +23,8 @@ /* * @test TestEarlyDynamicLoadJcmd - * @summary Test that jcmd fails gracefully when the JVM is not in live phase + * @summary Test that jcmd fails gracefully when the JVM is not in live phase. + * The test sets up a callback for VMStart in Agent_OnLoad, which then invokes jcmd. * @requires vm.jvmti * @library /test/lib * @run driver TestEarlyDynamicLoadJcmd From 84f168b64d901cdd04412962d1e54bd1f36e1c1a Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 11:24:35 +0100 Subject: [PATCH 10/39] Update src/hotspot/share/prims/jvmtiAgentList.cpp Co-authored-by: David Holmes <62092539+dholmes-ora@users.noreply.github.com> --- src/hotspot/share/prims/jvmtiAgentList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/prims/jvmtiAgentList.cpp b/src/hotspot/share/prims/jvmtiAgentList.cpp index 05f7979747848..41fc9c0f3594c 100644 --- a/src/hotspot/share/prims/jvmtiAgentList.cpp +++ b/src/hotspot/share/prims/jvmtiAgentList.cpp @@ -197,7 +197,7 @@ void JvmtiAgentList::load_xrun_agents() { void JvmtiAgentList::load_agent(const char* agent_name, bool is_absolute_path, const char* options, outputStream* st) { if (JvmtiEnvBase::get_phase() != JVMTI_PHASE_LIVE) { - st->print_cr("Not in live phase"); + st->print_cr("Dynamic agent loading is only permitted in the live phase"); return; } From 2e21bc3f38404183bb0677980732ba1487d110d0 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 11:07:23 +0000 Subject: [PATCH 11/39] nn --- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 1 - 1 file changed, 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index 832984d6d5899..e1c723e065f1f 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -42,7 +42,6 @@ public static void main(String[] args) throws Exception { "-XX:+StartAttachListener", "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); - pb.environment().put("MODE", "jcmd"); String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); pb.environment().put("JCMD_PATH", jcmdPath); From e9646e685357c066f66939e97c48813c5f064c1d Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 11:40:56 +0000 Subject: [PATCH 12/39] errno --- .../EarlyDynamicLoad/libEarlyDynamicLoad.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index c935e5464e15a..a29ec366ed0bf 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -23,6 +23,7 @@ #include +#include #include #include #ifdef WINDOWS @@ -37,7 +38,11 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[256]; snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); int res = system(cmd); - printf("jcmd result = %d\n", res); + if (res == -1) { + printf("jcmd call failed: %s\n", strerror(errno)); + } else { + printf("jcmd result = %d\n", res); + } } static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { @@ -45,7 +50,11 @@ static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), PID()); int res = system(cmd); - printf("attach result = %d\n", res); + if (res == -1) { + printf("attach call failed: %s\n", strerror(errno)); + } else { + printf("attach result = %d\n", res); + } } JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { From cbbbf8a22e195c6dc242595949d40c8bce58b059 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 11:51:56 +0000 Subject: [PATCH 13/39] ops --- .../EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 1 + .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 1 + .../jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c | 1 + 3 files changed, 3 insertions(+) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index 35784d1a0cef5..eee58b8f85bc9 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -49,6 +49,7 @@ public static void main(String[] args) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); + output.shouldContain("Dynamic agent loading is only permitted in the live phase"); } } diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index e1c723e065f1f..544fe454e9148 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -47,5 +47,6 @@ public static void main(String[] args) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); + output.shouldContain("Dynamic agent loading is only permitted in the live phase"); } } diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index a29ec366ed0bf..d5ce0cbcfdf02 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -26,6 +26,7 @@ #include #include #include +#include #ifdef WINDOWS #include "process.h" #define PID() _getpid() From b53c2da4588f433918314432fca58dcad16be4b6 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 14:05:40 +0000 Subject: [PATCH 14/39] debug --- .../serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index d5ce0cbcfdf02..9f91d003c9293 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -38,6 +38,8 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[256]; snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); + printf("Running jcmd command: '%s'\n", cmd); + int res = system(cmd); if (res == -1) { printf("jcmd call failed: %s\n", strerror(errno)); @@ -50,6 +52,8 @@ static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[1024]; snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), PID()); + printf("Running attach command: '%s'\n", cmd); + int res = system(cmd); if (res == -1) { printf("attach call failed: %s\n", strerror(errno)); From 2a7ab98d7bda7dcb2070c9da720419bc578a04f1 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 20:47:29 +0000 Subject: [PATCH 15/39] replace --- src/hotspot/share/code/nmethod.cpp | 2 +- .../EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 4 ++-- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 7274b627f3e6b..6dc23ad2ba366 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -2596,7 +2596,7 @@ void nmethod::metadata_do(MetadataClosure* f) { // Main purpose is to reduce code cache pressure and get rid of // nmethods that don't seem to be all that relevant any longer. bool nmethod::is_cold() { - if (!MethodFlushing || is_native_method() || is_not_installed()) { + if (!MethodFlushing || is_not_installed()) { // No heuristic unloading at all return false; } diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index eee58b8f85bc9..e754616992a73 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -44,8 +44,8 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String javaPath = JDKToolFinder.getJDKTool("java"); - pb.environment().put("JAVA_PATH", javaPath); - pb.environment().put("CLASSPATH", System.getProperty("java.class.path")); + pb.environment().put("JAVA_PATH", javaPath.replace("\\", "/")); + pb.environment().put("CLASSPATH", System.getProperty("java.class.path").replace("\\", "/")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index 544fe454e9148..ce7c82f2b691a 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -43,7 +43,7 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); - pb.environment().put("JCMD_PATH", jcmdPath); + pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "/")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); From 7870ca781a0cf0219089c26c3d4d7c9349e88981 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 20:49:00 +0000 Subject: [PATCH 16/39] revert --- src/hotspot/share/code/nmethod.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/code/nmethod.cpp b/src/hotspot/share/code/nmethod.cpp index 6dc23ad2ba366..7274b627f3e6b 100644 --- a/src/hotspot/share/code/nmethod.cpp +++ b/src/hotspot/share/code/nmethod.cpp @@ -2596,7 +2596,7 @@ void nmethod::metadata_do(MetadataClosure* f) { // Main purpose is to reduce code cache pressure and get rid of // nmethods that don't seem to be all that relevant any longer. bool nmethod::is_cold() { - if (!MethodFlushing || is_not_installed()) { + if (!MethodFlushing || is_native_method() || is_not_installed()) { // No heuristic unloading at all return false; } From 1363424e97335b8b7eb46b94a7f01f4e91d8f5de Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Thu, 16 Oct 2025 22:49:17 +0000 Subject: [PATCH 17/39] check jcmd exist --- .../EarlyDynamicLoad/libEarlyDynamicLoad.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index 9f91d003c9293..42dc8313bc010 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -36,8 +36,16 @@ #endif // WINDOWS static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { + const char* jcmd_path = getenv("JCMD_PATH"); + FILE* file = fopen(jcmd_path, "r"); + if (file == NULL) { + printf("%s does not exist", jcmd_path); + return; + } + fclose(file); + char cmd[256]; - snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); + snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", jcmd_path, PID()); printf("Running jcmd command: '%s'\n", cmd); int res = system(cmd); From bc998afd4a050e88b96433c77f706af65f690214 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 00:35:23 +0000 Subject: [PATCH 18/39] wip --- .../jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index 42dc8313bc010..31f471ec53adb 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -45,7 +45,7 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { fclose(file); char cmd[256]; - snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", jcmd_path, PID()); + snprintf(cmd, sizeof(cmd), "%s %d help", jcmd_path, PID()); printf("Running jcmd command: '%s'\n", cmd); int res = system(cmd); From e0b879b08b14dba4e2e5c24219bc6d8d78251750 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 08:07:15 +0000 Subject: [PATCH 19/39] revert --- .../EarlyDynamicLoad/libEarlyDynamicLoad.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index 31f471ec53adb..9f91d003c9293 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -36,16 +36,8 @@ #endif // WINDOWS static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { - const char* jcmd_path = getenv("JCMD_PATH"); - FILE* file = fopen(jcmd_path, "r"); - if (file == NULL) { - printf("%s does not exist", jcmd_path); - return; - } - fclose(file); - char cmd[256]; - snprintf(cmd, sizeof(cmd), "%s %d help", jcmd_path, PID()); + snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); printf("Running jcmd command: '%s'\n", cmd); int res = system(cmd); From 4269dee4aa72459b5ff8e27de22afec53db2508a Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 08:13:42 +0000 Subject: [PATCH 20/39] quote --- .../EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 4 ++-- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 2 +- .../serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index e754616992a73..eee58b8f85bc9 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -44,8 +44,8 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String javaPath = JDKToolFinder.getJDKTool("java"); - pb.environment().put("JAVA_PATH", javaPath.replace("\\", "/")); - pb.environment().put("CLASSPATH", System.getProperty("java.class.path").replace("\\", "/")); + pb.environment().put("JAVA_PATH", javaPath); + pb.environment().put("CLASSPATH", System.getProperty("java.class.path")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index ce7c82f2b691a..544fe454e9148 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -43,7 +43,7 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); - pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "/")); + pb.environment().put("JCMD_PATH", jcmdPath); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index 9f91d003c9293..d9a0a6361843e 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -37,7 +37,7 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[256]; - snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); + snprintf(cmd, sizeof(cmd), "\"%s\" %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); printf("Running jcmd command: '%s'\n", cmd); int res = system(cmd); @@ -50,8 +50,7 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[1024]; - snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), - PID()); + snprintf(cmd, sizeof(cmd), "\"%s\" -cp \"%s\" AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), PID()); printf("Running attach command: '%s'\n", cmd); int res = system(cmd); From 8bbedbcae0cdab7f93e3552d912110513e866a90 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 10:09:07 +0000 Subject: [PATCH 21/39] backslash --- .../EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 4 ++-- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index eee58b8f85bc9..250fa514881ad 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -44,8 +44,8 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String javaPath = JDKToolFinder.getJDKTool("java"); - pb.environment().put("JAVA_PATH", javaPath); - pb.environment().put("CLASSPATH", System.getProperty("java.class.path")); + pb.environment().put("JAVA_PATH", javaPath.replace("\\", "\\\\")); + pb.environment().put("CLASSPATH", System.getProperty("java.class.path").replace("\\", "\\\\")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index 544fe454e9148..a4d99197cc5d2 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -43,7 +43,7 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); - pb.environment().put("JCMD_PATH", jcmdPath); + pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "\\\\")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); From 84fa5ac57ff818ec46d342380ea188c0088bcf42 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 12:53:12 +0000 Subject: [PATCH 22/39] debug --- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index a4d99197cc5d2..2d46fdcd0368d 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -38,6 +38,12 @@ public class TestEarlyDynamicLoadJcmd { public static void main(String[] args) throws Exception { + ProcessBuilder x = new ProcessBuilder(); + String pid = Long.toString(ProcessTools.getProcessId()); + x.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "help"}); + OutputAnalyzer output = new OutputAnalyzer(x.start()); + output.shouldHaveExitValue(0); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-XX:+StartAttachListener", "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), @@ -45,7 +51,7 @@ public static void main(String[] args) throws Exception { String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "\\\\")); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); + output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); output.shouldContain("Dynamic agent loading is only permitted in the live phase"); } From 5b98640c751f5ff1d472bfb02ba56e336a550953 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 14:52:44 +0000 Subject: [PATCH 23/39] revert --- .../EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 4 ++-- .../EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 10 ++-------- .../EarlyDynamicLoad/libEarlyDynamicLoad.c | 5 +++-- 3 files changed, 7 insertions(+), 12 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index 250fa514881ad..e754616992a73 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -44,8 +44,8 @@ public static void main(String[] args) throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String javaPath = JDKToolFinder.getJDKTool("java"); - pb.environment().put("JAVA_PATH", javaPath.replace("\\", "\\\\")); - pb.environment().put("CLASSPATH", System.getProperty("java.class.path").replace("\\", "\\\\")); + pb.environment().put("JAVA_PATH", javaPath.replace("\\", "/")); + pb.environment().put("CLASSPATH", System.getProperty("java.class.path").replace("\\", "/")); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index 2d46fdcd0368d..ce7c82f2b691a 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -38,20 +38,14 @@ public class TestEarlyDynamicLoadJcmd { public static void main(String[] args) throws Exception { - ProcessBuilder x = new ProcessBuilder(); - String pid = Long.toString(ProcessTools.getProcessId()); - x.command(new String[] { JDKToolFinder.getJDKTool("jcmd"), pid, "help"}); - OutputAnalyzer output = new OutputAnalyzer(x.start()); - output.shouldHaveExitValue(0); - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( "-XX:+StartAttachListener", "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); - pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "\\\\")); + pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "/")); - output = new OutputAnalyzer(pb.start()); + OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); output.shouldContain("Dynamic agent loading is only permitted in the live phase"); } diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c index d9a0a6361843e..9f91d003c9293 100644 --- a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -37,7 +37,7 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[256]; - snprintf(cmd, sizeof(cmd), "\"%s\" %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); + snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); printf("Running jcmd command: '%s'\n", cmd); int res = system(cmd); @@ -50,7 +50,8 @@ static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { char cmd[1024]; - snprintf(cmd, sizeof(cmd), "\"%s\" -cp \"%s\" AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), PID()); + snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), + PID()); printf("Running attach command: '%s'\n", cmd); int res = system(cmd); From 4dddb5ab908738fe5e82b03e48af20129d782631 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 14:53:46 +0000 Subject: [PATCH 24/39] mv to attach --- .../{ => attach}/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java | 0 .../{ => attach}/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java | 0 .../{ => attach}/EarlyDynamicLoad/libEarlyDynamicLoad.c | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename test/hotspot/jtreg/serviceability/{ => attach}/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java (100%) rename test/hotspot/jtreg/serviceability/{ => attach}/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java (100%) rename test/hotspot/jtreg/serviceability/{ => attach}/EarlyDynamicLoad/libEarlyDynamicLoad.c (100%) diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java similarity index 100% rename from test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java rename to test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java similarity index 100% rename from test/hotspot/jtreg/serviceability/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java rename to test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java diff --git a/test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c similarity index 100% rename from test/hotspot/jtreg/serviceability/EarlyDynamicLoad/libEarlyDynamicLoad.c rename to test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c From 4fa7d721564804349c27c71ead9eae98867b2742 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 15:10:48 +0000 Subject: [PATCH 25/39] simplfiy --- .../TestEarlyDynamicLoadAttach.java | 6 ++-- .../TestEarlyDynamicLoadJcmd.java | 4 ++- .../EarlyDynamicLoad/libEarlyDynamicLoad.c | 35 +++++-------------- 3 files changed, 16 insertions(+), 29 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java index e754616992a73..623ca9fc12b73 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java @@ -43,9 +43,11 @@ public static void main(String[] args) throws Exception { "-XX:+StartAttachListener", "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); + String javaPath = JDKToolFinder.getJDKTool("java"); - pb.environment().put("JAVA_PATH", javaPath.replace("\\", "/")); - pb.environment().put("CLASSPATH", System.getProperty("java.class.path").replace("\\", "/")); + String classPath = System.getProperty("java.class.path"); + String attachCommand = String.format("%s -cp %s AttachAgent %%d", javaPath, classPath); + pb.environment().put("ATTACH_CMD", attachCommand); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java index ce7c82f2b691a..3f17cd77b660e 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java @@ -42,8 +42,10 @@ public static void main(String[] args) throws Exception { "-XX:+StartAttachListener", "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version"); + String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); - pb.environment().put("JCMD_PATH", jcmdPath.replace("\\", "/")); + String attachCommand = String.format("%s %%d JVMTI.agent_load some.jar", jcmdPath); + pb.environment().put("ATTACH_CMD", attachCommand); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c index 9f91d003c9293..cf46cd3f37b18 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -35,30 +35,17 @@ #define PID() getpid() #endif // WINDOWS -static void JNICALL VMStartJcmd(jvmtiEnv* jvmti, JNIEnv* env) { - char cmd[256]; - snprintf(cmd, sizeof(cmd), "%s %d JVMTI.agent_load some.jar", getenv("JCMD_PATH"), PID()); - printf("Running jcmd command: '%s'\n", cmd); +static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { + const char* attach_cmd_pattern = getenv("ATTACH_CMD"); + char attach_cmd[1024]; + snprintf(attach_cmd, sizeof(attach_cmd), attach_cmd_pattern, PID()); + printf("Running attach command: '%s'\n", attach_cmd); - int res = system(cmd); + int res = system(attach_cmd); if (res == -1) { - printf("jcmd call failed: %s\n", strerror(errno)); + printf("Attach call failed: %s\n", strerror(errno)); } else { - printf("jcmd result = %d\n", res); - } -} - -static void JNICALL VMStartAttach(jvmtiEnv* jvmti, JNIEnv* env) { - char cmd[1024]; - snprintf(cmd, sizeof(cmd), "%s -cp %s AttachAgent %d", getenv("JAVA_PATH"), getenv("CLASSPATH"), - PID()); - printf("Running attach command: '%s'\n", cmd); - - int res = system(cmd); - if (res == -1) { - printf("attach call failed: %s\n", strerror(errno)); - } else { - printf("attach result = %d\n", res); + printf("Attach call result = %d\n", res); } } @@ -69,11 +56,7 @@ JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { } jvmtiEventCallbacks callbacks = {0}; - if (getenv("JCMD_PATH") != NULL) { - callbacks.VMStart = VMStartJcmd; - } else { - callbacks.VMStart = VMStartAttach; - } + callbacks.VMStart = VMStartCallback; (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); From 4fd6e07f985bec800cb2ae7a0fe2581c5b8b941c Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 15:58:57 +0000 Subject: [PATCH 26/39] cc --- .../TestEarlyDynamicLoad.java | 94 +++++++++++++++++++ .../TestEarlyDynamicLoadAttach.java | 64 ------------- .../TestEarlyDynamicLoadJcmd.java | 54 ----------- .../EarlyDynamicLoad/libEarlyDynamicLoad.c | 25 +---- 4 files changed, 97 insertions(+), 140 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java delete mode 100644 test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java delete mode 100644 test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java new file mode 100644 index 0000000000000..c87975170ca4d --- /dev/null +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2025, 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. + */ + +import com.sun.tools.attach.VirtualMachine; +import com.sun.tools.attach.AgentLoadException; + +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.AfterAll; + +import java.io.File; +import java.io.InputStream; +import java.util.Objects; +import java.util.concurrent.TimeUnit; +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.Utils; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.process.OutputAnalyzer; + +/* + * @test TestEarlyDynamicLoad + * @summary Test that dynamic attach fails gracefully when the JVM is not in live phase. + * @requires vm.jvmti + * @library /test/lib + * @run junit TestEarlyDynamicLoad + */ +public class TestEarlyDynamicLoad { + private static Process child; + + @BeforeAll + static void startAndWaitChild() throws Exception { + child = ProcessTools.createTestJavaProcessBuilder( + "-XX:+StartAttachListener", + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), + "-version").start(); + + // Wait the process to enter VMStartCallback + child.getInputStream().read(); + } + + @AfterAll + static void stopChild() throws Exception { + child.destroy(); + child.waitFor(); + } + + @Test + public void virtualMachine() throws Exception { + try { + VirtualMachine vm = VirtualMachine.attach(child.pid() + ""); + vm.loadAgent("some.jar"); + vm.detach(); + throw new AssertionError("Should have failed with AgentLoadException"); + } catch(AgentLoadException exception) { + if (!exception.getMessage().contains("Dynamic agent loading is only permitted in the live phase")) { + throw new AssertionError("Unexpected error message", exception); + } + } + } + + @Test + public void jcmd() throws Exception { + JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd"); + jcmd.addToolArg(child.pid() + ""); + jcmd.addToolArg("JVMTI.agent_load"); + jcmd.addToolArg("some.jar"); + + ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand()); + OutputAnalyzer out = new OutputAnalyzer(pb.start()); + + out.shouldHaveExitValue(0); + out.stdoutShouldContain("Dynamic agent loading is only permitted in the live phase"); + } +} diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java deleted file mode 100644 index 623ca9fc12b73..0000000000000 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadAttach.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2025, 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. - */ - -/* - * @test TestEarlyDynamicLoadAttach - * @summary Test that dynamic attach (via VirtualMachine) fails gracefully when the JVM is not in live phase. - * The test sets up a callback for VMStart in Agent_OnLoad, which then tries to attach with VirtualMachine. - * @requires vm.jvmti - * @library /test/lib - * @run driver TestEarlyDynamicLoadAttach - */ - -import com.sun.tools.attach.VirtualMachine; -import java.io.File; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.JDKToolFinder; - -public class TestEarlyDynamicLoadAttach { - public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( - "-XX:+StartAttachListener", - "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), - "-version"); - - String javaPath = JDKToolFinder.getJDKTool("java"); - String classPath = System.getProperty("java.class.path"); - String attachCommand = String.format("%s -cp %s AttachAgent %%d", javaPath, classPath); - pb.environment().put("ATTACH_CMD", attachCommand); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); - output.shouldContain("Dynamic agent loading is only permitted in the live phase"); - } -} - -class AttachAgent { - public static void main(String... args) throws Exception { - VirtualMachine vm = VirtualMachine.attach(args[0]); - vm.loadAgent("some.jar"); - vm.detach(); - } -} diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java deleted file mode 100644 index 3f17cd77b660e..0000000000000 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoadJcmd.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2025, 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. - */ - -/* - * @test TestEarlyDynamicLoadJcmd - * @summary Test that jcmd fails gracefully when the JVM is not in live phase. - * The test sets up a callback for VMStart in Agent_OnLoad, which then invokes jcmd. - * @requires vm.jvmti - * @library /test/lib - * @run driver TestEarlyDynamicLoadJcmd - */ - -import java.io.File; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Utils; -import jdk.test.lib.process.ProcessTools; -import jdk.test.lib.JDKToolFinder; - -public class TestEarlyDynamicLoadJcmd { - public static void main(String[] args) throws Exception { - ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder( - "-XX:+StartAttachListener", - "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), - "-version"); - - String jcmdPath = JDKToolFinder.getJDKTool("jcmd"); - String attachCommand = String.format("%s %%d JVMTI.agent_load some.jar", jcmdPath); - pb.environment().put("ATTACH_CMD", attachCommand); - - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldHaveExitValue(0); - output.shouldContain("Dynamic agent loading is only permitted in the live phase"); - } -} diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c index cf46cd3f37b18..566cd65a5239d 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c @@ -22,31 +22,12 @@ */ #include - -#include -#include #include -#include -#ifdef WINDOWS -#include "process.h" -#define PID() _getpid() -#else -#include "unistd.h" -#define PID() getpid() -#endif // WINDOWS static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { - const char* attach_cmd_pattern = getenv("ATTACH_CMD"); - char attach_cmd[1024]; - snprintf(attach_cmd, sizeof(attach_cmd), attach_cmd_pattern, PID()); - printf("Running attach command: '%s'\n", attach_cmd); - - int res = system(attach_cmd); - if (res == -1) { - printf("Attach call failed: %s\n", strerror(errno)); - } else { - printf("Attach call result = %d\n", res); - } + putchar('1'); + fflush(stdout); + getchar(); } JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { From 1af09f8ba080416b94aeb947da3a6be1acf9167d Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 16:06:20 +0000 Subject: [PATCH 27/39] c++ --- ...arlyDynamicLoad.c => libEarlyDynamicLoad.cpp} | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) rename test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/{libEarlyDynamicLoad.c => libEarlyDynamicLoad.cpp} (80%) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp similarity index 80% rename from test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c rename to test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp index 566cd65a5239d..a7c62966fd875 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.c +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp @@ -22,7 +22,10 @@ */ #include -#include +#include +#include + +extern "C" { static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { putchar('1'); @@ -32,15 +35,18 @@ static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { jvmtiEnv* jvmti; - if ((*vm)->GetEnv(vm, (void**)&jvmti, JVMTI_VERSION_1_0) != 0) { + if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != 0) { return 1; } - jvmtiEventCallbacks callbacks = {0}; + jvmtiEventCallbacks callbacks; + memset(&callbacks, 0, sizeof(callbacks)); callbacks.VMStart = VMStartCallback; - (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks)); - (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); + jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); + jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); return 0; } + +} From 93667b807f3427767bac6e0db6238157721786cd Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 16:20:24 +0000 Subject: [PATCH 28/39] msg --- .../attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index c87975170ca4d..0f96bc32763d5 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -45,6 +45,8 @@ * @run junit TestEarlyDynamicLoad */ public class TestEarlyDynamicLoad { + private static final String EXPECTED_MESSAGE = "Dynamic agent loading is only permitted in the live phase"; + private static Process child; @BeforeAll @@ -72,7 +74,7 @@ public void virtualMachine() throws Exception { vm.detach(); throw new AssertionError("Should have failed with AgentLoadException"); } catch(AgentLoadException exception) { - if (!exception.getMessage().contains("Dynamic agent loading is only permitted in the live phase")) { + if (!exception.getMessage().contains(EXPECTED_MESSAGE)) { throw new AssertionError("Unexpected error message", exception); } } @@ -89,6 +91,6 @@ public void jcmd() throws Exception { OutputAnalyzer out = new OutputAnalyzer(pb.start()); out.shouldHaveExitValue(0); - out.stdoutShouldContain("Dynamic agent loading is only permitted in the live phase"); + out.stdoutShouldContain(EXPECTED_MESSAGE); } } From 2e628c601255e1bd39862414434ac36f3221c7df Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 17:47:51 +0000 Subject: [PATCH 29/39] nullptr --- .../attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp index a7c62966fd875..ffea42ae32e8e 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp @@ -44,7 +44,7 @@ JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { callbacks.VMStart = VMStartCallback; jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); - jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, NULL); + jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr); return 0; } From 30b2cf96d673dd7f3e0b007f50cf29d9298fcb18 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Fri, 17 Oct 2025 20:11:09 +0000 Subject: [PATCH 30/39] fix tool call --- .../attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index 0f96bc32763d5..9df601800eed6 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -27,6 +27,7 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; +import org.junit.jupiter.api.Assumptions; import java.io.File; import java.io.InputStream; @@ -82,7 +83,14 @@ public void virtualMachine() throws Exception { @Test public void jcmd() throws Exception { - JDKToolLauncher jcmd = JDKToolLauncher.createUsingTestJDK("jcmd"); + JDKToolLauncher jcmd; + try { + jcmd = JDKToolLauncher.create("jcmd"); + } catch (Exception exception) { + Assumptions.abort("jcmd wasn't found: " + exception.getMessage()); + return; + } + jcmd.addToolArg(child.pid() + ""); jcmd.addToolArg("JVMTI.agent_load"); jcmd.addToolArg("some.jar"); From bd4b98a7ad038a4516db7caa8d62204ba760a79c Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 08:14:38 +0000 Subject: [PATCH 31/39] PidJcmdExecutor. unused import. cc --- .../TestEarlyDynamicLoad.java | 26 +++++-------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index 9df601800eed6..ce2bef2cbc822 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -27,16 +27,14 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.AfterAll; -import org.junit.jupiter.api.Assumptions; import java.io.File; import java.io.InputStream; import java.util.Objects; -import java.util.concurrent.TimeUnit; -import jdk.test.lib.JDKToolLauncher; -import jdk.test.lib.Utils; -import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.dcmd.PidJcmdExecutor; import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; +import jdk.test.lib.Utils; /* * @test TestEarlyDynamicLoad @@ -70,7 +68,7 @@ static void stopChild() throws Exception { @Test public void virtualMachine() throws Exception { try { - VirtualMachine vm = VirtualMachine.attach(child.pid() + ""); + VirtualMachine vm = VirtualMachine.attach(String.valueOf(child.pid())); vm.loadAgent("some.jar"); vm.detach(); throw new AssertionError("Should have failed with AgentLoadException"); @@ -83,20 +81,8 @@ public void virtualMachine() throws Exception { @Test public void jcmd() throws Exception { - JDKToolLauncher jcmd; - try { - jcmd = JDKToolLauncher.create("jcmd"); - } catch (Exception exception) { - Assumptions.abort("jcmd wasn't found: " + exception.getMessage()); - return; - } - - jcmd.addToolArg(child.pid() + ""); - jcmd.addToolArg("JVMTI.agent_load"); - jcmd.addToolArg("some.jar"); - - ProcessBuilder pb = new ProcessBuilder(jcmd.getCommand()); - OutputAnalyzer out = new OutputAnalyzer(pb.start()); + PidJcmdExecutor executor = new PidJcmdExecutor(String.valueOf(child.pid())); + OutputAnalyzer out = executor.execute("JVMTI.agent_load some.jar"); out.shouldHaveExitValue(0); out.stdoutShouldContain(EXPECTED_MESSAGE); From 9d51f085e1eb2e45761bc1f7919e915feb9f963a Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 08:15:28 +0000 Subject: [PATCH 32/39] rephrase --- .../attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index ce2bef2cbc822..3cdf4f60f2e77 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -55,7 +55,7 @@ static void startAndWaitChild() throws Exception { "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), "-version").start(); - // Wait the process to enter VMStartCallback + // Wait until the process enters VMStartCallback child.getInputStream().read(); } From 206fd080abb8fdd034db4a3a05424496ba2bc9b0 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 08:58:26 +0000 Subject: [PATCH 33/39] close --- .../EarlyDynamicLoad/TestEarlyDynamicLoad.java | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index 3cdf4f60f2e77..2934b328ecade 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -30,6 +30,8 @@ import java.io.File; import java.io.InputStream; +import java.io.OutputStream; +import java.util.concurrent.TimeUnit; import java.util.Objects; import jdk.test.lib.dcmd.PidJcmdExecutor; import jdk.test.lib.process.OutputAnalyzer; @@ -56,13 +58,23 @@ static void startAndWaitChild() throws Exception { "-version").start(); // Wait until the process enters VMStartCallback - child.getInputStream().read(); + try (InputStream is = child.getInputStream()) { + is.read(); + } } @AfterAll static void stopChild() throws Exception { - child.destroy(); - child.waitFor(); + try (OutputStream os = child.getOutputStream()) { + os.write(0); + } + + if (!child.waitFor(5, TimeUnit.SECONDS)) { + throw new AssertionError("Timed out while waiting child process to complete"); + } + if (child.exitValue() != 0) { + throw new AssertionError("Expected child exit code to be 0, but was " + child.exitValue()); + } } @Test From a401f0a118785f600e70ca0099802ff05e967bc9 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 09:00:05 +0000 Subject: [PATCH 34/39] indent --- .../EarlyDynamicLoad/libEarlyDynamicLoad.cpp | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp index ffea42ae32e8e..93da6f6a9d344 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp @@ -28,25 +28,25 @@ extern "C" { static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { - putchar('1'); - fflush(stdout); - getchar(); + putchar('1'); + fflush(stdout); + getchar(); } JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { - jvmtiEnv* jvmti; - if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != 0) { - return 1; - } + jvmtiEnv* jvmti; + if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != 0) { + return 1; + } - jvmtiEventCallbacks callbacks; - memset(&callbacks, 0, sizeof(callbacks)); - callbacks.VMStart = VMStartCallback; + jvmtiEventCallbacks callbacks; + memset(&callbacks, 0, sizeof(callbacks)); + callbacks.VMStart = VMStartCallback; - jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); - jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr); + jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); + jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr); - return 0; + return 0; } } From 925f9fc828597f920e4b800d63428e414f8b0345 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 09:26:55 +0000 Subject: [PATCH 35/39] jvmti errors --- .../EarlyDynamicLoad/libEarlyDynamicLoad.cpp | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp index 93da6f6a9d344..3104648d8dee5 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp @@ -35,16 +35,23 @@ static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { jvmtiEnv* jvmti; - if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != 0) { - return 1; + if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != JVMTI_ERROR_NONE) { + fprintf(stderr, "JVMTI error occurred during GetEnv call\n"); + return 1; } jvmtiEventCallbacks callbacks; memset(&callbacks, 0, sizeof(callbacks)); callbacks.VMStart = VMStartCallback; - jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)); - jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr); + if (jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)) != JVMTI_ERROR_NONE) { + fprintf(stderr, "JVMTI error occurred during SetEventCallbacks call\n"); + return 1; + } + if (jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr) != JVMTI_ERROR_NONE) { + fprintf(stderr, "JVMTI error occurred during SetEventNotificationMode call\n"); + return 1; + } return 0; } From 60d6fdff670bcaabdcddebf520b5b9216d3b22bd Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 09:40:09 +0000 Subject: [PATCH 36/39] empty stderr --- .../EarlyDynamicLoad/TestEarlyDynamicLoad.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index 2934b328ecade..a2ed1fee3a993 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -53,9 +53,9 @@ public class TestEarlyDynamicLoad { @BeforeAll static void startAndWaitChild() throws Exception { child = ProcessTools.createTestJavaProcessBuilder( - "-XX:+StartAttachListener", - "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), - "-version").start(); + "-XX:+StartAttachListener", + "-agentpath:" + Utils.TEST_NATIVE_PATH + File.separator + System.mapLibraryName("EarlyDynamicLoad"), + "--version").start(); // Wait until the process enters VMStartCallback try (InputStream is = child.getInputStream()) { @@ -70,11 +70,13 @@ static void stopChild() throws Exception { } if (!child.waitFor(5, TimeUnit.SECONDS)) { + child.destroyForcibly(); throw new AssertionError("Timed out while waiting child process to complete"); } - if (child.exitValue() != 0) { - throw new AssertionError("Expected child exit code to be 0, but was " + child.exitValue()); - } + + OutputAnalyzer analyzer = new OutputAnalyzer(child); + analyzer.shouldHaveExitValue(0); + analyzer.stderrShouldBeEmpty(); } @Test From ba3dc02432150c8824abea112ccffdf550aa1e55 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Tue, 21 Oct 2025 09:42:57 +0000 Subject: [PATCH 37/39] cc --- .../attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java | 1 - .../attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java index a2ed1fee3a993..cd2281d96f5a6 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java @@ -32,7 +32,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.util.concurrent.TimeUnit; -import java.util.Objects; import jdk.test.lib.dcmd.PidJcmdExecutor; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp index 3104648d8dee5..7643690d530e3 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp @@ -36,7 +36,7 @@ static void JNICALL VMStartCallback(jvmtiEnv* jvmti, JNIEnv* env) { JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { jvmtiEnv* jvmti; if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != JVMTI_ERROR_NONE) { - fprintf(stderr, "JVMTI error occurred during GetEnv call\n"); + fprintf(stderr, "JVMTI error occurred during GetEnv\n"); return 1; } @@ -45,11 +45,11 @@ JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { callbacks.VMStart = VMStartCallback; if (jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)) != JVMTI_ERROR_NONE) { - fprintf(stderr, "JVMTI error occurred during SetEventCallbacks call\n"); + fprintf(stderr, "JVMTI error occurred during SetEventCallbacks\n"); return 1; } if (jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr) != JVMTI_ERROR_NONE) { - fprintf(stderr, "JVMTI error occurred during SetEventNotificationMode call\n"); + fprintf(stderr, "JVMTI error occurred during SetEventNotificationMode\n"); return 1; } From 205967939772764946e3df0e1633d6cec9e7d4a1 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Wed, 22 Oct 2025 08:28:36 +0000 Subject: [PATCH 38/39] return value --- .../attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp index 7643690d530e3..3991926306e4f 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/libEarlyDynamicLoad.cpp @@ -37,7 +37,7 @@ JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { jvmtiEnv* jvmti; if (vm->GetEnv((void**) &jvmti, JVMTI_VERSION_1_0) != JVMTI_ERROR_NONE) { fprintf(stderr, "JVMTI error occurred during GetEnv\n"); - return 1; + return JNI_ERR; } jvmtiEventCallbacks callbacks; @@ -46,14 +46,14 @@ JNIEXPORT int Agent_OnLoad(JavaVM* vm, char* options, void* reserved) { if (jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks)) != JVMTI_ERROR_NONE) { fprintf(stderr, "JVMTI error occurred during SetEventCallbacks\n"); - return 1; + return JNI_ERR; } if (jvmti->SetEventNotificationMode(JVMTI_ENABLE, JVMTI_EVENT_VM_START, nullptr) != JVMTI_ERROR_NONE) { fprintf(stderr, "JVMTI error occurred during SetEventNotificationMode\n"); - return 1; + return JNI_ERR; } - return 0; + return JNI_OK; } } From 1dafec32b57ac557b66dfe91c4bd2964019c9ff1 Mon Sep 17 00:00:00 2001 From: Francesco Andreuzzi Date: Wed, 22 Oct 2025 08:36:36 +0000 Subject: [PATCH 39/39] rename --- .../{TestEarlyDynamicLoad.java => EarlyDynamicLoad.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/{TestEarlyDynamicLoad.java => EarlyDynamicLoad.java} (97%) diff --git a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/EarlyDynamicLoad.java similarity index 97% rename from test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java rename to test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/EarlyDynamicLoad.java index cd2281d96f5a6..cb1596da08cc4 100644 --- a/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/TestEarlyDynamicLoad.java +++ b/test/hotspot/jtreg/serviceability/attach/EarlyDynamicLoad/EarlyDynamicLoad.java @@ -38,13 +38,13 @@ import jdk.test.lib.Utils; /* - * @test TestEarlyDynamicLoad + * @test EarlyDynamicLoad * @summary Test that dynamic attach fails gracefully when the JVM is not in live phase. * @requires vm.jvmti * @library /test/lib - * @run junit TestEarlyDynamicLoad + * @run junit EarlyDynamicLoad */ -public class TestEarlyDynamicLoad { +public class EarlyDynamicLoad { private static final String EXPECTED_MESSAGE = "Dynamic agent loading is only permitted in the live phase"; private static Process child;