8237388: serviceability/dcmd/framework/VMVersionTest.java fails with connection refused error.

Reviewed-by: cjplummer, sspitsyn
This commit is contained in:
Alex Menkov 2021-06-08 17:05:22 +00:00
parent c21cc932f0
commit b568e87947
5 changed files with 92 additions and 69 deletions

View File

@ -1,6 +1,6 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, 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
@ -61,13 +61,13 @@ public class TestProcessLauncher {
Binder binder = new Binder(argHandler, log);
binder.prepareForPipeConnection(argHandler);
pipe = IOPipe.startDebuggerPipe(binder);
String cmd = prepareLaunch(java, argHandler.getPipePort());
Debugee debuggee = binder.startLocalDebugee(cmd);
debuggee.redirectOutput(log);
pipe = new IOPipe(debuggee);
String line = pipe.readln();
if (!"ready".equals(line)) {
System.out.println("Wrong reply received:" + line);

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2019, 2021, 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
@ -48,7 +48,7 @@ public class TestJavaProcess {
log("Waiting for the quit command from the test ...");
String cmd = pipe.readln();
int exitCode = PASSED;
if (cmd.equals("quit")) {
if ("quit".equals(cmd)) {
log("'quit' received");
} else {
log("Invalid command received " + cmd);

View File

@ -24,6 +24,7 @@
package nsk.share.jpda;
import nsk.share.*;
import nsk.share.jdi.Binder;
/**
* This class implements communicational channel between
@ -42,8 +43,6 @@ public class IOPipe extends SocketIOPipe {
public static final String PIPE_LOG_PREFIX = "IOPipe> ";
private DebugeeProcess debugee;
/**
* Make <code>IOPipe</code> at debugee's side.
*
@ -61,7 +60,9 @@ public class IOPipe extends SocketIOPipe {
* Make <code>IOPipe</code> at debugger's side
* with given <code>Debugee</code> mirror.
*
* @deprecated Use Debugee.createIOPipe() instead.
* @deprecated Preferred way is to start IOPipe before launching debuggee process.
*
* @see #startDebuggerPipe
*/
@Deprecated
public IOPipe(DebugeeProcess debugee) {
@ -70,8 +71,7 @@ public class IOPipe extends SocketIOPipe {
debugee.getArgumentHandler().getPipePortNumber(),
(long)debugee.getArgumentHandler().getWaitTime() * 60 * 1000,
true);
this.debugee = debugee;
setServerSocket(debugee.getPipeServerSocket());
}
/**
@ -81,12 +81,22 @@ public class IOPipe extends SocketIOPipe {
super("IOPipe", log, PIPE_LOG_PREFIX, host, port, timeout, listening);
}
protected void connect() {
if (listening) {
setServerSocket(debugee.getPipeServerSocket());
setConnectingProcess(debugee.getProcess());
}
/**
* Creates and starts listening <code>IOPipe</code> at debugger side.
*/
public static IOPipe startDebuggerPipe(Binder binder) {
IOPipe ioPipe = new IOPipe(binder.getLog(),
binder.getArgumentHandler().getDebugeeHost(),
binder.getArgumentHandler().getPipePortNumber(),
(long)binder.getArgumentHandler().getWaitTime() * 60 * 1000,
true);
ioPipe.setServerSocket(binder.getPipeServerSocket());
ioPipe.startListening();
return ioPipe;
}
protected void connect() {
super.connect();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2001, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2001, 2021, 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
@ -53,8 +53,6 @@ class BasicSocketConnection {
protected OutputStream sout = null;
protected Process connectingProcess = null;
protected volatile boolean connected = false;
protected volatile boolean closed = false;
@ -257,11 +255,6 @@ class BasicSocketConnection {
} catch (ConnectException e) {
logger.display("Attempt #" + i + " to attach for " + name + " connection failed:\n\t" + e);
lastException = e;
// check if listening process still alive
if (!checkConnectingProcess()) {
shouldStop = true;
throw new Failure("Break attaching to " + name + " connection: " + "listening process exited");
}
// sleep between attempts
try {
Thread.sleep(DebugeeBinder.CONNECT_TRY_DELAY);
@ -310,31 +303,6 @@ class BasicSocketConnection {
return socket;
}
/**
* Return true if another connecting process is still alive.
*/
public boolean checkConnectingProcess() {
if (connectingProcess == null) {
// no process to check
return true;
}
try {
int exitCode = connectingProcess.exitValue();
} catch (IllegalThreadStateException e) {
// process is still alive
return true;
}
// process exited
return false;
}
/**
* Set another connecting process to control if it is still alive.
*/
public void setConnectingProcess(Process process) {
connectingProcess = process;
}
/**
* Check if connection is established.
*/

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2021, 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
@ -79,8 +79,6 @@ public class SocketIOPipe extends Log.Logger implements Finalizable {
protected volatile boolean shouldStop;
protected Process connectingProcess;
protected ServerSocket serverSocket;
protected String name;
@ -160,10 +158,6 @@ public class SocketIOPipe extends Log.Logger implements Finalizable {
return port;
}
protected void setConnectingProcess(Process connectingProcess) {
this.connectingProcess = connectingProcess;
}
protected void setServerSocket(ServerSocket serverSocket) {
this.serverSocket = serverSocket;
if (serverSocket != null)
@ -207,6 +201,63 @@ public class SocketIOPipe extends Log.Logger implements Finalizable {
}
}
protected class ListenerThread extends Thread {
private SocketConnection connection;
private RuntimeException error;
ListenerThread() {
super("PipeIO Listener Thread");
setDaemon(true);
connection = new SocketConnection(SocketIOPipe.this, getName());
if (serverSocket == null) {
connection.bind(port, timeout);
} else {
connection.setServerSocket(serverSocket);
}
}
@Override
public void run() {
synchronized (this) {
try {
connection.accept(timeout);
} catch (Throwable th) {
error = th instanceof RuntimeException
? (RuntimeException)th
: new RuntimeException(th);
}
notifyAll();
}
}
public SocketConnection getConnection() {
synchronized (this) {
while (!connection.isConnected() && error != null) {
try {
wait();
} catch (InterruptedException e) {
}
}
if (error != null) {
throw error;
}
return connection;
}
}
}
private ListenerThread listenerThread;
protected void startListening() {
if (listenerThread != null) {
throw new TestBug("already listening");
}
listenerThread = new ListenerThread();
listenerThread.start();
}
/**
* Establish <code>IOPipe</code> connection by attaching or accepting
* connection appropriately.
@ -219,23 +270,17 @@ public class SocketIOPipe extends Log.Logger implements Finalizable {
if (shouldStop)
return;
connection = new SocketConnection(this, getName());
if (listening) {
connection.setConnectingProcess(connectingProcess);
if (serverSocket == null) {
connection.bind(port, timeout);
} else {
connection.setServerSocket(serverSocket);
// listenerThread == null means the test is not updated yet
// to start IOPipe listening before launching debuggee.
if (listenerThread == null) {
// start listening and accept connection on the current thread
listenerThread = new ListenerThread();
listenerThread.run();
}
if (shouldStop)
return;
// wait for connection from remote host
connection.accept(timeout);
connection = listenerThread.getConnection();
} else {
connection = new SocketConnection(this, getName());
// attach from the debuggee's side
connection.continueAttach(host, port, timeout);
}