diff --git a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java index cd54a6a2ff8..9e00978f250 100644 --- a/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/aix/classes/sun/tools/attach/VirtualMachineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2015, 2019 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -25,7 +25,6 @@ */ package sun.tools.attach; -import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.spi.AttachProvider; @@ -57,13 +56,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { super(provider, vmid); // This provider only understands pids - int pid; - try { - pid = Integer.parseInt(vmid); - if (pid < 1) { - throw new NumberFormatException(); - } - } catch (NumberFormatException x) { + int pid = Integer.parseInt(vmid); + if (pid < 1) { throw new AttachNotSupportedException("Invalid process identifier: " + vmid); } @@ -137,9 +131,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // protocol version private static final String PROTOCOL_VERSION = "1"; - // known errors - private static final int ATTACH_ERROR_BADVERSION = 101; - /** * Execute the given command in the target VM. */ @@ -185,46 +176,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // Create an input stream to read reply - SocketInputStream sis = new SocketInputStream(s); + SocketInputStreamImpl sis = new SocketInputStreamImpl(s); - // Read the command completion status - int completionStatus; - try { - completionStatus = readInt(sis); - } catch (IOException x) { - sis.close(); - if (ioe != null) { - throw ioe; - } else { - throw x; - } - } - - if (completionStatus != 0) { - // read from the stream and use that as the error message - String message = readErrorMessage(sis); - sis.close(); - - // In the event of a protocol mismatch then the target VM - // returns a known error so that we can throw a reasonable - // error. - if (completionStatus == ATTACH_ERROR_BADVERSION) { - throw new IOException("Protocol mismatch with target VM"); - } - - // Special-case the "load" command so that the right exception is - // thrown. - if (cmd.equals("load")) { - String msg = "Failed to load agent library"; - if (!message.isEmpty()) - msg += ": " + message; - throw new AgentLoadException(msg); - } else { - if (message.isEmpty()) - message = "Command failed in target VM"; - throw new AttachOperationFailedException(message); - } - } + // Process the command completion status + processCompletionStatus(ioe, cmd, sis); // Return the input stream so that the command output can be read return sis; @@ -233,39 +188,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { /* * InputStream for the socket connection to get target VM */ - private static class SocketInputStream extends InputStream { - int s; - - public SocketInputStream(int s) { - this.s = s; + private static class SocketInputStreamImpl extends SocketInputStream { + public SocketInputStreamImpl(long fd) { + super(fd); } - public synchronized int read() throws IOException { - byte b[] = new byte[1]; - int n = this.read(b, 0, 1); - if (n == 1) { - return b[0] & 0xff; - } else { - return -1; - } + @Override + protected int read(long fd, byte[] bs, int off, int len) throws IOException { + return VirtualMachineImpl.read((int)fd, bs, off, len); } - public synchronized int read(byte[] bs, int off, int len) throws IOException { - if ((off < 0) || (off > bs.length) || (len < 0) || - ((off + len) > bs.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) - return 0; - - return VirtualMachineImpl.read(s, bs, off, len); - } - - public synchronized void close() throws IOException { - if (s != -1) { - int toClose = s; - s = -1; - VirtualMachineImpl.close(toClose); - } + @Override + protected void close(long fd) throws IOException { + VirtualMachineImpl.close((int)fd); } } diff --git a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java index 7ac440d947d..324e52235cb 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -24,7 +24,6 @@ */ package sun.tools.attach; -import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.spi.AttachProvider; @@ -58,13 +57,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { super(provider, vmid); // This provider only understands pids - int pid; - try { - pid = Integer.parseInt(vmid); - if (pid < 1) { - throw new NumberFormatException(); - } - } catch (NumberFormatException x) { + int pid = Integer.parseInt(vmid); + if (pid < 1) { throw new AttachNotSupportedException("Invalid process identifier: " + vmid); } @@ -141,9 +135,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // protocol version private static final String PROTOCOL_VERSION = "1"; - // known errors - private static final int ATTACH_ERROR_BADVERSION = 101; - /** * Execute the given command in the target VM. */ @@ -189,46 +180,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // Create an input stream to read reply - SocketInputStream sis = new SocketInputStream(s); + SocketInputStreamImpl sis = new SocketInputStreamImpl(s); - // Read the command completion status - int completionStatus; - try { - completionStatus = readInt(sis); - } catch (IOException x) { - sis.close(); - if (ioe != null) { - throw ioe; - } else { - throw x; - } - } - - if (completionStatus != 0) { - // read from the stream and use that as the error message - String message = readErrorMessage(sis); - sis.close(); - - // In the event of a protocol mismatch then the target VM - // returns a known error so that we can throw a reasonable - // error. - if (completionStatus == ATTACH_ERROR_BADVERSION) { - throw new IOException("Protocol mismatch with target VM"); - } - - // Special-case the "load" command so that the right exception is - // thrown. - if (cmd.equals("load")) { - String msg = "Failed to load agent library"; - if (!message.isEmpty()) - msg += ": " + message; - throw new AgentLoadException(msg); - } else { - if (message.isEmpty()) - message = "Command failed in target VM"; - throw new AttachOperationFailedException(message); - } - } + // Process the command completion status + processCompletionStatus(ioe, cmd, sis); // Return the input stream so that the command output can be read return sis; @@ -237,40 +192,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { /* * InputStream for the socket connection to get target VM */ - private static class SocketInputStream extends InputStream { - int s = -1; - - public SocketInputStream(int s) { - this.s = s; + private static class SocketInputStreamImpl extends SocketInputStream { + public SocketInputStreamImpl(long fd) { + super(fd); } - public synchronized int read() throws IOException { - byte b[] = new byte[1]; - int n = this.read(b, 0, 1); - if (n == 1) { - return b[0] & 0xff; - } else { - return -1; - } + @Override + protected int read(long fd, byte[] bs, int off, int len) throws IOException { + return VirtualMachineImpl.read((int)fd, bs, off, len); } - public synchronized int read(byte[] bs, int off, int len) throws IOException { - if ((off < 0) || (off > bs.length) || (len < 0) || - ((off + len) > bs.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - - return VirtualMachineImpl.read(s, bs, off, len); - } - - public synchronized void close() throws IOException { - if (s != -1) { - int toClose = s; - s = -1; - VirtualMachineImpl.close(toClose); - } + @Override + protected void close(long fd) throws IOException { + VirtualMachineImpl.close((int)fd); } } diff --git a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java index 6d05e1158ef..7a3b79853e7 100644 --- a/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/macosx/classes/sun/tools/attach/VirtualMachineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -24,7 +24,6 @@ */ package sun.tools.attach; -import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.spi.AttachProvider; @@ -58,13 +57,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { super(provider, vmid); // This provider only understands pids - int pid; - try { - pid = Integer.parseInt(vmid); - if (pid < 1) { - throw new NumberFormatException(); - } - } catch (NumberFormatException x) { + int pid = Integer.parseInt(vmid); + if (pid < 1) { throw new AttachNotSupportedException("Invalid process identifier: " + vmid); } @@ -137,9 +131,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // protocol version private static final String PROTOCOL_VERSION = "1"; - // known errors - private static final int ATTACH_ERROR_BADVERSION = 101; - /** * Execute the given command in the target VM. */ @@ -185,46 +176,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { // Create an input stream to read reply - SocketInputStream sis = new SocketInputStream(s); + SocketInputStreamImpl sis = new SocketInputStreamImpl(s); - // Read the command completion status - int completionStatus; - try { - completionStatus = readInt(sis); - } catch (IOException x) { - sis.close(); - if (ioe != null) { - throw ioe; - } else { - throw x; - } - } - - if (completionStatus != 0) { - // read from the stream and use that as the error message - String message = readErrorMessage(sis); - sis.close(); - - // In the event of a protocol mismatch then the target VM - // returns a known error so that we can throw a reasonable - // error. - if (completionStatus == ATTACH_ERROR_BADVERSION) { - throw new IOException("Protocol mismatch with target VM"); - } - - // Special-case the "load" command so that the right exception is - // thrown. - if (cmd.equals("load")) { - String msg = "Failed to load agent library"; - if (!message.isEmpty()) - msg += ": " + message; - throw new AgentLoadException(msg); - } else { - if (message.isEmpty()) - message = "Command failed in target VM"; - throw new AttachOperationFailedException(message); - } - } + // Process the command completion status + processCompletionStatus(ioe, cmd, sis); // Return the input stream so that the command output can be read return sis; @@ -233,40 +188,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { /* * InputStream for the socket connection to get target VM */ - private static class SocketInputStream extends InputStream { - int s; - - public SocketInputStream(int s) { - this.s = s; + private static class SocketInputStreamImpl extends SocketInputStream { + public SocketInputStreamImpl(long fd) { + super(fd); } - public synchronized int read() throws IOException { - byte b[] = new byte[1]; - int n = this.read(b, 0, 1); - if (n == 1) { - return b[0] & 0xff; - } else { - return -1; - } + @Override + protected int read(long fd, byte[] bs, int off, int len) throws IOException { + return VirtualMachineImpl.read((int)fd, bs, off, len); } - public synchronized int read(byte[] bs, int off, int len) throws IOException { - if ((off < 0) || (off > bs.length) || (len < 0) || - ((off + len) > bs.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return 0; - } - - return VirtualMachineImpl.read(s, bs, off, len); - } - - public synchronized void close() throws IOException { - if (s != -1) { - int toClose = s; - s = -1; - VirtualMachineImpl.close(toClose); - } + @Override + protected void close(long fd) throws IOException { + VirtualMachineImpl.close((int)fd); } } diff --git a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java index 15a257eca42..409aa055082 100644 --- a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java +++ b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -25,6 +25,7 @@ package sun.tools.attach; +import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.AgentLoadException; @@ -70,7 +71,7 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { try { pid = Integer.parseInt(id); } catch (NumberFormatException e) { - throw new AttachNotSupportedException("Invalid process identifier"); + throw new AttachNotSupportedException("Invalid process identifier: " + id); } // The tool should be a different VM to the target. This check will @@ -183,6 +184,8 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { private static final int ATTACH_ERROR_NOTONCP = 101; private static final int ATTACH_ERROR_STARTFAIL = 102; + // known error + private static final int ATTACH_ERROR_BADVERSION = 101; /* * Send "properties" command to target VM @@ -366,6 +369,94 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { return message.toString(); } + /* + * Utility method to process the completion status after command execution. + * If we get IOE during previous command execution, delay throwing it until + * completion status has been read. + */ + void processCompletionStatus(IOException ioe, String cmd, InputStream sis) throws AgentLoadException, IOException { + // Read the command completion status + int completionStatus; + try { + completionStatus = readInt(sis); + } catch (IOException x) { + sis.close(); + if (ioe != null) { + throw ioe; + } else { + throw x; + } + } + if (completionStatus != 0) { + // read from the stream and use that as the error message + String message = readErrorMessage(sis); + sis.close(); + + // In the event of a protocol mismatch then the target VM + // returns a known error so that we can throw a reasonable + // error. + if (completionStatus == ATTACH_ERROR_BADVERSION) { + throw new IOException("Protocol mismatch with target VM"); + } + + // Special-case the "load" command so that the right exception is + // thrown. + if (cmd.equals("load")) { + String msg = "Failed to load agent library"; + if (!message.isEmpty()) { + msg += ": " + message; + } + throw new AgentLoadException(msg); + } else { + if (message.isEmpty()) { + message = "Command failed in target VM"; + } + throw new AttachOperationFailedException(message); + } + } + } + + /* + * InputStream for the socket connection to get target VM + */ + abstract static class SocketInputStream extends InputStream { + private long fd; + + public SocketInputStream(long fd) { + this.fd = fd; + } + + protected abstract int read(long fd, byte[] bs, int off, int len) throws IOException; + protected abstract void close(long fd) throws IOException; + + public synchronized int read() throws IOException { + byte b[] = new byte[1]; + int n = this.read(b, 0, 1); + if (n == 1) { + return b[0] & 0xff; + } else { + return -1; + } + } + + public synchronized int read(byte[] bs, int off, int len) throws IOException { + if ((off < 0) || (off > bs.length) || (len < 0) || + ((off + len) > bs.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return 0; + } + return read(fd, bs, off, len); + } + + public synchronized void close() throws IOException { + if (fd != -1) { + long toClose = fd; + fd = -1; + close(toClose); + } + } + } // -- attach timeout support diff --git a/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java index 1277e1fd123..f2241c209bb 100644 --- a/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/windows/classes/sun/tools/attach/VirtualMachineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2023, 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 @@ -24,7 +24,6 @@ */ package sun.tools.attach; -import com.sun.tools.attach.AttachOperationFailedException; import com.sun.tools.attach.AgentLoadException; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.spi.AttachProvider; @@ -33,6 +32,9 @@ import java.io.IOException; import java.io.InputStream; import java.util.Random; +/* + * Windows implementation of HotSpotVirtualMachine + */ public class VirtualMachineImpl extends HotSpotVirtualMachine { // the enqueue code stub (copied into each target VM) @@ -45,12 +47,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { { super(provider, id); - int pid; - try { - pid = Integer.parseInt(id); - } catch (NumberFormatException x) { - throw new AttachNotSupportedException("Invalid process identifier"); - } + int pid = Integer.parseInt(id); hProcess = openProcess(pid); // The target VM might be a pre-6.0 VM so we enqueue a "null" command @@ -108,26 +105,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { connectPipe(hPipe); // create an input stream for the pipe - PipedInputStream in = new PipedInputStream(hPipe); + SocketInputStreamImpl in = new SocketInputStreamImpl(hPipe); - // read completion status - int status = readInt(in); - if (status != 0) { - // read from the stream and use that as the error message - String message = readErrorMessage(in); - in.close(); - // special case the load command so that the right exception is thrown - if (cmd.equals("load")) { - String msg = "Failed to load agent library"; - if (!message.isEmpty()) - msg += ": " + message; - throw new AgentLoadException(msg); - } else { - if (message.isEmpty()) - message = "Command failed in target VM"; - throw new AttachOperationFailedException(message); - } - } + // Process the command completion status + processCompletionStatus(null, cmd, in); // return the input stream return in; @@ -139,40 +120,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { } // An InputStream based on a pipe to the target VM - private static class PipedInputStream extends InputStream { - - private long hPipe; - - public PipedInputStream(long hPipe) { - this.hPipe = hPipe; + private static class SocketInputStreamImpl extends SocketInputStream { + public SocketInputStreamImpl(long fd) { + super(fd); } - public synchronized int read() throws IOException { - byte b[] = new byte[1]; - int n = this.read(b, 0, 1); - if (n == 1) { - return b[0] & 0xff; - } else { - return -1; - } + @Override + protected int read(long fd, byte[] bs, int off, int len) throws IOException { + return VirtualMachineImpl.readPipe(fd, bs, off, len); } - public synchronized int read(byte[] bs, int off, int len) throws IOException { - if ((off < 0) || (off > bs.length) || (len < 0) || - ((off + len) > bs.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) - return 0; - - return VirtualMachineImpl.readPipe(hPipe, bs, off, len); - } - - public synchronized void close() throws IOException { - if (hPipe != -1) { - long toClose = hPipe; - hPipe = -1; - VirtualMachineImpl.closePipe(toClose); - } + @Override + protected void close(long fd) throws IOException { + VirtualMachineImpl.closePipe(fd); } }