Skip to content

Commit 5ebdf2d

Browse files
committedSep 3, 2024
8338708: Don't create/destroy debug agent cmdQueueLock for each connection
Reviewed-by: amenkov, lmesnik
1 parent 130ac13 commit 5ebdf2d

File tree

2 files changed

+130
-3
lines changed

2 files changed

+130
-3
lines changed
 

‎src/jdk.jdwp.agent/share/native/libjdwp/debugLoop.c

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -87,7 +87,9 @@ debugLoop_run(void)
8787
/* Initialize all statics */
8888
/* We may be starting a new connection after an error */
8989
cmdQueue = NULL;
90-
cmdQueueLock = debugMonitorCreate("JDWP Command Queue Lock");
90+
if (cmdQueueLock == NULL) {
91+
cmdQueueLock = debugMonitorCreate("JDWP Command Queue Lock");
92+
}
9193
transportError = JNI_FALSE;
9294

9395
shouldListen = JNI_TRUE;
@@ -190,7 +192,6 @@ debugLoop_run(void)
190192
* be trying to send.
191193
*/
192194
transport_close();
193-
debugMonitorDestroy(cmdQueueLock);
194195

195196
/* Reset for a new connection to this VM if it's still alive */
196197
if ( ! gdata->vmDead ) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
import java.io.IOException;
25+
import java.io.InputStream;
26+
import java.util.Map;
27+
28+
import jdk.test.lib.process.ProcessTools;
29+
30+
import com.sun.jdi.Bootstrap;
31+
import com.sun.jdi.VirtualMachine;
32+
import com.sun.jdi.connect.AttachingConnector;
33+
import com.sun.jdi.connect.Connector;
34+
import com.sun.jdi.connect.IllegalConnectorArgumentsException;
35+
36+
/**
37+
* @test
38+
* @bug 8338708
39+
* @summary Stress test for reattaching to a debuggee
40+
* @library /test/lib
41+
* @modules jdk.jdi
42+
* @run driver ProcessAttachTest
43+
*/
44+
45+
class ReattachStressTestTarg {
46+
public static void main(String args[]) throws Exception {
47+
System.out.println("Debuggee started");
48+
while (true) {
49+
try {
50+
Thread.sleep(100);
51+
} catch (InterruptedException e) {
52+
}
53+
}
54+
}
55+
}
56+
57+
public class ReattachStressTest {
58+
public static void main(String[] args) throws Exception {
59+
System.out.println("Test 1: Debuggee start with suspend=n");
60+
runTest("-agentlib:jdwp=transport=dt_socket,server=y,suspend=n");
61+
62+
System.out.println("Test 2: Debuggee start with suspend=y");
63+
runTest("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y");
64+
}
65+
66+
private static void runTest(String jdwpArg) throws Exception {
67+
ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(
68+
jdwpArg,
69+
"ReattachStressTestTarg");
70+
Process p = null;
71+
try {
72+
p = pb.start();
73+
74+
// Read the first character of output to make sure we've waited until the
75+
// debuggee is ready. This will be the debug agent's "Listening..." message.
76+
InputStream is = p.getInputStream();
77+
is.read();
78+
79+
// Attach a debugger
80+
tryDebug(p.pid(), is);
81+
} finally {
82+
p.destroyForcibly();
83+
}
84+
}
85+
86+
private static void tryDebug(long pid, InputStream is) throws IOException,
87+
IllegalConnectorArgumentsException {
88+
// Get the ProcessAttachingConnector, which can attach using the pid of the debuggee.
89+
AttachingConnector ac = Bootstrap.virtualMachineManager().attachingConnectors()
90+
.stream()
91+
.filter(c -> c.name().equals("com.sun.jdi.ProcessAttach"))
92+
.findFirst()
93+
.orElseThrow(() -> new RuntimeException("Unable to locate ProcessAttachingConnector"));
94+
95+
// Set the connector's "pid" argument to the pid of the debuggee.
96+
Map<String, Connector.Argument> args = ac.defaultArguments();
97+
Connector.StringArgument arg = (Connector.StringArgument)args.get("pid");
98+
arg.setValue("" + pid);
99+
100+
// Loop that will repeatedly attach and detach from the same debuggee.
101+
for (int i = 0; i < 500; i++) {
102+
System.out.println(i + ": Debugger is attaching to: " + pid + " ...");
103+
104+
// Attach to the debuggee.
105+
VirtualMachine vm = ac.attach(args);
106+
107+
// Drain remaining "Listening..." output. Otherwise too much
108+
// output will buffer up and the debuggee may block until it is cleared.
109+
while (is.available() > 0) {
110+
is.read();
111+
}
112+
113+
// We've attached. Do some things that will send JDWP commands.
114+
System.out.println("Attached!");
115+
System.out.println("JVM name: " + vm.name());
116+
System.out.println("Num threads: " + vm.allThreads().size());
117+
118+
// We're all done with this debugger connection.
119+
vm.dispose();
120+
121+
// Wait for first char of next "Listening..." output.
122+
is.read();
123+
}
124+
System.out.println("Debugger done.");
125+
}
126+
}

0 commit comments

Comments
 (0)
Please sign in to comment.