8299518: HotSpotVirtualMachine shared code across different platforms
Reviewed-by: cjplummer, dholmes
This commit is contained in:
parent
148900c2dc
commit
10d6a8e66a
@ -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.
|
* Copyright (c) 2015, 2019 SAP SE. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
@ -25,7 +25,6 @@
|
|||||||
*/
|
*/
|
||||||
package sun.tools.attach;
|
package sun.tools.attach;
|
||||||
|
|
||||||
import com.sun.tools.attach.AttachOperationFailedException;
|
|
||||||
import com.sun.tools.attach.AgentLoadException;
|
import com.sun.tools.attach.AgentLoadException;
|
||||||
import com.sun.tools.attach.AttachNotSupportedException;
|
import com.sun.tools.attach.AttachNotSupportedException;
|
||||||
import com.sun.tools.attach.spi.AttachProvider;
|
import com.sun.tools.attach.spi.AttachProvider;
|
||||||
@ -57,13 +56,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
super(provider, vmid);
|
super(provider, vmid);
|
||||||
|
|
||||||
// This provider only understands pids
|
// This provider only understands pids
|
||||||
int pid;
|
int pid = Integer.parseInt(vmid);
|
||||||
try {
|
if (pid < 1) {
|
||||||
pid = Integer.parseInt(vmid);
|
|
||||||
if (pid < 1) {
|
|
||||||
throw new NumberFormatException();
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException x) {
|
|
||||||
throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
|
throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +131,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
// protocol version
|
// protocol version
|
||||||
private static final String PROTOCOL_VERSION = "1";
|
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.
|
* Execute the given command in the target VM.
|
||||||
*/
|
*/
|
||||||
@ -185,46 +176,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
|
|
||||||
|
|
||||||
// Create an input stream to read reply
|
// Create an input stream to read reply
|
||||||
SocketInputStream sis = new SocketInputStream(s);
|
SocketInputStreamImpl sis = new SocketInputStreamImpl(s);
|
||||||
|
|
||||||
// Read the command completion status
|
// Process the command completion status
|
||||||
int completionStatus;
|
processCompletionStatus(ioe, cmd, sis);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the input stream so that the command output can be read
|
// Return the input stream so that the command output can be read
|
||||||
return sis;
|
return sis;
|
||||||
@ -233,39 +188,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
/*
|
/*
|
||||||
* InputStream for the socket connection to get target VM
|
* InputStream for the socket connection to get target VM
|
||||||
*/
|
*/
|
||||||
private static class SocketInputStream extends InputStream {
|
private static class SocketInputStreamImpl extends SocketInputStream {
|
||||||
int s;
|
public SocketInputStreamImpl(long fd) {
|
||||||
|
super(fd);
|
||||||
public SocketInputStream(int s) {
|
|
||||||
this.s = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read() throws IOException {
|
@Override
|
||||||
byte b[] = new byte[1];
|
protected int read(long fd, byte[] bs, int off, int len) throws IOException {
|
||||||
int n = this.read(b, 0, 1);
|
return VirtualMachineImpl.read((int)fd, bs, off, len);
|
||||||
if (n == 1) {
|
|
||||||
return b[0] & 0xff;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read(byte[] bs, int off, int len) throws IOException {
|
@Override
|
||||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
protected void close(long fd) throws IOException {
|
||||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
VirtualMachineImpl.close((int)fd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
package sun.tools.attach;
|
package sun.tools.attach;
|
||||||
|
|
||||||
import com.sun.tools.attach.AttachOperationFailedException;
|
|
||||||
import com.sun.tools.attach.AgentLoadException;
|
import com.sun.tools.attach.AgentLoadException;
|
||||||
import com.sun.tools.attach.AttachNotSupportedException;
|
import com.sun.tools.attach.AttachNotSupportedException;
|
||||||
import com.sun.tools.attach.spi.AttachProvider;
|
import com.sun.tools.attach.spi.AttachProvider;
|
||||||
@ -58,13 +57,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
super(provider, vmid);
|
super(provider, vmid);
|
||||||
|
|
||||||
// This provider only understands pids
|
// This provider only understands pids
|
||||||
int pid;
|
int pid = Integer.parseInt(vmid);
|
||||||
try {
|
if (pid < 1) {
|
||||||
pid = Integer.parseInt(vmid);
|
|
||||||
if (pid < 1) {
|
|
||||||
throw new NumberFormatException();
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException x) {
|
|
||||||
throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
|
throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,9 +135,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
// protocol version
|
// protocol version
|
||||||
private static final String PROTOCOL_VERSION = "1";
|
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.
|
* Execute the given command in the target VM.
|
||||||
*/
|
*/
|
||||||
@ -189,46 +180,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
|
|
||||||
|
|
||||||
// Create an input stream to read reply
|
// Create an input stream to read reply
|
||||||
SocketInputStream sis = new SocketInputStream(s);
|
SocketInputStreamImpl sis = new SocketInputStreamImpl(s);
|
||||||
|
|
||||||
// Read the command completion status
|
// Process the command completion status
|
||||||
int completionStatus;
|
processCompletionStatus(ioe, cmd, sis);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the input stream so that the command output can be read
|
// Return the input stream so that the command output can be read
|
||||||
return sis;
|
return sis;
|
||||||
@ -237,40 +192,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
/*
|
/*
|
||||||
* InputStream for the socket connection to get target VM
|
* InputStream for the socket connection to get target VM
|
||||||
*/
|
*/
|
||||||
private static class SocketInputStream extends InputStream {
|
private static class SocketInputStreamImpl extends SocketInputStream {
|
||||||
int s = -1;
|
public SocketInputStreamImpl(long fd) {
|
||||||
|
super(fd);
|
||||||
public SocketInputStream(int s) {
|
|
||||||
this.s = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read() throws IOException {
|
@Override
|
||||||
byte b[] = new byte[1];
|
protected int read(long fd, byte[] bs, int off, int len) throws IOException {
|
||||||
int n = this.read(b, 0, 1);
|
return VirtualMachineImpl.read((int)fd, bs, off, len);
|
||||||
if (n == 1) {
|
|
||||||
return b[0] & 0xff;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read(byte[] bs, int off, int len) throws IOException {
|
@Override
|
||||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
protected void close(long fd) throws IOException {
|
||||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
VirtualMachineImpl.close((int)fd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
package sun.tools.attach;
|
package sun.tools.attach;
|
||||||
|
|
||||||
import com.sun.tools.attach.AttachOperationFailedException;
|
|
||||||
import com.sun.tools.attach.AgentLoadException;
|
import com.sun.tools.attach.AgentLoadException;
|
||||||
import com.sun.tools.attach.AttachNotSupportedException;
|
import com.sun.tools.attach.AttachNotSupportedException;
|
||||||
import com.sun.tools.attach.spi.AttachProvider;
|
import com.sun.tools.attach.spi.AttachProvider;
|
||||||
@ -58,13 +57,8 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
super(provider, vmid);
|
super(provider, vmid);
|
||||||
|
|
||||||
// This provider only understands pids
|
// This provider only understands pids
|
||||||
int pid;
|
int pid = Integer.parseInt(vmid);
|
||||||
try {
|
if (pid < 1) {
|
||||||
pid = Integer.parseInt(vmid);
|
|
||||||
if (pid < 1) {
|
|
||||||
throw new NumberFormatException();
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException x) {
|
|
||||||
throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
|
throw new AttachNotSupportedException("Invalid process identifier: " + vmid);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,9 +131,6 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
// protocol version
|
// protocol version
|
||||||
private static final String PROTOCOL_VERSION = "1";
|
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.
|
* Execute the given command in the target VM.
|
||||||
*/
|
*/
|
||||||
@ -185,46 +176,10 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
|
|
||||||
|
|
||||||
// Create an input stream to read reply
|
// Create an input stream to read reply
|
||||||
SocketInputStream sis = new SocketInputStream(s);
|
SocketInputStreamImpl sis = new SocketInputStreamImpl(s);
|
||||||
|
|
||||||
// Read the command completion status
|
// Process the command completion status
|
||||||
int completionStatus;
|
processCompletionStatus(ioe, cmd, sis);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the input stream so that the command output can be read
|
// Return the input stream so that the command output can be read
|
||||||
return sis;
|
return sis;
|
||||||
@ -233,40 +188,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
/*
|
/*
|
||||||
* InputStream for the socket connection to get target VM
|
* InputStream for the socket connection to get target VM
|
||||||
*/
|
*/
|
||||||
private static class SocketInputStream extends InputStream {
|
private static class SocketInputStreamImpl extends SocketInputStream {
|
||||||
int s;
|
public SocketInputStreamImpl(long fd) {
|
||||||
|
super(fd);
|
||||||
public SocketInputStream(int s) {
|
|
||||||
this.s = s;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read() throws IOException {
|
@Override
|
||||||
byte b[] = new byte[1];
|
protected int read(long fd, byte[] bs, int off, int len) throws IOException {
|
||||||
int n = this.read(b, 0, 1);
|
return VirtualMachineImpl.read((int)fd, bs, off, len);
|
||||||
if (n == 1) {
|
|
||||||
return b[0] & 0xff;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read(byte[] bs, int off, int len) throws IOException {
|
@Override
|
||||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
protected void close(long fd) throws IOException {
|
||||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
VirtualMachineImpl.close((int)fd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
package sun.tools.attach;
|
package sun.tools.attach;
|
||||||
|
|
||||||
|
import com.sun.tools.attach.AttachOperationFailedException;
|
||||||
import com.sun.tools.attach.AttachNotSupportedException;
|
import com.sun.tools.attach.AttachNotSupportedException;
|
||||||
import com.sun.tools.attach.VirtualMachine;
|
import com.sun.tools.attach.VirtualMachine;
|
||||||
import com.sun.tools.attach.AgentLoadException;
|
import com.sun.tools.attach.AgentLoadException;
|
||||||
@ -70,7 +71,7 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine {
|
|||||||
try {
|
try {
|
||||||
pid = Integer.parseInt(id);
|
pid = Integer.parseInt(id);
|
||||||
} catch (NumberFormatException e) {
|
} 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
|
// 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_NOTONCP = 101;
|
||||||
private static final int ATTACH_ERROR_STARTFAIL = 102;
|
private static final int ATTACH_ERROR_STARTFAIL = 102;
|
||||||
|
|
||||||
|
// known error
|
||||||
|
private static final int ATTACH_ERROR_BADVERSION = 101;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send "properties" command to target VM
|
* Send "properties" command to target VM
|
||||||
@ -366,6 +369,94 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine {
|
|||||||
return message.toString();
|
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
|
// -- attach timeout support
|
||||||
|
|
||||||
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -24,7 +24,6 @@
|
|||||||
*/
|
*/
|
||||||
package sun.tools.attach;
|
package sun.tools.attach;
|
||||||
|
|
||||||
import com.sun.tools.attach.AttachOperationFailedException;
|
|
||||||
import com.sun.tools.attach.AgentLoadException;
|
import com.sun.tools.attach.AgentLoadException;
|
||||||
import com.sun.tools.attach.AttachNotSupportedException;
|
import com.sun.tools.attach.AttachNotSupportedException;
|
||||||
import com.sun.tools.attach.spi.AttachProvider;
|
import com.sun.tools.attach.spi.AttachProvider;
|
||||||
@ -33,6 +32,9 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Windows implementation of HotSpotVirtualMachine
|
||||||
|
*/
|
||||||
public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
||||||
|
|
||||||
// the enqueue code stub (copied into each target VM)
|
// the enqueue code stub (copied into each target VM)
|
||||||
@ -45,12 +47,7 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
{
|
{
|
||||||
super(provider, id);
|
super(provider, id);
|
||||||
|
|
||||||
int pid;
|
int pid = Integer.parseInt(id);
|
||||||
try {
|
|
||||||
pid = Integer.parseInt(id);
|
|
||||||
} catch (NumberFormatException x) {
|
|
||||||
throw new AttachNotSupportedException("Invalid process identifier");
|
|
||||||
}
|
|
||||||
hProcess = openProcess(pid);
|
hProcess = openProcess(pid);
|
||||||
|
|
||||||
// The target VM might be a pre-6.0 VM so we enqueue a "null" command
|
// 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);
|
connectPipe(hPipe);
|
||||||
|
|
||||||
// create an input stream for the pipe
|
// create an input stream for the pipe
|
||||||
PipedInputStream in = new PipedInputStream(hPipe);
|
SocketInputStreamImpl in = new SocketInputStreamImpl(hPipe);
|
||||||
|
|
||||||
// read completion status
|
// Process the command completion status
|
||||||
int status = readInt(in);
|
processCompletionStatus(null, cmd, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the input stream
|
// return the input stream
|
||||||
return in;
|
return in;
|
||||||
@ -139,40 +120,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// An InputStream based on a pipe to the target VM
|
// An InputStream based on a pipe to the target VM
|
||||||
private static class PipedInputStream extends InputStream {
|
private static class SocketInputStreamImpl extends SocketInputStream {
|
||||||
|
public SocketInputStreamImpl(long fd) {
|
||||||
private long hPipe;
|
super(fd);
|
||||||
|
|
||||||
public PipedInputStream(long hPipe) {
|
|
||||||
this.hPipe = hPipe;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read() throws IOException {
|
@Override
|
||||||
byte b[] = new byte[1];
|
protected int read(long fd, byte[] bs, int off, int len) throws IOException {
|
||||||
int n = this.read(b, 0, 1);
|
return VirtualMachineImpl.readPipe(fd, bs, off, len);
|
||||||
if (n == 1) {
|
|
||||||
return b[0] & 0xff;
|
|
||||||
} else {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized int read(byte[] bs, int off, int len) throws IOException {
|
@Override
|
||||||
if ((off < 0) || (off > bs.length) || (len < 0) ||
|
protected void close(long fd) throws IOException {
|
||||||
((off + len) > bs.length) || ((off + len) < 0)) {
|
VirtualMachineImpl.closePipe(fd);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user