feat(jdk8): move files to new folder to avoid resources compiled.
This commit is contained in:
273
jdkSrc/jdk8/com/sun/tools/jdi/AbstractLauncher.java
Normal file
273
jdkSrc/jdk8/com/sun/tools/jdi/AbstractLauncher.java
Normal file
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.tools.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
|
||||
abstract class AbstractLauncher extends ConnectorImpl implements LaunchingConnector {
|
||||
|
||||
abstract public VirtualMachine
|
||||
launch(Map<String,? extends Connector.Argument> arguments)
|
||||
throws IOException,
|
||||
IllegalConnectorArgumentsException,
|
||||
VMStartException;
|
||||
abstract public String name();
|
||||
abstract public String description();
|
||||
|
||||
ThreadGroup grp;
|
||||
|
||||
AbstractLauncher() {
|
||||
super();
|
||||
|
||||
grp = Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup parent = null;
|
||||
while ((parent = grp.getParent()) != null) {
|
||||
grp = parent;
|
||||
}
|
||||
}
|
||||
|
||||
String[] tokenizeCommand(String command, char quote) {
|
||||
String quoteStr = String.valueOf(quote); // easier to deal with
|
||||
|
||||
/*
|
||||
* Tokenize the command, respecting the given quote character.
|
||||
*/
|
||||
StringTokenizer tokenizer = new StringTokenizer(command,
|
||||
quote + " \t\r\n\f",
|
||||
true);
|
||||
String quoted = null;
|
||||
String pending = null;
|
||||
List<String> tokenList = new ArrayList<String>();
|
||||
while (tokenizer.hasMoreTokens()) {
|
||||
String token = tokenizer.nextToken();
|
||||
if (quoted != null) {
|
||||
if (token.equals(quoteStr)) {
|
||||
tokenList.add(quoted);
|
||||
quoted = null;
|
||||
} else {
|
||||
quoted += token;
|
||||
}
|
||||
} else if (pending != null) {
|
||||
if (token.equals(quoteStr)) {
|
||||
quoted = pending;
|
||||
} else if ((token.length() == 1) &&
|
||||
Character.isWhitespace(token.charAt(0))) {
|
||||
tokenList.add(pending);
|
||||
} else {
|
||||
throw new InternalException("Unexpected token: " + token);
|
||||
}
|
||||
pending = null;
|
||||
} else {
|
||||
if (token.equals(quoteStr)) {
|
||||
quoted = "";
|
||||
} else if ((token.length() == 1) &&
|
||||
Character.isWhitespace(token.charAt(0))) {
|
||||
// continue
|
||||
} else {
|
||||
pending = token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add final token.
|
||||
*/
|
||||
if (pending != null) {
|
||||
tokenList.add(pending);
|
||||
}
|
||||
|
||||
/*
|
||||
* An unclosed quote at the end of the command. Do an
|
||||
* implicit end quote.
|
||||
*/
|
||||
if (quoted != null) {
|
||||
tokenList.add(quoted);
|
||||
}
|
||||
|
||||
String[] tokenArray = new String[tokenList.size()];
|
||||
for (int i = 0; i < tokenList.size(); i++) {
|
||||
tokenArray[i] = tokenList.get(i);
|
||||
}
|
||||
return tokenArray;
|
||||
}
|
||||
|
||||
protected VirtualMachine launch(String[] commandArray, String address,
|
||||
TransportService.ListenKey listenKey,
|
||||
TransportService ts)
|
||||
throws IOException, VMStartException {
|
||||
Helper helper = new Helper(commandArray, address, listenKey, ts);
|
||||
helper.launchAndAccept();
|
||||
|
||||
VirtualMachineManager manager =
|
||||
Bootstrap.virtualMachineManager();
|
||||
|
||||
return manager.createVirtualMachine(helper.connection(),
|
||||
helper.process());
|
||||
}
|
||||
|
||||
/**
|
||||
* This class simply provides a context for a single launch and
|
||||
* accept. It provides instance fields that can be used by
|
||||
* all threads involved. This stuff can't be in the Connector proper
|
||||
* because the connector is a singleton and is not specific to any
|
||||
* one launch.
|
||||
*/
|
||||
private class Helper {
|
||||
private final String address;
|
||||
private TransportService.ListenKey listenKey;
|
||||
private TransportService ts;
|
||||
private final String[] commandArray;
|
||||
private Process process = null;
|
||||
private Connection connection = null;
|
||||
private IOException acceptException = null;
|
||||
private boolean exited = false;
|
||||
|
||||
Helper(String[] commandArray, String address, TransportService.ListenKey listenKey,
|
||||
TransportService ts) {
|
||||
this.commandArray = commandArray;
|
||||
this.address = address;
|
||||
this.listenKey = listenKey;
|
||||
this.ts = ts;
|
||||
}
|
||||
|
||||
String commandString() {
|
||||
String str = "";
|
||||
for (int i = 0; i < commandArray.length; i++) {
|
||||
if (i > 0) {
|
||||
str += " ";
|
||||
}
|
||||
str += commandArray[i];
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
synchronized void launchAndAccept() throws
|
||||
IOException, VMStartException {
|
||||
|
||||
process = Runtime.getRuntime().exec(commandArray);
|
||||
|
||||
Thread acceptingThread = acceptConnection();
|
||||
Thread monitoringThread = monitorTarget();
|
||||
try {
|
||||
while ((connection == null) &&
|
||||
(acceptException == null) &&
|
||||
!exited) {
|
||||
wait();
|
||||
}
|
||||
|
||||
if (exited) {
|
||||
throw new VMStartException(
|
||||
"VM initialization failed for: " + commandString(), process);
|
||||
}
|
||||
if (acceptException != null) {
|
||||
// Rethrow the exception in this thread
|
||||
throw acceptException;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
throw new InterruptedIOException("Interrupted during accept");
|
||||
} finally {
|
||||
acceptingThread.interrupt();
|
||||
monitoringThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
Process process() {
|
||||
return process;
|
||||
}
|
||||
|
||||
Connection connection() {
|
||||
return connection;
|
||||
}
|
||||
|
||||
synchronized void notifyOfExit() {
|
||||
exited = true;
|
||||
notify();
|
||||
}
|
||||
|
||||
synchronized void notifyOfConnection(Connection connection) {
|
||||
this.connection = connection;
|
||||
notify();
|
||||
}
|
||||
|
||||
synchronized void notifyOfAcceptException(IOException acceptException) {
|
||||
this.acceptException = acceptException;
|
||||
notify();
|
||||
}
|
||||
|
||||
Thread monitorTarget() {
|
||||
Thread thread = new Thread(grp,
|
||||
"launched target monitor") {
|
||||
public void run() {
|
||||
try {
|
||||
process.waitFor();
|
||||
/*
|
||||
* Notify waiting thread of VM error termination
|
||||
*/
|
||||
notifyOfExit();
|
||||
} catch (InterruptedException e) {
|
||||
// Connection has been established, stop monitoring
|
||||
}
|
||||
}
|
||||
};
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
return thread;
|
||||
}
|
||||
|
||||
Thread acceptConnection() {
|
||||
Thread thread = new Thread(grp,
|
||||
"connection acceptor") {
|
||||
public void run() {
|
||||
try {
|
||||
Connection connection = ts.accept(listenKey, 0, 0);
|
||||
/*
|
||||
* Notify waiting thread of connection
|
||||
*/
|
||||
notifyOfConnection(connection);
|
||||
} catch (InterruptedIOException e) {
|
||||
// VM terminated, stop accepting
|
||||
} catch (IOException e) {
|
||||
// Report any other exception to waiting thread
|
||||
notifyOfAcceptException(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
}
|
||||
283
jdkSrc/jdk8/com/sun/tools/jdi/ArrayReferenceImpl.java
Normal file
283
jdkSrc/jdk8/com/sun/tools/jdi/ArrayReferenceImpl.java
Normal file
@@ -0,0 +1,283 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
|
||||
public class ArrayReferenceImpl extends ObjectReferenceImpl
|
||||
implements ArrayReference
|
||||
{
|
||||
int length = -1;
|
||||
|
||||
ArrayReferenceImpl(VirtualMachine aVm,long aRef) {
|
||||
super(aVm,aRef);
|
||||
}
|
||||
|
||||
protected ClassTypeImpl invokableReferenceType(Method method) {
|
||||
// The method has to be a method on Object since
|
||||
// arrays don't have methods nor any other 'superclasses'
|
||||
// So, use the ClassTypeImpl for Object instead of
|
||||
// the ArrayTypeImpl for the array itself.
|
||||
return (ClassTypeImpl)method.declaringType();
|
||||
}
|
||||
|
||||
ArrayTypeImpl arrayType() {
|
||||
return (ArrayTypeImpl)type();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return array length.
|
||||
* Need not be synchronized since it cannot be provably stale.
|
||||
*/
|
||||
public int length() {
|
||||
if(length == -1) {
|
||||
try {
|
||||
length = JDWP.ArrayReference.Length.
|
||||
process(vm, this).arrayLength;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
public Value getValue(int index) {
|
||||
List<Value> list = getValues(index, 1);
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
public List<Value> getValues() {
|
||||
return getValues(0, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate that the range to set/get is valid.
|
||||
* length of -1 (meaning rest of array) has been converted
|
||||
* before entry.
|
||||
*/
|
||||
private void validateArrayAccess(int index, int length) {
|
||||
// because length can be computed from index,
|
||||
// index must be tested first for correct error message
|
||||
if ((index < 0) || (index > length())) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid array index: " + index);
|
||||
}
|
||||
if (length < 0) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid array range length: " + length);
|
||||
}
|
||||
if (index + length > length()) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid array range: " +
|
||||
index + " to " + (index + length - 1));
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private static <T> T cast(Object x) {
|
||||
return (T)x;
|
||||
}
|
||||
|
||||
public List<Value> getValues(int index, int length) {
|
||||
if (length == -1) { // -1 means the rest of the array
|
||||
length = length() - index;
|
||||
}
|
||||
validateArrayAccess(index, length);
|
||||
if (length == 0) {
|
||||
return new ArrayList<Value>();
|
||||
}
|
||||
|
||||
List<Value> vals;
|
||||
try {
|
||||
vals = cast(JDWP.ArrayReference.GetValues.process(vm, this, index, length).values);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
|
||||
return vals;
|
||||
}
|
||||
|
||||
public void setValue(int index, Value value)
|
||||
throws InvalidTypeException,
|
||||
ClassNotLoadedException {
|
||||
List<Value> list = new ArrayList<Value>(1);
|
||||
list.add(value);
|
||||
setValues(index, list, 0, 1);
|
||||
}
|
||||
|
||||
public void setValues(List<? extends Value> values)
|
||||
throws InvalidTypeException,
|
||||
ClassNotLoadedException {
|
||||
setValues(0, values, 0, -1);
|
||||
}
|
||||
|
||||
public void setValues(int index, List<? extends Value> values,
|
||||
int srcIndex, int length)
|
||||
throws InvalidTypeException,
|
||||
ClassNotLoadedException {
|
||||
|
||||
if (length == -1) { // -1 means the rest of the array
|
||||
// shorter of, the rest of the array and rest of
|
||||
// the source values
|
||||
length = Math.min(length() - index,
|
||||
values.size() - srcIndex);
|
||||
}
|
||||
validateMirrorsOrNulls(values);
|
||||
validateArrayAccess(index, length);
|
||||
|
||||
if ((srcIndex < 0) || (srcIndex > values.size())) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid source index: " + srcIndex);
|
||||
}
|
||||
if (srcIndex + length > values.size()) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"Invalid source range: " +
|
||||
srcIndex + " to " +
|
||||
(srcIndex + length - 1));
|
||||
}
|
||||
|
||||
boolean somethingToSet = false;;
|
||||
ValueImpl[] setValues = new ValueImpl[length];
|
||||
|
||||
for (int i = 0; i < length; i++) {
|
||||
ValueImpl value = (ValueImpl)values.get(srcIndex + i);
|
||||
|
||||
try {
|
||||
// Validate and convert if necessary
|
||||
setValues[i] =
|
||||
ValueImpl.prepareForAssignment(value,
|
||||
new Component());
|
||||
somethingToSet = true;
|
||||
} catch (ClassNotLoadedException e) {
|
||||
/*
|
||||
* Since we got this exception,
|
||||
* the component must be a reference type.
|
||||
* This means the class has not yet been loaded
|
||||
* through the defining class's class loader.
|
||||
* If the value we're trying to set is null,
|
||||
* then setting to null is essentially a
|
||||
* no-op, and we should allow it without an
|
||||
* exception.
|
||||
*/
|
||||
if (value != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (somethingToSet) {
|
||||
try {
|
||||
JDWP.ArrayReference.SetValues.
|
||||
process(vm, this, index, setValues);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "instance of " + arrayType().componentTypeName() +
|
||||
"[" + length() + "] (id=" + uniqueID() + ")";
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.ARRAY;
|
||||
}
|
||||
|
||||
void validateAssignment(ValueContainer destination)
|
||||
throws InvalidTypeException, ClassNotLoadedException {
|
||||
try {
|
||||
super.validateAssignment(destination);
|
||||
} catch (ClassNotLoadedException e) {
|
||||
/*
|
||||
* An array can be used extensively without the
|
||||
* enclosing loader being recorded by the VM as an
|
||||
* initiating loader of the array type. In addition, the
|
||||
* load of an array class is fairly harmless as long as
|
||||
* the component class is already loaded. So we relax the
|
||||
* rules a bit and allow the assignment as long as the
|
||||
* ultimate component types are assignable.
|
||||
*/
|
||||
boolean valid = false;
|
||||
JNITypeParser destParser = new JNITypeParser(
|
||||
destination.signature());
|
||||
JNITypeParser srcParser = new JNITypeParser(
|
||||
arrayType().signature());
|
||||
int destDims = destParser.dimensionCount();
|
||||
if (destDims <= srcParser.dimensionCount()) {
|
||||
/*
|
||||
* Remove all dimensions from the destination. Remove
|
||||
* the same number of dimensions from the source.
|
||||
* Get types for both and check to see if they are
|
||||
* compatible.
|
||||
*/
|
||||
String destComponentSignature =
|
||||
destParser.componentSignature(destDims);
|
||||
Type destComponentType =
|
||||
destination.findType(destComponentSignature);
|
||||
String srcComponentSignature =
|
||||
srcParser.componentSignature(destDims);
|
||||
Type srcComponentType =
|
||||
arrayType().findComponentType(srcComponentSignature);
|
||||
valid = ArrayTypeImpl.isComponentAssignable(destComponentType,
|
||||
srcComponentType);
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
throw new InvalidTypeException("Cannot assign " +
|
||||
arrayType().name() +
|
||||
" to " +
|
||||
destination.typeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Represents an array component to other internal parts of this
|
||||
* implementation. This is not exposed at the JDI level. Currently,
|
||||
* this class is needed only for type checking so it does not even
|
||||
* reference a particular component - just a generic component
|
||||
* of this array. In the future we may need to expand its use.
|
||||
*/
|
||||
class Component implements ValueContainer {
|
||||
public Type type() throws ClassNotLoadedException {
|
||||
return arrayType().componentType();
|
||||
}
|
||||
public String typeName() {
|
||||
return arrayType().componentTypeName();
|
||||
}
|
||||
public String signature() {
|
||||
return arrayType().componentSignature();
|
||||
}
|
||||
public Type findType(String signature) throws ClassNotLoadedException {
|
||||
return arrayType().findComponentType(signature);
|
||||
}
|
||||
}
|
||||
}
|
||||
208
jdkSrc/jdk8/com/sun/tools/jdi/ArrayTypeImpl.java
Normal file
208
jdkSrc/jdk8/com/sun/tools/jdi/ArrayTypeImpl.java
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
public class ArrayTypeImpl extends ReferenceTypeImpl
|
||||
implements ArrayType
|
||||
{
|
||||
protected ArrayTypeImpl(VirtualMachine aVm, long aRef) {
|
||||
super(aVm, aRef);
|
||||
}
|
||||
|
||||
public ArrayReference newInstance(int length) {
|
||||
try {
|
||||
return (ArrayReference)JDWP.ArrayType.NewInstance.
|
||||
process(vm, this, length).newArray;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
public String componentSignature() {
|
||||
return signature().substring(1); // Just skip the leading '['
|
||||
}
|
||||
|
||||
public String componentTypeName() {
|
||||
JNITypeParser parser = new JNITypeParser(componentSignature());
|
||||
return parser.typeName();
|
||||
}
|
||||
|
||||
Type type() throws ClassNotLoadedException {
|
||||
return findType(componentSignature());
|
||||
}
|
||||
|
||||
@Override
|
||||
void addVisibleMethods(Map<String, Method> map, Set<InterfaceType> seenInterfaces) {
|
||||
// arrays don't have methods
|
||||
}
|
||||
|
||||
public List<Method> allMethods() {
|
||||
return new ArrayList<Method>(0); // arrays don't have methods
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the type object, if any, of a component type of this array.
|
||||
* The component type does not have to be immediate; e.g. this method
|
||||
* can be used to find the component Foo of Foo[][]. This method takes
|
||||
* advantage of the property that an array and its component must have
|
||||
* the same class loader. Since array set operations don't have an
|
||||
* implicit enclosing type like field and variable set operations,
|
||||
* this method is sometimes needed for proper type checking.
|
||||
*/
|
||||
Type findComponentType(String signature) throws ClassNotLoadedException {
|
||||
byte tag = (byte)signature.charAt(0);
|
||||
if (PacketStream.isObjectTag(tag)) {
|
||||
// It's a reference type
|
||||
JNITypeParser parser = new JNITypeParser(componentSignature());
|
||||
List<ReferenceType> list = vm.classesByName(parser.typeName());
|
||||
Iterator<ReferenceType> iter = list.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ReferenceType type = iter.next();
|
||||
ClassLoaderReference cl = type.classLoader();
|
||||
if ((cl == null)?
|
||||
(classLoader() == null) :
|
||||
(cl.equals(classLoader()))) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
// Component class has not yet been loaded
|
||||
throw new ClassNotLoadedException(componentTypeName());
|
||||
} else {
|
||||
// It's a primitive type
|
||||
return vm.primitiveTypeMirror(tag);
|
||||
}
|
||||
}
|
||||
|
||||
public Type componentType() throws ClassNotLoadedException {
|
||||
return findComponentType(componentSignature());
|
||||
}
|
||||
|
||||
static boolean isComponentAssignable(Type destination, Type source) {
|
||||
if (source instanceof PrimitiveType) {
|
||||
// Assignment of primitive arrays requires identical
|
||||
// component types.
|
||||
return source.equals(destination);
|
||||
} else {
|
||||
if (destination instanceof PrimitiveType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ReferenceTypeImpl refSource = (ReferenceTypeImpl)source;
|
||||
ReferenceTypeImpl refDestination = (ReferenceTypeImpl)destination;
|
||||
// Assignment of object arrays requires availability
|
||||
// of widening conversion of component types
|
||||
return refSource.isAssignableTo(refDestination);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return true if an instance of the given reference type
|
||||
* can be assigned to a variable of this type
|
||||
*/
|
||||
boolean isAssignableTo(ReferenceType destType) {
|
||||
if (destType instanceof ArrayType) {
|
||||
try {
|
||||
Type destComponentType = ((ArrayType)destType).componentType();
|
||||
return isComponentAssignable(destComponentType, componentType());
|
||||
} catch (ClassNotLoadedException e) {
|
||||
// One or both component types has not yet been
|
||||
// loaded => can't assign
|
||||
return false;
|
||||
}
|
||||
} else if (destType instanceof InterfaceType) {
|
||||
// Only valid InterfaceType assignee is Cloneable
|
||||
return destType.name().equals("java.lang.Cloneable");
|
||||
} else {
|
||||
// Only valid ClassType assignee is Object
|
||||
return destType.name().equals("java.lang.Object");
|
||||
}
|
||||
}
|
||||
|
||||
List<ReferenceType> inheritedTypes() {
|
||||
return new ArrayList<ReferenceType>(0);
|
||||
}
|
||||
|
||||
void getModifiers() {
|
||||
if (modifiers != -1) {
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* For object arrays, the return values for Interface
|
||||
* Accessible.isPrivate(), Accessible.isProtected(),
|
||||
* etc... are the same as would be returned for the
|
||||
* component type. Fetch the modifier bits from the
|
||||
* component type and use those.
|
||||
*
|
||||
* For primitive arrays, the modifiers are always
|
||||
* VMModifiers.FINAL | VMModifiers.PUBLIC
|
||||
*
|
||||
* Reference com.sun.jdi.Accessible.java.
|
||||
*/
|
||||
try {
|
||||
Type t = componentType();
|
||||
if (t instanceof PrimitiveType) {
|
||||
modifiers = VMModifiers.FINAL | VMModifiers.PUBLIC;
|
||||
} else {
|
||||
ReferenceType rt = (ReferenceType)t;
|
||||
modifiers = rt.modifiers();
|
||||
}
|
||||
} catch (ClassNotLoadedException cnle) {
|
||||
cnle.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "array class " + name() + " (" + loaderString() + ")";
|
||||
}
|
||||
|
||||
/*
|
||||
* Save a pointless trip over the wire for these methods
|
||||
* which have undefined results for arrays.
|
||||
*/
|
||||
public boolean isPrepared() { return true; }
|
||||
public boolean isVerified() { return true; }
|
||||
public boolean isInitialized() { return true; }
|
||||
public boolean failedToInitialize() { return false; }
|
||||
public boolean isAbstract() { return false; }
|
||||
|
||||
/*
|
||||
* Defined always to be true for arrays
|
||||
*/
|
||||
public boolean isFinal() { return true; }
|
||||
|
||||
/*
|
||||
* Defined always to be false for arrays
|
||||
*/
|
||||
public boolean isStatic() { return false; }
|
||||
}
|
||||
57
jdkSrc/jdk8/com/sun/tools/jdi/BaseLineInfo.java
Normal file
57
jdkSrc/jdk8/com/sun/tools/jdi/BaseLineInfo.java
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
class BaseLineInfo implements LineInfo {
|
||||
private final int lineNumber;
|
||||
private final ReferenceTypeImpl declaringType;
|
||||
|
||||
BaseLineInfo(int lineNumber,
|
||||
ReferenceTypeImpl declaringType) {
|
||||
this.lineNumber = lineNumber;
|
||||
this.declaringType = declaringType;
|
||||
}
|
||||
|
||||
public String liStratum() {
|
||||
return SDE.BASE_STRATUM_NAME;
|
||||
}
|
||||
|
||||
public int liLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public String liSourceName()
|
||||
throws AbsentInformationException {
|
||||
return declaringType.baseSourceName();
|
||||
}
|
||||
|
||||
public String liSourcePath()
|
||||
throws AbsentInformationException {
|
||||
return declaringType.baseSourcePath();
|
||||
}
|
||||
}
|
||||
42
jdkSrc/jdk8/com/sun/tools/jdi/BooleanTypeImpl.java
Normal file
42
jdkSrc/jdk8/com/sun/tools/jdi/BooleanTypeImpl.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class BooleanTypeImpl extends PrimitiveTypeImpl implements BooleanType {
|
||||
BooleanTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.BOOLEAN);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedBooleanValue());
|
||||
}
|
||||
}
|
||||
103
jdkSrc/jdk8/com/sun/tools/jdi/BooleanValueImpl.java
Normal file
103
jdkSrc/jdk8/com/sun/tools/jdi/BooleanValueImpl.java
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class BooleanValueImpl extends PrimitiveValueImpl
|
||||
implements BooleanValue {
|
||||
private boolean value;
|
||||
|
||||
BooleanValueImpl(VirtualMachine aVm,boolean aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof BooleanValue)) {
|
||||
return (value == ((BooleanValue)obj).value())
|
||||
&& super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theBooleanType();
|
||||
}
|
||||
|
||||
public boolean value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)((value)?1:0);
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)((value)?1:0);
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)((value)?1:0);
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return (value)?1:0;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)((value)?1:0);
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)((value)?1.0:0.0);
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return (value)?1.0:0.0;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.BOOLEAN;
|
||||
}
|
||||
}
|
||||
43
jdkSrc/jdk8/com/sun/tools/jdi/ByteTypeImpl.java
Normal file
43
jdkSrc/jdk8/com/sun/tools/jdi/ByteTypeImpl.java
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class ByteTypeImpl extends PrimitiveTypeImpl implements ByteType {
|
||||
ByteTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.BYTE);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedByteValue());
|
||||
}
|
||||
}
|
||||
117
jdkSrc/jdk8/com/sun/tools/jdi/ByteValueImpl.java
Normal file
117
jdkSrc/jdk8/com/sun/tools/jdi/ByteValueImpl.java
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class ByteValueImpl extends PrimitiveValueImpl
|
||||
implements ByteValue {
|
||||
private byte value;
|
||||
|
||||
ByteValueImpl(VirtualMachine aVm,byte aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof ByteValue)) {
|
||||
return (value == ((ByteValue)obj).value())
|
||||
&& super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public int compareTo(ByteValue obj) {
|
||||
byte other = obj.value();
|
||||
return value() - other;
|
||||
}
|
||||
|
||||
|
||||
public Type type() {
|
||||
return vm.theByteType();
|
||||
}
|
||||
|
||||
public byte value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return(int)value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return(double)value;
|
||||
}
|
||||
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to char");
|
||||
} else {
|
||||
return super.checkedCharValue();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.BYTE;
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/CharTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/CharTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class CharTypeImpl extends PrimitiveTypeImpl implements CharType {
|
||||
CharTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.CHAR);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedCharValue());
|
||||
}
|
||||
|
||||
}
|
||||
126
jdkSrc/jdk8/com/sun/tools/jdi/CharValueImpl.java
Normal file
126
jdkSrc/jdk8/com/sun/tools/jdi/CharValueImpl.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class CharValueImpl extends PrimitiveValueImpl
|
||||
implements CharValue {
|
||||
private char value;
|
||||
|
||||
CharValueImpl(VirtualMachine aVm,char aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof CharValue)) {
|
||||
return (value == ((CharValue)obj).value()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public int compareTo(CharValue obj) {
|
||||
char other = obj.value();
|
||||
return value() - other;
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theCharType();
|
||||
}
|
||||
|
||||
public char value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return(int)value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return(double)value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
// Note: since char is unsigned, don't check against MIN_VALUE
|
||||
if (value > Byte.MAX_VALUE) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to byte");
|
||||
} else {
|
||||
return super.checkedByteValue();
|
||||
}
|
||||
}
|
||||
|
||||
short checkedShortValue() throws InvalidTypeException {
|
||||
// Note: since char is unsigned, don't check against MIN_VALUE
|
||||
if (value > Short.MAX_VALUE) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to short");
|
||||
} else {
|
||||
return super.checkedShortValue();
|
||||
}
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.CHAR;
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/com/sun/tools/jdi/ClassLoaderReferenceImpl.java
Normal file
113
jdkSrc/jdk8/com/sun/tools/jdi/ClassLoaderReferenceImpl.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ClassLoaderReferenceImpl extends ObjectReferenceImpl
|
||||
implements ClassLoaderReference, VMListener {
|
||||
|
||||
// This is cached only while the VM is suspended
|
||||
private static class Cache extends ObjectReferenceImpl.Cache {
|
||||
List<ReferenceType> visibleClasses = null;
|
||||
}
|
||||
|
||||
protected ObjectReferenceImpl.Cache newCache() {
|
||||
return new Cache();
|
||||
}
|
||||
|
||||
ClassLoaderReferenceImpl(VirtualMachine aVm, long ref) {
|
||||
super(aVm, ref);
|
||||
vm.state().addListener(this);
|
||||
}
|
||||
|
||||
protected String description() {
|
||||
return "ClassLoaderReference " + uniqueID();
|
||||
}
|
||||
|
||||
public List<ReferenceType> definedClasses() {
|
||||
ArrayList<ReferenceType> definedClasses = new ArrayList<ReferenceType>();
|
||||
for (ReferenceType type : vm.allClasses()) {
|
||||
if (type.isPrepared() &&
|
||||
equals(type.classLoader())) {
|
||||
definedClasses.add(type);
|
||||
}
|
||||
}
|
||||
return definedClasses;
|
||||
}
|
||||
|
||||
public List<ReferenceType> visibleClasses() {
|
||||
List<ReferenceType> classes = null;
|
||||
try {
|
||||
Cache local = (Cache)getCache();
|
||||
|
||||
if (local != null) {
|
||||
classes = local.visibleClasses;
|
||||
}
|
||||
if (classes == null) {
|
||||
JDWP.ClassLoaderReference.VisibleClasses.ClassInfo[]
|
||||
jdwpClasses = JDWP.ClassLoaderReference.VisibleClasses.
|
||||
process(vm, this).classes;
|
||||
classes = new ArrayList<ReferenceType>(jdwpClasses.length);
|
||||
for (int i = 0; i < jdwpClasses.length; ++i) {
|
||||
classes.add(vm.referenceType(jdwpClasses[i].typeID,
|
||||
jdwpClasses[i].refTypeTag));
|
||||
}
|
||||
classes = Collections.unmodifiableList(classes);
|
||||
if (local != null) {
|
||||
local.visibleClasses = classes;
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace(description() +
|
||||
" temporarily caching visible classes (count = " +
|
||||
classes.size() + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return classes;
|
||||
}
|
||||
|
||||
Type findType(String signature) throws ClassNotLoadedException {
|
||||
List<ReferenceType> types = visibleClasses();
|
||||
Iterator<ReferenceType> iter = types.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ReferenceType type = iter.next();
|
||||
if (type.signature().equals(signature)) {
|
||||
return type;
|
||||
}
|
||||
}
|
||||
JNITypeParser parser = new JNITypeParser(signature);
|
||||
throw new ClassNotLoadedException(parser.typeName(),
|
||||
"Class " + parser.typeName() + " not loaded");
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.CLASS_LOADER;
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/com/sun/tools/jdi/ClassObjectReferenceImpl.java
Normal file
62
jdkSrc/jdk8/com/sun/tools/jdi/ClassObjectReferenceImpl.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ClassObjectReferenceImpl extends ObjectReferenceImpl
|
||||
implements ClassObjectReference {
|
||||
private ReferenceType reflectedType;
|
||||
|
||||
ClassObjectReferenceImpl(VirtualMachine vm, long ref) {
|
||||
super(vm, ref);
|
||||
}
|
||||
|
||||
public ReferenceType reflectedType() {
|
||||
if (reflectedType == null) {
|
||||
try {
|
||||
JDWP.ClassObjectReference.ReflectedType reply =
|
||||
JDWP.ClassObjectReference.ReflectedType.process(vm, this);
|
||||
reflectedType = vm.referenceType(reply.typeID,
|
||||
reply.refTypeTag);
|
||||
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return reflectedType;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.CLASS_OBJECT;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "instance of " + referenceType().name() +
|
||||
"(reflected class=" + reflectedType().name() + ", " + "id=" + uniqueID() + ")";
|
||||
}
|
||||
}
|
||||
296
jdkSrc/jdk8/com/sun/tools/jdi/ClassTypeImpl.java
Normal file
296
jdkSrc/jdk8/com/sun/tools/jdi/ClassTypeImpl.java
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
final public class ClassTypeImpl extends InvokableTypeImpl
|
||||
implements ClassType
|
||||
{
|
||||
private static class IResult implements InvocationResult {
|
||||
final private JDWP.ClassType.InvokeMethod rslt;
|
||||
|
||||
public IResult(JDWP.ClassType.InvokeMethod rslt) {
|
||||
this.rslt = rslt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectReferenceImpl getException() {
|
||||
return rslt.exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueImpl getResult() {
|
||||
return rslt.returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean cachedSuperclass = false;
|
||||
private ClassType superclass = null;
|
||||
private int lastLine = -1;
|
||||
private List<InterfaceType> interfaces = null;
|
||||
|
||||
protected ClassTypeImpl(VirtualMachine aVm,long aRef) {
|
||||
super(aVm, aRef);
|
||||
}
|
||||
|
||||
public ClassType superclass() {
|
||||
if(!cachedSuperclass) {
|
||||
ClassTypeImpl sup = null;
|
||||
try {
|
||||
sup = JDWP.ClassType.Superclass.
|
||||
process(vm, this).superclass;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
|
||||
/*
|
||||
* If there is a superclass, cache its
|
||||
* ClassType here. Otherwise,
|
||||
* leave the cache reference null.
|
||||
*/
|
||||
if (sup != null) {
|
||||
superclass = sup;
|
||||
}
|
||||
cachedSuperclass = true;
|
||||
}
|
||||
|
||||
return superclass;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InterfaceType> interfaces() {
|
||||
if (interfaces == null) {
|
||||
interfaces = getInterfaces();
|
||||
}
|
||||
return interfaces;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<InterfaceType> allInterfaces() {
|
||||
return getAllInterfaces();
|
||||
}
|
||||
|
||||
public List<ClassType> subclasses() {
|
||||
List<ClassType> subs = new ArrayList<ClassType>();
|
||||
for (ReferenceType refType : vm.allClasses()) {
|
||||
if (refType instanceof ClassType) {
|
||||
ClassType clazz = (ClassType)refType;
|
||||
ClassType superclass = clazz.superclass();
|
||||
if ((superclass != null) && superclass.equals(this)) {
|
||||
subs.add((ClassType)refType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return subs;
|
||||
}
|
||||
|
||||
public boolean isEnum() {
|
||||
ClassType superclass = superclass();
|
||||
if (superclass != null &&
|
||||
superclass.name().equals("java.lang.Enum")) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setValue(Field field, Value value)
|
||||
throws InvalidTypeException, ClassNotLoadedException {
|
||||
|
||||
validateMirror(field);
|
||||
validateMirrorOrNull(value);
|
||||
validateFieldSet(field);
|
||||
|
||||
// More validation specific to setting from a ClassType
|
||||
if(!field.isStatic()) {
|
||||
throw new IllegalArgumentException(
|
||||
"Must set non-static field through an instance");
|
||||
}
|
||||
|
||||
try {
|
||||
JDWP.ClassType.SetValues.FieldValue[] values =
|
||||
new JDWP.ClassType.SetValues.FieldValue[1];
|
||||
values[0] = new JDWP.ClassType.SetValues.FieldValue(
|
||||
((FieldImpl)field).ref(),
|
||||
// validate and convert if necessary
|
||||
ValueImpl.prepareForAssignment(value, (FieldImpl)field));
|
||||
|
||||
try {
|
||||
JDWP.ClassType.SetValues.process(vm, this, values);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
} catch (ClassNotLoadedException e) {
|
||||
/*
|
||||
* Since we got this exception,
|
||||
* the field type must be a reference type. The value
|
||||
* we're trying to set is null, but if the field's
|
||||
* class has not yet been loaded through the enclosing
|
||||
* class loader, then setting to null is essentially a
|
||||
* no-op, and we should allow it without an exception.
|
||||
*/
|
||||
if (value != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PacketStream sendNewInstanceCommand(final ThreadReferenceImpl thread,
|
||||
final MethodImpl method,
|
||||
final ValueImpl[] args,
|
||||
final int options) {
|
||||
CommandSender sender =
|
||||
new CommandSender() {
|
||||
public PacketStream send() {
|
||||
return JDWP.ClassType.NewInstance.enqueueCommand(
|
||||
vm, ClassTypeImpl.this, thread,
|
||||
method.ref(), args, options);
|
||||
}
|
||||
};
|
||||
|
||||
PacketStream stream;
|
||||
if ((options & INVOKE_SINGLE_THREADED) != 0) {
|
||||
stream = thread.sendResumingCommand(sender);
|
||||
} else {
|
||||
stream = vm.sendResumingCommand(sender);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
public ObjectReference newInstance(ThreadReference threadIntf,
|
||||
Method methodIntf,
|
||||
List<? extends Value> origArguments,
|
||||
int options)
|
||||
throws InvalidTypeException,
|
||||
ClassNotLoadedException,
|
||||
IncompatibleThreadStateException,
|
||||
InvocationException {
|
||||
validateMirror(threadIntf);
|
||||
validateMirror(methodIntf);
|
||||
validateMirrorsOrNulls(origArguments);
|
||||
|
||||
MethodImpl method = (MethodImpl)methodIntf;
|
||||
ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
|
||||
|
||||
validateConstructorInvocation(method);
|
||||
|
||||
List<Value> arguments = method.validateAndPrepareArgumentsForInvoke(
|
||||
origArguments);
|
||||
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
|
||||
JDWP.ClassType.NewInstance ret = null;
|
||||
try {
|
||||
PacketStream stream =
|
||||
sendNewInstanceCommand(thread, method, args, options);
|
||||
ret = JDWP.ClassType.NewInstance.waitForReply(vm, stream);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
|
||||
throw new IncompatibleThreadStateException();
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There is an implict VM-wide suspend at the conclusion
|
||||
* of a normal (non-single-threaded) method invoke
|
||||
*/
|
||||
if ((options & INVOKE_SINGLE_THREADED) == 0) {
|
||||
vm.notifySuspend();
|
||||
}
|
||||
|
||||
if (ret.exception != null) {
|
||||
throw new InvocationException(ret.exception);
|
||||
} else {
|
||||
return ret.newObject;
|
||||
}
|
||||
}
|
||||
|
||||
public Method concreteMethodByName(String name, String signature) {
|
||||
Method method = null;
|
||||
for (Method candidate : visibleMethods()) {
|
||||
if (candidate.name().equals(name) &&
|
||||
candidate.signature().equals(signature) &&
|
||||
!candidate.isAbstract()) {
|
||||
|
||||
method = candidate;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
void validateConstructorInvocation(Method method)
|
||||
throws InvalidTypeException,
|
||||
InvocationException {
|
||||
/*
|
||||
* Method must be in this class.
|
||||
*/
|
||||
ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
|
||||
if (!declType.equals(this)) {
|
||||
throw new IllegalArgumentException("Invalid constructor");
|
||||
}
|
||||
|
||||
/*
|
||||
* Method must be a constructor
|
||||
*/
|
||||
if (!method.isConstructor()) {
|
||||
throw new IllegalArgumentException("Cannot create instance with non-constructor");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "class " + name() + " (" + loaderString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
CommandSender getInvokeMethodSender(ThreadReferenceImpl thread,
|
||||
MethodImpl method,
|
||||
ValueImpl[] args,
|
||||
int options) {
|
||||
return () ->
|
||||
JDWP.ClassType.InvokeMethod.enqueueCommand(vm,
|
||||
ClassTypeImpl.this,
|
||||
thread,
|
||||
method.ref(),
|
||||
args,
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
InvocationResult waitForReply(PacketStream stream) throws JDWPException {
|
||||
return new IResult(JDWP.ClassType.InvokeMethod.waitForReply(vm, stream));
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean canInvoke(Method method) {
|
||||
// Method must be in this class or a superclass.
|
||||
return ((ReferenceTypeImpl)method.declaringType()).isAssignableFrom(this);
|
||||
}
|
||||
}
|
||||
33
jdkSrc/jdk8/com/sun/tools/jdi/CommandSender.java
Normal file
33
jdkSrc/jdk8/com/sun/tools/jdi/CommandSender.java
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.EventListener;
|
||||
|
||||
interface CommandSender {
|
||||
PacketStream send();
|
||||
}
|
||||
545
jdkSrc/jdk8/com/sun/tools/jdi/ConcreteMethodImpl.java
Normal file
545
jdkSrc/jdk8/com/sun/tools/jdi/ConcreteMethodImpl.java
Normal file
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
/**
|
||||
* Represents methods with method bodies.
|
||||
* That is, non-native non-abstract methods.
|
||||
* Private to MethodImpl.
|
||||
*/
|
||||
public class ConcreteMethodImpl extends MethodImpl {
|
||||
|
||||
/*
|
||||
* A subset of the line number info that is softly cached
|
||||
*/
|
||||
static private class SoftLocationXRefs {
|
||||
final String stratumID; // The stratum of this information
|
||||
final Map<Integer, List<Location>> lineMapper; // Maps line number to location(s)
|
||||
final List<Location> lineLocations; // List of locations ordered by code index
|
||||
|
||||
/*
|
||||
* Note: these do not necessarily correspond to
|
||||
* the line numbers of the first and last elements
|
||||
* in the lineLocations list. Use these only for bounds
|
||||
* checking and with lineMapper.
|
||||
*/
|
||||
final int lowestLine;
|
||||
final int highestLine;
|
||||
|
||||
SoftLocationXRefs(String stratumID, Map<Integer, List<Location>> lineMapper, List<Location> lineLocations,
|
||||
int lowestLine, int highestLine) {
|
||||
this.stratumID = stratumID;
|
||||
this.lineMapper = Collections.unmodifiableMap(lineMapper);
|
||||
this.lineLocations =
|
||||
Collections.unmodifiableList(lineLocations);
|
||||
this.lowestLine = lowestLine;
|
||||
this.highestLine = highestLine;
|
||||
}
|
||||
}
|
||||
|
||||
private Location location = null;
|
||||
private SoftReference<SoftLocationXRefs> softBaseLocationXRefsRef;
|
||||
private SoftReference<SoftLocationXRefs> softOtherLocationXRefsRef;
|
||||
private SoftReference<List<LocalVariable>> variablesRef = null;
|
||||
private boolean absentVariableInformation = false;
|
||||
private long firstIndex = -1;
|
||||
private long lastIndex = -1;
|
||||
private SoftReference<byte[]> bytecodesRef = null;
|
||||
private int argSlotCount = -1;
|
||||
|
||||
ConcreteMethodImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
|
||||
long ref,
|
||||
String name, String signature,
|
||||
String genericSignature, int modifiers) {
|
||||
|
||||
// The generic signature is set when this is created
|
||||
super(vm, declaringType, ref, name, signature,
|
||||
genericSignature, modifiers);
|
||||
}
|
||||
|
||||
public Location location() {
|
||||
if (location == null) {
|
||||
getBaseLocations();
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
List<Location> sourceNameFilter(List<Location> list,
|
||||
SDE.Stratum stratum,
|
||||
String sourceName)
|
||||
throws AbsentInformationException {
|
||||
if (sourceName == null) {
|
||||
return list;
|
||||
} else {
|
||||
/* needs sourceName filteration */
|
||||
List<Location> locs = new ArrayList<Location>();
|
||||
for (Location loc : list) {
|
||||
if (((LocationImpl)loc).sourceName(stratum).equals(sourceName)) {
|
||||
locs.add(loc);
|
||||
}
|
||||
}
|
||||
return locs;
|
||||
}
|
||||
}
|
||||
|
||||
List<Location> allLineLocations(SDE.Stratum stratum,
|
||||
String sourceName)
|
||||
throws AbsentInformationException {
|
||||
List<Location> lineLocations = getLocations(stratum).lineLocations;
|
||||
|
||||
if (lineLocations.size() == 0) {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(
|
||||
sourceNameFilter(lineLocations, stratum, sourceName));
|
||||
}
|
||||
|
||||
List<Location> locationsOfLine(SDE.Stratum stratum,
|
||||
String sourceName,
|
||||
int lineNumber)
|
||||
throws AbsentInformationException {
|
||||
SoftLocationXRefs info = getLocations(stratum);
|
||||
|
||||
if (info.lineLocations.size() == 0) {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
|
||||
/*
|
||||
* Find the locations which match the line number
|
||||
* passed in.
|
||||
*/
|
||||
List<Location> list = info.lineMapper.get(new Integer(lineNumber));
|
||||
|
||||
if (list == null) {
|
||||
list = new ArrayList<Location>(0);
|
||||
}
|
||||
return Collections.unmodifiableList(
|
||||
sourceNameFilter(list, stratum, sourceName));
|
||||
}
|
||||
|
||||
|
||||
public Location locationOfCodeIndex(long codeIndex) {
|
||||
if (firstIndex == -1) {
|
||||
getBaseLocations();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for invalid code index.
|
||||
*/
|
||||
if (codeIndex < firstIndex || codeIndex > lastIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new LocationImpl(virtualMachine(), this, codeIndex);
|
||||
}
|
||||
|
||||
|
||||
LineInfo codeIndexToLineInfo(SDE.Stratum stratum,
|
||||
long codeIndex) {
|
||||
if (firstIndex == -1) {
|
||||
getBaseLocations();
|
||||
}
|
||||
|
||||
/*
|
||||
* Check for invalid code index.
|
||||
*/
|
||||
if (codeIndex < firstIndex || codeIndex > lastIndex) {
|
||||
throw new InternalError(
|
||||
"Location with invalid code index");
|
||||
}
|
||||
|
||||
List<Location> lineLocations = getLocations(stratum).lineLocations;
|
||||
|
||||
/*
|
||||
* Check for absent line numbers.
|
||||
*/
|
||||
if (lineLocations.size() == 0) {
|
||||
return super.codeIndexToLineInfo(stratum, codeIndex);
|
||||
}
|
||||
|
||||
Iterator<Location> iter = lineLocations.iterator();
|
||||
/*
|
||||
* Treat code before the beginning of the first line table
|
||||
* entry as part of the first line. javac will generate
|
||||
* code like this for some local classes. This "prolog"
|
||||
* code contains assignments from locals in the enclosing
|
||||
* scope to synthetic fields in the local class. Same for
|
||||
* other language prolog code.
|
||||
*/
|
||||
LocationImpl bestMatch = (LocationImpl)iter.next();
|
||||
while (iter.hasNext()) {
|
||||
LocationImpl current = (LocationImpl)iter.next();
|
||||
if (current.codeIndex() > codeIndex) {
|
||||
break;
|
||||
}
|
||||
bestMatch = current;
|
||||
}
|
||||
return bestMatch.getLineInfo(stratum);
|
||||
}
|
||||
|
||||
|
||||
public List<LocalVariable> variables() throws AbsentInformationException {
|
||||
return getVariables();
|
||||
}
|
||||
|
||||
public List<LocalVariable> variablesByName(String name) throws AbsentInformationException {
|
||||
List<LocalVariable> variables = getVariables();
|
||||
|
||||
List<LocalVariable> retList = new ArrayList<LocalVariable>(2);
|
||||
Iterator<LocalVariable> iter = variables.iterator();
|
||||
while(iter.hasNext()) {
|
||||
LocalVariable variable = iter.next();
|
||||
if (variable.name().equals(name)) {
|
||||
retList.add(variable);
|
||||
}
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
|
||||
public List<LocalVariable> arguments() throws AbsentInformationException {
|
||||
List<LocalVariable> variables = getVariables();
|
||||
|
||||
List<LocalVariable> retList = new ArrayList<LocalVariable>(variables.size());
|
||||
Iterator<LocalVariable> iter = variables.iterator();
|
||||
while(iter.hasNext()) {
|
||||
LocalVariable variable = iter.next();
|
||||
if (variable.isArgument()) {
|
||||
retList.add(variable);
|
||||
}
|
||||
}
|
||||
return retList;
|
||||
}
|
||||
|
||||
public byte[] bytecodes() {
|
||||
byte[] bytecodes = (bytecodesRef == null) ? null :
|
||||
bytecodesRef.get();
|
||||
if (bytecodes == null) {
|
||||
try {
|
||||
bytecodes = JDWP.Method.Bytecodes.
|
||||
process(vm, declaringType, ref).bytes;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
bytecodesRef = new SoftReference<byte[]>(bytecodes);
|
||||
}
|
||||
/*
|
||||
* Arrays are always modifiable, so it is a little unsafe
|
||||
* to return the cached bytecodes directly; instead, we
|
||||
* make a clone at the cost of using more memory.
|
||||
*/
|
||||
return bytecodes.clone();
|
||||
}
|
||||
|
||||
int argSlotCount() throws AbsentInformationException {
|
||||
if (argSlotCount == -1) {
|
||||
getVariables();
|
||||
}
|
||||
return argSlotCount;
|
||||
}
|
||||
|
||||
private SoftLocationXRefs getLocations(SDE.Stratum stratum) {
|
||||
if (stratum.isJava()) {
|
||||
return getBaseLocations();
|
||||
}
|
||||
String stratumID = stratum.id();
|
||||
SoftLocationXRefs info =
|
||||
(softOtherLocationXRefsRef == null) ? null :
|
||||
softOtherLocationXRefsRef.get();
|
||||
if (info != null && info.stratumID.equals(stratumID)) {
|
||||
return info;
|
||||
}
|
||||
|
||||
List<Location> lineLocations = new ArrayList<Location>();
|
||||
Map<Integer, List<Location>> lineMapper = new HashMap<Integer, List<Location>>();
|
||||
int lowestLine = -1;
|
||||
int highestLine = -1;
|
||||
SDE.LineStratum lastLineStratum = null;
|
||||
SDE.Stratum baseStratum =
|
||||
declaringType.stratum(SDE.BASE_STRATUM_NAME);
|
||||
Iterator<Location> it = getBaseLocations().lineLocations.iterator();
|
||||
while(it.hasNext()) {
|
||||
LocationImpl loc = (LocationImpl)it.next();
|
||||
int baseLineNumber = loc.lineNumber(baseStratum);
|
||||
SDE.LineStratum lineStratum =
|
||||
stratum.lineStratum(declaringType,
|
||||
baseLineNumber);
|
||||
|
||||
if (lineStratum == null) {
|
||||
// location not mapped in this stratum
|
||||
continue;
|
||||
}
|
||||
|
||||
int lineNumber = lineStratum.lineNumber();
|
||||
|
||||
// remove unmapped and dup lines
|
||||
if ((lineNumber != -1) &&
|
||||
(!lineStratum.equals(lastLineStratum))) {
|
||||
lastLineStratum = lineStratum;
|
||||
|
||||
// Remember the largest/smallest line number
|
||||
if (lineNumber > highestLine) {
|
||||
highestLine = lineNumber;
|
||||
}
|
||||
if ((lineNumber < lowestLine) || (lowestLine == -1)) {
|
||||
lowestLine = lineNumber;
|
||||
}
|
||||
|
||||
loc.addStratumLineInfo(
|
||||
new StratumLineInfo(stratumID,
|
||||
lineNumber,
|
||||
lineStratum.sourceName(),
|
||||
lineStratum.sourcePath()));
|
||||
|
||||
// Add to the location list
|
||||
lineLocations.add(loc);
|
||||
|
||||
// Add to the line -> locations map
|
||||
Integer key = new Integer(lineNumber);
|
||||
List<Location> mappedLocs = lineMapper.get(key);
|
||||
if (mappedLocs == null) {
|
||||
mappedLocs = new ArrayList<Location>(1);
|
||||
lineMapper.put(key, mappedLocs);
|
||||
}
|
||||
mappedLocs.add(loc);
|
||||
}
|
||||
}
|
||||
|
||||
info = new SoftLocationXRefs(stratumID,
|
||||
lineMapper, lineLocations,
|
||||
lowestLine, highestLine);
|
||||
softOtherLocationXRefsRef = new SoftReference<SoftLocationXRefs>(info);
|
||||
return info;
|
||||
}
|
||||
|
||||
private SoftLocationXRefs getBaseLocations() {
|
||||
SoftLocationXRefs info = (softBaseLocationXRefsRef == null) ? null :
|
||||
softBaseLocationXRefsRef.get();
|
||||
if (info != null) {
|
||||
return info;
|
||||
}
|
||||
|
||||
JDWP.Method.LineTable lntab = null;
|
||||
try {
|
||||
lntab = JDWP.Method.LineTable.process(vm, declaringType, ref);
|
||||
} catch (JDWPException exc) {
|
||||
/*
|
||||
* Note: the absent info error shouldn't happen here
|
||||
* because the first and last index are always available.
|
||||
*/
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
|
||||
int count = lntab.lines.length;
|
||||
|
||||
List<Location> lineLocations = new ArrayList<Location>(count);
|
||||
Map<Integer, List<Location>>lineMapper = new HashMap<Integer, List<Location>>();
|
||||
int lowestLine = -1;
|
||||
int highestLine = -1;
|
||||
for (int i = 0; i < count; i++) {
|
||||
long bci = lntab.lines[i].lineCodeIndex;
|
||||
int lineNumber = lntab.lines[i].lineNumber;
|
||||
|
||||
/*
|
||||
* Some compilers will point multiple consecutive
|
||||
* lines at the same location. We need to choose
|
||||
* one of them so that we can consistently map back
|
||||
* and forth between line and location. So we choose
|
||||
* to record only the last line entry at a particular
|
||||
* location.
|
||||
*/
|
||||
if ((i + 1 == count) || (bci != lntab.lines[i+1].lineCodeIndex)) {
|
||||
// Remember the largest/smallest line number
|
||||
if (lineNumber > highestLine) {
|
||||
highestLine = lineNumber;
|
||||
}
|
||||
if ((lineNumber < lowestLine) || (lowestLine == -1)) {
|
||||
lowestLine = lineNumber;
|
||||
}
|
||||
LocationImpl loc =
|
||||
new LocationImpl(virtualMachine(), this, bci);
|
||||
loc.addBaseLineInfo(
|
||||
new BaseLineInfo(lineNumber, declaringType));
|
||||
|
||||
// Add to the location list
|
||||
lineLocations.add(loc);
|
||||
|
||||
// Add to the line -> locations map
|
||||
Integer key = new Integer(lineNumber);
|
||||
List<Location> mappedLocs = lineMapper.get(key);
|
||||
if (mappedLocs == null) {
|
||||
mappedLocs = new ArrayList<Location>(1);
|
||||
lineMapper.put(key, mappedLocs);
|
||||
}
|
||||
mappedLocs.add(loc);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* firstIndex, lastIndex, and startLocation need to be
|
||||
* retrieved only once since they are strongly referenced.
|
||||
*/
|
||||
if (location == null) {
|
||||
firstIndex = lntab.start;
|
||||
lastIndex = lntab.end;
|
||||
/*
|
||||
* The startLocation is the first one in the
|
||||
* location list if we have one;
|
||||
* otherwise, we construct a location for a
|
||||
* method start with no line info
|
||||
*/
|
||||
if (count > 0) {
|
||||
location = lineLocations.get(0);
|
||||
} else {
|
||||
location = new LocationImpl(virtualMachine(), this,
|
||||
firstIndex);
|
||||
}
|
||||
}
|
||||
|
||||
info = new SoftLocationXRefs(SDE.BASE_STRATUM_NAME,
|
||||
lineMapper, lineLocations,
|
||||
lowestLine, highestLine);
|
||||
softBaseLocationXRefsRef = new SoftReference<SoftLocationXRefs>(info);
|
||||
return info;
|
||||
}
|
||||
|
||||
private List<LocalVariable> getVariables1_4() throws AbsentInformationException {
|
||||
JDWP.Method.VariableTable vartab = null;
|
||||
try {
|
||||
vartab = JDWP.Method.VariableTable.
|
||||
process(vm, declaringType, ref);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
|
||||
absentVariableInformation = true;
|
||||
throw new AbsentInformationException();
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the number of slots used by argument variables
|
||||
argSlotCount = vartab.argCnt;
|
||||
int count = vartab.slots.length;
|
||||
List<LocalVariable> variables = new ArrayList<LocalVariable>(count);
|
||||
for (int i=0; i<count; i++) {
|
||||
JDWP.Method.VariableTable.SlotInfo si = vartab.slots[i];
|
||||
|
||||
/*
|
||||
* Skip "this*" entries because they are never real
|
||||
* variables from the JLS perspective.
|
||||
*/
|
||||
if (!si.name.startsWith("this$") && !si.name.equals("this")) {
|
||||
Location scopeStart = new LocationImpl(virtualMachine(),
|
||||
this, si.codeIndex);
|
||||
Location scopeEnd =
|
||||
new LocationImpl(virtualMachine(), this,
|
||||
si.codeIndex + si.length - 1);
|
||||
LocalVariable variable =
|
||||
new LocalVariableImpl(virtualMachine(), this,
|
||||
si.slot, scopeStart, scopeEnd,
|
||||
si.name, si.signature, null);
|
||||
// Add to the variable list
|
||||
variables.add(variable);
|
||||
}
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
private List<LocalVariable> getVariables1() throws AbsentInformationException {
|
||||
|
||||
if (!vm.canGet1_5LanguageFeatures()) {
|
||||
return getVariables1_4();
|
||||
}
|
||||
|
||||
JDWP.Method.VariableTableWithGeneric vartab = null;
|
||||
try {
|
||||
vartab = JDWP.Method.VariableTableWithGeneric.
|
||||
process(vm, declaringType, ref);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.ABSENT_INFORMATION) {
|
||||
absentVariableInformation = true;
|
||||
throw new AbsentInformationException();
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
// Get the number of slots used by argument variables
|
||||
argSlotCount = vartab.argCnt;
|
||||
int count = vartab.slots.length;
|
||||
List<LocalVariable> variables = new ArrayList<LocalVariable>(count);
|
||||
for (int i=0; i<count; i++) {
|
||||
JDWP.Method.VariableTableWithGeneric.SlotInfo si = vartab.slots[i];
|
||||
|
||||
/*
|
||||
* Skip "this*" entries because they are never real
|
||||
* variables from the JLS perspective.
|
||||
*/
|
||||
if (!si.name.startsWith("this$") && !si.name.equals("this")) {
|
||||
Location scopeStart = new LocationImpl(virtualMachine(),
|
||||
this, si.codeIndex);
|
||||
Location scopeEnd =
|
||||
new LocationImpl(virtualMachine(), this,
|
||||
si.codeIndex + si.length - 1);
|
||||
LocalVariable variable =
|
||||
new LocalVariableImpl(virtualMachine(), this,
|
||||
si.slot, scopeStart, scopeEnd,
|
||||
si.name, si.signature,
|
||||
si.genericSignature);
|
||||
// Add to the variable list
|
||||
variables.add(variable);
|
||||
}
|
||||
}
|
||||
return variables;
|
||||
}
|
||||
|
||||
private List<LocalVariable> getVariables() throws AbsentInformationException {
|
||||
if (absentVariableInformation) {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
|
||||
List<LocalVariable> variables = (variablesRef == null) ? null :
|
||||
variablesRef.get();
|
||||
if (variables != null) {
|
||||
return variables;
|
||||
}
|
||||
variables = getVariables1();
|
||||
variables = Collections.unmodifiableList(variables);
|
||||
variablesRef = new SoftReference<List<LocalVariable>>(variables);
|
||||
return variables;
|
||||
}
|
||||
}
|
||||
425
jdkSrc/jdk8/com/sun/tools/jdi/ConnectorImpl.java
Normal file
425
jdkSrc/jdk8/com/sun/tools/jdi/ConnectorImpl.java
Normal file
@@ -0,0 +1,425 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.tools.jdi.*;
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.InternalException;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.ResourceBundle;
|
||||
import java.io.Serializable;
|
||||
|
||||
abstract class ConnectorImpl implements Connector {
|
||||
Map<String,Argument> defaultArguments = new java.util.LinkedHashMap<String,Argument>();
|
||||
|
||||
// Used by BooleanArgument
|
||||
static String trueString = null;
|
||||
static String falseString;
|
||||
|
||||
public Map<String,Argument> defaultArguments() {
|
||||
Map<String,Argument> defaults = new java.util.LinkedHashMap<String,Argument>();
|
||||
Collection<Argument> values = defaultArguments.values();
|
||||
|
||||
Iterator<Argument> iter = values.iterator();
|
||||
while (iter.hasNext()) {
|
||||
ArgumentImpl argument = (ArgumentImpl)iter.next();
|
||||
defaults.put(argument.name(), (Argument)argument.clone());
|
||||
}
|
||||
return defaults;
|
||||
}
|
||||
|
||||
void addStringArgument(String name, String label, String description,
|
||||
String defaultValue, boolean mustSpecify) {
|
||||
defaultArguments.put(name,
|
||||
new StringArgumentImpl(name, label,
|
||||
description,
|
||||
defaultValue,
|
||||
mustSpecify));
|
||||
}
|
||||
|
||||
void addBooleanArgument(String name, String label, String description,
|
||||
boolean defaultValue, boolean mustSpecify) {
|
||||
defaultArguments.put(name,
|
||||
new BooleanArgumentImpl(name, label,
|
||||
description,
|
||||
defaultValue,
|
||||
mustSpecify));
|
||||
}
|
||||
|
||||
void addIntegerArgument(String name, String label, String description,
|
||||
String defaultValue, boolean mustSpecify,
|
||||
int min, int max) {
|
||||
defaultArguments.put(name,
|
||||
new IntegerArgumentImpl(name, label,
|
||||
description,
|
||||
defaultValue,
|
||||
mustSpecify,
|
||||
min, max));
|
||||
}
|
||||
|
||||
void addSelectedArgument(String name, String label, String description,
|
||||
String defaultValue, boolean mustSpecify,
|
||||
List<String> list) {
|
||||
defaultArguments.put(name,
|
||||
new SelectedArgumentImpl(name, label,
|
||||
description,
|
||||
defaultValue,
|
||||
mustSpecify, list));
|
||||
}
|
||||
|
||||
ArgumentImpl argument(String name, Map<String, ? extends Argument> arguments)
|
||||
throws IllegalConnectorArgumentsException {
|
||||
|
||||
ArgumentImpl argument = (ArgumentImpl)arguments.get(name);
|
||||
if (argument == null) {
|
||||
throw new IllegalConnectorArgumentsException(
|
||||
"Argument missing", name);
|
||||
}
|
||||
String value = argument.value();
|
||||
if (value == null || value.length() == 0) {
|
||||
if (argument.mustSpecify()) {
|
||||
throw new IllegalConnectorArgumentsException(
|
||||
"Argument unspecified", name);
|
||||
}
|
||||
} else if(!argument.isValid(value)) {
|
||||
throw new IllegalConnectorArgumentsException(
|
||||
"Argument invalid", name);
|
||||
}
|
||||
|
||||
return argument;
|
||||
}
|
||||
|
||||
|
||||
private ResourceBundle messages = null;
|
||||
|
||||
String getString(String key) {
|
||||
if (messages == null) {
|
||||
messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi");
|
||||
}
|
||||
return messages.getString(key);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
String string = name() + " (defaults: ";
|
||||
Iterator<Argument> iter = defaultArguments().values().iterator();
|
||||
boolean first = true;
|
||||
while (iter.hasNext()) {
|
||||
ArgumentImpl argument = (ArgumentImpl)iter.next();
|
||||
if (!first) {
|
||||
string += ", ";
|
||||
}
|
||||
string += argument.toString();
|
||||
first = false;
|
||||
}
|
||||
string += ")";
|
||||
return string;
|
||||
}
|
||||
|
||||
abstract class ArgumentImpl implements Connector.Argument, Cloneable, Serializable {
|
||||
private String name;
|
||||
private String label;
|
||||
private String description;
|
||||
private String value;
|
||||
private boolean mustSpecify;
|
||||
|
||||
ArgumentImpl(String name, String label, String description,
|
||||
String value,
|
||||
boolean mustSpecify) {
|
||||
this.name = name;
|
||||
this.label = label;
|
||||
this.description = description;
|
||||
this.value = value;
|
||||
this.mustSpecify = mustSpecify;
|
||||
}
|
||||
|
||||
public abstract boolean isValid(String value);
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public String value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(String value) {
|
||||
if (value == null) {
|
||||
throw new NullPointerException("Can't set null value");
|
||||
}
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public boolean mustSpecify() {
|
||||
return mustSpecify;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof Connector.Argument)) {
|
||||
Connector.Argument other = (Connector.Argument)obj;
|
||||
return (name().equals(other.name())) &&
|
||||
(description().equals(other.description())) &&
|
||||
(mustSpecify() == other.mustSpecify()) &&
|
||||
(value().equals(other.value()));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return description().hashCode();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
try {
|
||||
return super.clone();
|
||||
} catch (CloneNotSupportedException e) {
|
||||
// Object should always support clone
|
||||
throw new InternalException();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name() + "=" + value();
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanArgumentImpl extends ConnectorImpl.ArgumentImpl
|
||||
implements Connector.BooleanArgument {
|
||||
private static final long serialVersionUID = 1624542968639361316L;
|
||||
BooleanArgumentImpl(String name, String label, String description,
|
||||
boolean value,
|
||||
boolean mustSpecify) {
|
||||
super(name, label, description, null, mustSpecify);
|
||||
if(trueString == null) {
|
||||
trueString = getString("true");
|
||||
falseString = getString("false");
|
||||
}
|
||||
setValue(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the argument.
|
||||
*/
|
||||
public void setValue(boolean value) {
|
||||
setValue(stringValueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sanity check of argument.
|
||||
* @return <code>true</code> if value is a string
|
||||
* representation of a boolean value.
|
||||
* @see #stringValueOf(boolean)
|
||||
*/
|
||||
public boolean isValid(String value) {
|
||||
return value.equals(trueString) || value.equals(falseString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of the <code>value</code>
|
||||
* parameter.
|
||||
* Does not set or examine the value or the argument.
|
||||
* @return the localized String representation of the
|
||||
* boolean value.
|
||||
*/
|
||||
public String stringValueOf(boolean value) {
|
||||
return value? trueString : falseString;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the argument as a boolean. Since
|
||||
* the argument may not have been set or may have an invalid
|
||||
* value {@link #isValid(String)} should be called on
|
||||
* {@link #value()} to check its validity. If it is invalid
|
||||
* the boolean returned by this method is undefined.
|
||||
* @return the value of the argument as a boolean.
|
||||
*/
|
||||
public boolean booleanValue() {
|
||||
return value().equals(trueString);
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerArgumentImpl extends ConnectorImpl.ArgumentImpl
|
||||
implements Connector.IntegerArgument {
|
||||
private static final long serialVersionUID = 763286081923797770L;
|
||||
private final int min;
|
||||
private final int max;
|
||||
|
||||
IntegerArgumentImpl(String name, String label, String description,
|
||||
String value,
|
||||
boolean mustSpecify, int min, int max) {
|
||||
super(name, label, description, value, mustSpecify);
|
||||
this.min = min;
|
||||
this.max = max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the value of the argument.
|
||||
* The value should be checked with {@link #isValid(int)}
|
||||
* before setting it; invalid values will throw an exception
|
||||
* when the connection is established - for example,
|
||||
* on {@link LaunchingConnector#launch}
|
||||
*/
|
||||
public void setValue(int value) {
|
||||
setValue(stringValueOf(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sanity check of argument.
|
||||
* @return <code>true</code> if value represents an int that is
|
||||
* <code>{@link #min()} <= value <= {@link #max()}</code>
|
||||
*/
|
||||
public boolean isValid(String value) {
|
||||
if (value == null) {
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
return isValid(Integer.decode(value).intValue());
|
||||
} catch(NumberFormatException exc) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sanity check of argument.
|
||||
* @return <code>true</code> if
|
||||
* <code>{@link #min()} <= value <= {@link #max()}</code>
|
||||
*/
|
||||
public boolean isValid(int value) {
|
||||
return min <= value && value <= max;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the string representation of the <code>value</code>
|
||||
* parameter.
|
||||
* Does not set or examine the value or the argument.
|
||||
* @return the String representation of the
|
||||
* int value.
|
||||
*/
|
||||
public String stringValueOf(int value) {
|
||||
// *** Should this be internationalized????
|
||||
// *** Even Brian Beck was unsure if an Arabic programmer
|
||||
// *** would expect port numbers in Arabic numerals,
|
||||
// *** so punt for now.
|
||||
return ""+value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the value of the argument as a int. Since
|
||||
* the argument may not have been set or may have an invalid
|
||||
* value {@link #isValid(String)} should be called on
|
||||
* {@link #value()} to check its validity. If it is invalid
|
||||
* the int returned by this method is undefined.
|
||||
* @return the value of the argument as a int.
|
||||
*/
|
||||
public int intValue() {
|
||||
if (value() == null) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
return Integer.decode(value()).intValue();
|
||||
} catch(NumberFormatException exc) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The upper bound for the value.
|
||||
* @return the maximum allowed value for this argument.
|
||||
*/
|
||||
public int max() {
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* The lower bound for the value.
|
||||
* @return the minimum allowed value for this argument.
|
||||
*/
|
||||
public int min() {
|
||||
return min;
|
||||
}
|
||||
}
|
||||
|
||||
class StringArgumentImpl extends ConnectorImpl.ArgumentImpl
|
||||
implements Connector.StringArgument {
|
||||
private static final long serialVersionUID = 7500484902692107464L;
|
||||
StringArgumentImpl(String name, String label, String description,
|
||||
String value,
|
||||
boolean mustSpecify) {
|
||||
super(name, label, description, value, mustSpecify);
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sanity check of argument.
|
||||
* @return <code>true</code> always
|
||||
*/
|
||||
public boolean isValid(String value) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
class SelectedArgumentImpl extends ConnectorImpl.ArgumentImpl
|
||||
implements Connector.SelectedArgument {
|
||||
private static final long serialVersionUID = -5689584530908382517L;
|
||||
private final List<String> choices;
|
||||
|
||||
SelectedArgumentImpl(String name, String label, String description,
|
||||
String value,
|
||||
boolean mustSpecify, List<String> choices) {
|
||||
super(name, label, description, value, mustSpecify);
|
||||
this.choices = Collections.unmodifiableList(new ArrayList<String>(choices));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the possible values for the argument
|
||||
* @return {@link List} of {@link String}
|
||||
*/
|
||||
public List<String> choices() {
|
||||
return choices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs basic sanity check of argument.
|
||||
* @return <code>true</code> if value is one of {@link #choices()}.
|
||||
*/
|
||||
public boolean isValid(String value) {
|
||||
return choices.contains(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/DoubleTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/DoubleTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class DoubleTypeImpl extends PrimitiveTypeImpl implements DoubleType {
|
||||
DoubleTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.DOUBLE);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedDoubleValue());
|
||||
}
|
||||
|
||||
}
|
||||
164
jdkSrc/jdk8/com/sun/tools/jdi/DoubleValueImpl.java
Normal file
164
jdkSrc/jdk8/com/sun/tools/jdi/DoubleValueImpl.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class DoubleValueImpl extends PrimitiveValueImpl
|
||||
implements DoubleValue {
|
||||
private double value;
|
||||
|
||||
DoubleValueImpl(VirtualMachine aVm,double aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof DoubleValue)) {
|
||||
return (value == ((DoubleValue)obj).value()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int compareTo(DoubleValue obj) {
|
||||
double other = obj.value();
|
||||
if (value() < other) {
|
||||
return -1;
|
||||
} else if (value() == other) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theDoubleType();
|
||||
}
|
||||
|
||||
public double value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0.0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return(int)value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
if ((value > Byte.MAX_VALUE) || (value < Byte.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to byte");
|
||||
} else {
|
||||
return super.checkedByteValue();
|
||||
}
|
||||
}
|
||||
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to char");
|
||||
} else {
|
||||
return super.checkedCharValue();
|
||||
}
|
||||
}
|
||||
|
||||
short checkedShortValue() throws InvalidTypeException {
|
||||
if ((value > Short.MAX_VALUE) || (value < Short.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to short");
|
||||
} else {
|
||||
return super.checkedShortValue();
|
||||
}
|
||||
}
|
||||
|
||||
int checkedIntValue() throws InvalidTypeException {
|
||||
if ((value > Integer.MAX_VALUE) || (value < Integer.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to int");
|
||||
} else {
|
||||
return super.checkedIntValue();
|
||||
}
|
||||
}
|
||||
|
||||
long checkedLongValue() throws InvalidTypeException {
|
||||
long longValue = (long)value;
|
||||
if (longValue != value) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to long");
|
||||
} else {
|
||||
return super.checkedLongValue();
|
||||
}
|
||||
}
|
||||
|
||||
float checkedFloatValue() throws InvalidTypeException {
|
||||
float floatValue = (float)value;
|
||||
if (floatValue != value) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to float");
|
||||
} else {
|
||||
return super.checkedFloatValue();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.DOUBLE;
|
||||
}
|
||||
}
|
||||
242
jdkSrc/jdk8/com/sun/tools/jdi/EventQueueImpl.java
Normal file
242
jdkSrc/jdk8/com/sun/tools/jdi/EventQueueImpl.java
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.EventQueue;
|
||||
import com.sun.jdi.event.EventSet;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class EventQueueImpl extends MirrorImpl implements EventQueue {
|
||||
|
||||
/*
|
||||
* Note this is not a synchronized list. Iteration/update should be
|
||||
* protected through the 'this' monitor.
|
||||
*/
|
||||
LinkedList<EventSet> eventSets = new LinkedList<EventSet>();
|
||||
|
||||
TargetVM target;
|
||||
boolean closed = false;
|
||||
|
||||
EventQueueImpl(VirtualMachine vm, TargetVM target) {
|
||||
super(vm);
|
||||
this.target = target;
|
||||
target.addEventQueue(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* Override superclass back to default equality
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
synchronized void enqueue(EventSet eventSet) {
|
||||
eventSets.add(eventSet);
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
synchronized int size() {
|
||||
return eventSets.size();
|
||||
}
|
||||
|
||||
synchronized void close() {
|
||||
if (!closed) {
|
||||
closed = true; // OK for this the be first since synchronized
|
||||
|
||||
// place VMDisconnectEvent into queue
|
||||
enqueue(new EventSetImpl(vm,
|
||||
(byte)JDWP.EventKind.VM_DISCONNECTED));
|
||||
}
|
||||
}
|
||||
|
||||
public EventSet remove() throws InterruptedException {
|
||||
return remove(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out events not for user's eyes.
|
||||
* Then filter out empty sets.
|
||||
*/
|
||||
public EventSet remove(long timeout) throws InterruptedException {
|
||||
if (timeout < 0) {
|
||||
throw new IllegalArgumentException("Timeout cannot be negative");
|
||||
}
|
||||
|
||||
EventSet eventSet;
|
||||
while (true) {
|
||||
EventSetImpl fullEventSet = removeUnfiltered(timeout);
|
||||
if (fullEventSet == null) {
|
||||
eventSet = null; // timeout
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Remove events from the event set for which
|
||||
* there is no corresponding enabled request (
|
||||
* this includes our internally requested events.)
|
||||
* This never returns null
|
||||
*/
|
||||
eventSet = fullEventSet.userFilter();
|
||||
if (!eventSet.isEmpty()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((eventSet != null) && (eventSet.suspendPolicy() == JDWP.SuspendPolicy.ALL)) {
|
||||
vm.notifySuspend();
|
||||
}
|
||||
|
||||
return eventSet;
|
||||
}
|
||||
|
||||
EventSet removeInternal() throws InterruptedException {
|
||||
EventSet eventSet;
|
||||
do {
|
||||
// Waiting forever, so removeUnfiltered() is never null
|
||||
eventSet = removeUnfiltered(0).internalFilter();
|
||||
} while (eventSet == null || eventSet.isEmpty());
|
||||
|
||||
/*
|
||||
* Currently, no internal events are requested with a suspend
|
||||
* policy other than none, so we don't check for notifySuspend()
|
||||
* here. If this changes in the future, there is much
|
||||
* infrastructure that needs to be updated.
|
||||
*/
|
||||
|
||||
return eventSet;
|
||||
}
|
||||
|
||||
private TimerThread startTimerThread(long timeout) {
|
||||
TimerThread thread = new TimerThread(timeout);
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
return thread;
|
||||
}
|
||||
|
||||
private boolean shouldWait(TimerThread timerThread) {
|
||||
return !closed && eventSets.isEmpty() &&
|
||||
((timerThread == null) ? true : !timerThread.timedOut());
|
||||
}
|
||||
|
||||
private EventSetImpl removeUnfiltered(long timeout)
|
||||
throws InterruptedException {
|
||||
EventSetImpl eventSet = null;
|
||||
|
||||
/*
|
||||
* Make sure the VM has completed initialization before
|
||||
* trying to build events.
|
||||
*/
|
||||
vm.waitInitCompletion();
|
||||
|
||||
synchronized(this) {
|
||||
if (!eventSets.isEmpty()) {
|
||||
/*
|
||||
* If there's already something there, no need
|
||||
* for anything elaborate.
|
||||
*/
|
||||
eventSet = (EventSetImpl)eventSets.removeFirst();
|
||||
} else {
|
||||
/*
|
||||
* If a timeout was specified, create a thread to
|
||||
* notify this one when a timeout
|
||||
* occurs. We can't use the timed version of wait()
|
||||
* because it is possible for multiple enqueue() calls
|
||||
* before we see something in the eventSet queue
|
||||
* (this is possible when multiple threads call
|
||||
* remove() concurrently -- not a great idea, but
|
||||
* it should be supported). Even if enqueue() did a
|
||||
* notify() instead of notifyAll() we are not able to
|
||||
* use a timed wait because there's no way to distinguish
|
||||
* a timeout from a notify. That limitation implies a
|
||||
* possible race condition between a timed out thread
|
||||
* and a notified thread.
|
||||
*/
|
||||
TimerThread timerThread = null;
|
||||
try {
|
||||
if (timeout > 0) {
|
||||
timerThread = startTimerThread(timeout);
|
||||
}
|
||||
|
||||
while (shouldWait(timerThread)) {
|
||||
this.wait();
|
||||
}
|
||||
} finally {
|
||||
if ((timerThread != null) && !timerThread.timedOut()) {
|
||||
timerThread.interrupt();
|
||||
}
|
||||
}
|
||||
|
||||
if (eventSets.isEmpty()) {
|
||||
if (closed) {
|
||||
throw new VMDisconnectedException();
|
||||
}
|
||||
} else {
|
||||
eventSet = (EventSetImpl)eventSets.removeFirst();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The build is synchronized on the event set, don't hold
|
||||
// the queue lock.
|
||||
if (eventSet != null) {
|
||||
target.notifyDequeueEventSet();
|
||||
eventSet.build();
|
||||
}
|
||||
return eventSet;
|
||||
}
|
||||
|
||||
private class TimerThread extends Thread {
|
||||
private boolean timedOut = false;
|
||||
private long timeout;
|
||||
|
||||
TimerThread(long timeout) {
|
||||
super(vm.threadGroupForJDI(), "JDI Event Queue Timer");
|
||||
this.timeout = timeout;
|
||||
}
|
||||
|
||||
boolean timedOut() {
|
||||
return timedOut;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
Thread.sleep(timeout);
|
||||
EventQueueImpl queue = EventQueueImpl.this;
|
||||
synchronized(queue) {
|
||||
timedOut = true;
|
||||
queue.notifyAll();
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// Exit without notifying
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
954
jdkSrc/jdk8/com/sun/tools/jdi/EventRequestManagerImpl.java
Normal file
954
jdkSrc/jdk8/com/sun/tools/jdi/EventRequestManagerImpl.java
Normal file
@@ -0,0 +1,954 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.*;
|
||||
import com.sun.tools.jdi.JDWP;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This interface is used to create and remove Breakpoints, Watchpoints,
|
||||
* etc.
|
||||
* It include implementations of all the request interfaces..
|
||||
*/
|
||||
// Warnings from List filters and List[] requestLists is hard to fix.
|
||||
// Remove SuppressWarning when we fix the warnings from List filters
|
||||
// and List[] requestLists. The generic array is not supported.
|
||||
@SuppressWarnings("unchecked")
|
||||
class EventRequestManagerImpl extends MirrorImpl
|
||||
implements EventRequestManager
|
||||
{
|
||||
List<? extends EventRequest>[] requestLists;
|
||||
private static int methodExitEventCmd = 0;
|
||||
|
||||
static int JDWPtoJDISuspendPolicy(byte jdwpPolicy) {
|
||||
switch(jdwpPolicy) {
|
||||
case JDWP.SuspendPolicy.ALL:
|
||||
return EventRequest.SUSPEND_ALL;
|
||||
case JDWP.SuspendPolicy.EVENT_THREAD:
|
||||
return EventRequest.SUSPEND_EVENT_THREAD;
|
||||
case JDWP.SuspendPolicy.NONE:
|
||||
return EventRequest.SUSPEND_NONE;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal policy constant: " + jdwpPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
static byte JDItoJDWPSuspendPolicy(int jdiPolicy) {
|
||||
switch(jdiPolicy) {
|
||||
case EventRequest.SUSPEND_ALL:
|
||||
return JDWP.SuspendPolicy.ALL;
|
||||
case EventRequest.SUSPEND_EVENT_THREAD:
|
||||
return JDWP.SuspendPolicy.EVENT_THREAD;
|
||||
case EventRequest.SUSPEND_NONE:
|
||||
return JDWP.SuspendPolicy.NONE;
|
||||
default:
|
||||
throw new IllegalArgumentException("Illegal policy constant: " + jdiPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Override superclass back to default equality
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
abstract class EventRequestImpl extends MirrorImpl implements EventRequest {
|
||||
int id;
|
||||
|
||||
/*
|
||||
* This list is not protected by a synchronized wrapper. All
|
||||
* access/modification should be protected by synchronizing on
|
||||
* the enclosing instance of EventRequestImpl.
|
||||
*/
|
||||
List<Object> filters = new ArrayList<>();
|
||||
|
||||
boolean isEnabled = false;
|
||||
boolean deleted = false;
|
||||
byte suspendPolicy = JDWP.SuspendPolicy.ALL;
|
||||
private Map<Object, Object> clientProperties = null;
|
||||
|
||||
EventRequestImpl() {
|
||||
super(EventRequestManagerImpl.this.vm);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Override superclass back to default equality
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
abstract int eventCmd();
|
||||
|
||||
InvalidRequestStateException invalidState() {
|
||||
return new InvalidRequestStateException(toString());
|
||||
}
|
||||
|
||||
String state() {
|
||||
return deleted? " (deleted)" :
|
||||
(isEnabled()? " (enabled)" : " (disabled)");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return all the event request of this kind
|
||||
*/
|
||||
List requestList() {
|
||||
return EventRequestManagerImpl.this.requestList(eventCmd());
|
||||
}
|
||||
|
||||
/**
|
||||
* delete the event request
|
||||
*/
|
||||
void delete() {
|
||||
if (!deleted) {
|
||||
requestList().remove(this);
|
||||
disable(); /* must do BEFORE delete */
|
||||
deleted = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return isEnabled;
|
||||
}
|
||||
|
||||
public void enable() {
|
||||
setEnabled(true);
|
||||
}
|
||||
|
||||
public void disable() {
|
||||
setEnabled(false);
|
||||
}
|
||||
|
||||
public synchronized void setEnabled(boolean val) {
|
||||
if (deleted) {
|
||||
throw invalidState();
|
||||
} else {
|
||||
if (val != isEnabled) {
|
||||
if (isEnabled) {
|
||||
clear();
|
||||
} else {
|
||||
set();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized void addCountFilter(int count) {
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
if (count < 1) {
|
||||
throw new IllegalArgumentException("count is less than one");
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.Count.create(count));
|
||||
}
|
||||
|
||||
public void setSuspendPolicy(int policy) {
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
suspendPolicy = JDItoJDWPSuspendPolicy(policy);
|
||||
}
|
||||
|
||||
public int suspendPolicy() {
|
||||
return JDWPtoJDISuspendPolicy(suspendPolicy);
|
||||
}
|
||||
|
||||
/**
|
||||
* set (enable) the event request
|
||||
*/
|
||||
synchronized void set() {
|
||||
JDWP.EventRequest.Set.Modifier[] mods =
|
||||
filters.toArray(
|
||||
new JDWP.EventRequest.Set.Modifier[filters.size()]);
|
||||
try {
|
||||
id = JDWP.EventRequest.Set.process(vm, (byte)eventCmd(),
|
||||
suspendPolicy, mods).requestID;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
isEnabled = true;
|
||||
}
|
||||
|
||||
synchronized void clear() {
|
||||
try {
|
||||
JDWP.EventRequest.Clear.process(vm, (byte)eventCmd(), id);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
isEnabled = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a small Map
|
||||
* @see #putProperty
|
||||
* @see #getProperty
|
||||
*/
|
||||
private Map<Object, Object> getProperties() {
|
||||
if (clientProperties == null) {
|
||||
clientProperties = new HashMap<Object, Object>(2);
|
||||
}
|
||||
return clientProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the property with the specified key. Only
|
||||
* properties added with <code>putProperty</code> will return
|
||||
* a non-null value.
|
||||
*
|
||||
* @return the value of this property or null
|
||||
* @see #putProperty
|
||||
*/
|
||||
public final Object getProperty(Object key) {
|
||||
if (clientProperties == null) {
|
||||
return null;
|
||||
} else {
|
||||
return getProperties().get(key);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an arbitrary key/value "property" to this component.
|
||||
*
|
||||
* @see #getProperty
|
||||
*/
|
||||
public final void putProperty(Object key, Object value) {
|
||||
if (value != null) {
|
||||
getProperties().put(key, value);
|
||||
} else {
|
||||
getProperties().remove(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ThreadVisibleEventRequestImpl extends EventRequestImpl {
|
||||
public synchronized void addThreadFilter(ThreadReference thread) {
|
||||
validateMirror(thread);
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.ThreadOnly
|
||||
.create((ThreadReferenceImpl)thread));
|
||||
}
|
||||
}
|
||||
|
||||
abstract class ClassVisibleEventRequestImpl
|
||||
extends ThreadVisibleEventRequestImpl {
|
||||
public synchronized void addClassFilter(ReferenceType clazz) {
|
||||
validateMirror(clazz);
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.ClassOnly
|
||||
.create((ReferenceTypeImpl)clazz));
|
||||
}
|
||||
|
||||
public synchronized void addClassFilter(String classPattern) {
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
if (classPattern == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.ClassMatch
|
||||
.create(classPattern));
|
||||
}
|
||||
|
||||
public synchronized void addClassExclusionFilter(String classPattern) {
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
if (classPattern == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.ClassExclude
|
||||
.create(classPattern));
|
||||
}
|
||||
|
||||
public synchronized void addInstanceFilter(ObjectReference instance) {
|
||||
validateMirror(instance);
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
if (!vm.canUseInstanceFilters()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target does not support instance filters");
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.InstanceOnly
|
||||
.create((ObjectReferenceImpl)instance));
|
||||
}
|
||||
}
|
||||
|
||||
class BreakpointRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements BreakpointRequest {
|
||||
private final Location location;
|
||||
|
||||
BreakpointRequestImpl(Location location) {
|
||||
this.location = location;
|
||||
filters.add(0,JDWP.EventRequest.Set.Modifier.LocationOnly
|
||||
.create(location));
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
public Location location() {
|
||||
return location;
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.BREAKPOINT;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "breakpoint request " + location() + state();
|
||||
}
|
||||
}
|
||||
|
||||
class ClassPrepareRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements ClassPrepareRequest {
|
||||
ClassPrepareRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.CLASS_PREPARE;
|
||||
}
|
||||
|
||||
public synchronized void addSourceNameFilter(String sourceNamePattern) {
|
||||
if (isEnabled() || deleted) {
|
||||
throw invalidState();
|
||||
}
|
||||
if (!vm.canUseSourceNameFilters()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target does not support source name filters");
|
||||
}
|
||||
if (sourceNamePattern == null) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.SourceNameMatch
|
||||
.create(sourceNamePattern));
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "class prepare request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class ClassUnloadRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements ClassUnloadRequest {
|
||||
ClassUnloadRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.CLASS_UNLOAD;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "class unload request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class ExceptionRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements ExceptionRequest {
|
||||
ReferenceType exception = null;
|
||||
boolean caught = true;
|
||||
boolean uncaught = true;
|
||||
|
||||
ExceptionRequestImpl(ReferenceType refType,
|
||||
boolean notifyCaught, boolean notifyUncaught) {
|
||||
exception = refType;
|
||||
caught = notifyCaught;
|
||||
uncaught = notifyUncaught;
|
||||
{
|
||||
ReferenceTypeImpl exc;
|
||||
if (exception == null) {
|
||||
exc = new ClassTypeImpl(vm, 0);
|
||||
} else {
|
||||
exc = (ReferenceTypeImpl)exception;
|
||||
}
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.ExceptionOnly.
|
||||
create(exc, caught, uncaught));
|
||||
}
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
public ReferenceType exception() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public boolean notifyCaught() {
|
||||
return caught;
|
||||
}
|
||||
|
||||
public boolean notifyUncaught() {
|
||||
return uncaught;
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.EXCEPTION;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "exception request " + exception() + state();
|
||||
}
|
||||
}
|
||||
|
||||
class MethodEntryRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements MethodEntryRequest {
|
||||
MethodEntryRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.METHOD_ENTRY;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "method entry request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class MethodExitRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements MethodExitRequest {
|
||||
MethodExitRequestImpl() {
|
||||
if (methodExitEventCmd == 0) {
|
||||
/*
|
||||
* If we can get return values, then we always get them.
|
||||
* Thus, for JDI MethodExitRequests, we always use the
|
||||
* same JDWP EventKind. Here we decide which to use and
|
||||
* save it so that it will be used for all future
|
||||
* MethodExitRequests.
|
||||
*
|
||||
* This call to canGetMethodReturnValues can't
|
||||
* be done in the EventRequestManager ctor because that is too early.
|
||||
*/
|
||||
if (vm.canGetMethodReturnValues()) {
|
||||
methodExitEventCmd = JDWP.EventKind.METHOD_EXIT_WITH_RETURN_VALUE;
|
||||
} else {
|
||||
methodExitEventCmd = JDWP.EventKind.METHOD_EXIT;
|
||||
}
|
||||
}
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return EventRequestManagerImpl.methodExitEventCmd;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "method exit request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class MonitorContendedEnterRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements MonitorContendedEnterRequest {
|
||||
MonitorContendedEnterRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.MONITOR_CONTENDED_ENTER;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "monitor contended enter request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class MonitorContendedEnteredRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements MonitorContendedEnteredRequest {
|
||||
MonitorContendedEnteredRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.MONITOR_CONTENDED_ENTERED;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "monitor contended entered request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class MonitorWaitRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements MonitorWaitRequest {
|
||||
MonitorWaitRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.MONITOR_WAIT;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "monitor wait request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class MonitorWaitedRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements MonitorWaitedRequest {
|
||||
MonitorWaitedRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.MONITOR_WAITED;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "monitor waited request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class StepRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements StepRequest {
|
||||
ThreadReferenceImpl thread;
|
||||
int size;
|
||||
int depth;
|
||||
|
||||
StepRequestImpl(ThreadReference thread, int size, int depth) {
|
||||
this.thread = (ThreadReferenceImpl)thread;
|
||||
this.size = size;
|
||||
this.depth = depth;
|
||||
|
||||
/*
|
||||
* Translate size and depth to corresponding JDWP values.
|
||||
*/
|
||||
int jdwpSize;
|
||||
switch (size) {
|
||||
case STEP_MIN:
|
||||
jdwpSize = JDWP.StepSize.MIN;
|
||||
break;
|
||||
case STEP_LINE:
|
||||
jdwpSize = JDWP.StepSize.LINE;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid step size");
|
||||
}
|
||||
|
||||
int jdwpDepth;
|
||||
switch (depth) {
|
||||
case STEP_INTO:
|
||||
jdwpDepth = JDWP.StepDepth.INTO;
|
||||
break;
|
||||
case STEP_OVER:
|
||||
jdwpDepth = JDWP.StepDepth.OVER;
|
||||
break;
|
||||
case STEP_OUT:
|
||||
jdwpDepth = JDWP.StepDepth.OUT;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException("Invalid step depth");
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure this isn't a duplicate
|
||||
*/
|
||||
List<StepRequest> requests = stepRequests();
|
||||
Iterator<StepRequest> iter = requests.iterator();
|
||||
while (iter.hasNext()) {
|
||||
StepRequest request = iter.next();
|
||||
if ((request != this) &&
|
||||
request.isEnabled() &&
|
||||
request.thread().equals(thread)) {
|
||||
throw new DuplicateRequestException(
|
||||
"Only one step request allowed per thread");
|
||||
}
|
||||
}
|
||||
|
||||
filters.add(JDWP.EventRequest.Set.Modifier.Step.
|
||||
create(this.thread, jdwpSize, jdwpDepth));
|
||||
requestList().add(this);
|
||||
|
||||
}
|
||||
public int depth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return size;
|
||||
}
|
||||
|
||||
public ThreadReference thread() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.SINGLE_STEP;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "step request " + thread() + state();
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadDeathRequestImpl extends ThreadVisibleEventRequestImpl
|
||||
implements ThreadDeathRequest {
|
||||
ThreadDeathRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.THREAD_DEATH;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "thread death request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadStartRequestImpl extends ThreadVisibleEventRequestImpl
|
||||
implements ThreadStartRequest {
|
||||
ThreadStartRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.THREAD_START;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "thread start request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WatchpointRequestImpl extends ClassVisibleEventRequestImpl
|
||||
implements WatchpointRequest {
|
||||
final Field field;
|
||||
|
||||
WatchpointRequestImpl(Field field) {
|
||||
this.field = field;
|
||||
filters.add(0,
|
||||
JDWP.EventRequest.Set.Modifier.FieldOnly.create(
|
||||
(ReferenceTypeImpl)field.declaringType(),
|
||||
((FieldImpl)field).ref()));
|
||||
}
|
||||
|
||||
public Field field() {
|
||||
return field;
|
||||
}
|
||||
}
|
||||
|
||||
class AccessWatchpointRequestImpl extends WatchpointRequestImpl
|
||||
implements AccessWatchpointRequest {
|
||||
AccessWatchpointRequestImpl(Field field) {
|
||||
super(field);
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.FIELD_ACCESS;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "access watchpoint request " + field + state();
|
||||
}
|
||||
}
|
||||
|
||||
class ModificationWatchpointRequestImpl extends WatchpointRequestImpl
|
||||
implements ModificationWatchpointRequest {
|
||||
ModificationWatchpointRequestImpl(Field field) {
|
||||
super(field);
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.FIELD_MODIFICATION;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "modification watchpoint request " + field + state();
|
||||
}
|
||||
}
|
||||
|
||||
class VMDeathRequestImpl extends EventRequestImpl
|
||||
implements VMDeathRequest {
|
||||
VMDeathRequestImpl() {
|
||||
requestList().add(this);
|
||||
}
|
||||
|
||||
int eventCmd() {
|
||||
return JDWP.EventKind.VM_DEATH;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "VM death request " + state();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
EventRequestManagerImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
java.lang.reflect.Field[] ekinds =
|
||||
JDWP.EventKind.class.getDeclaredFields();
|
||||
int highest = 0;
|
||||
for (int i = 0; i < ekinds.length; ++i) {
|
||||
int val;
|
||||
try {
|
||||
val = ekinds[i].getInt(null);
|
||||
} catch (IllegalAccessException exc) {
|
||||
throw new RuntimeException("Got: " + exc);
|
||||
}
|
||||
if (val > highest) {
|
||||
highest = val;
|
||||
}
|
||||
}
|
||||
requestLists = new List[highest+1];
|
||||
for (int i=0; i <= highest; i++) {
|
||||
requestLists[i] = new ArrayList<>();
|
||||
}
|
||||
}
|
||||
|
||||
public ClassPrepareRequest createClassPrepareRequest() {
|
||||
return new ClassPrepareRequestImpl();
|
||||
}
|
||||
|
||||
public ClassUnloadRequest createClassUnloadRequest() {
|
||||
return new ClassUnloadRequestImpl();
|
||||
}
|
||||
|
||||
public ExceptionRequest createExceptionRequest(ReferenceType refType,
|
||||
boolean notifyCaught,
|
||||
boolean notifyUncaught) {
|
||||
validateMirrorOrNull(refType);
|
||||
return new ExceptionRequestImpl(refType, notifyCaught, notifyUncaught);
|
||||
}
|
||||
|
||||
public StepRequest createStepRequest(ThreadReference thread,
|
||||
int size, int depth) {
|
||||
validateMirror(thread);
|
||||
return new StepRequestImpl(thread, size, depth);
|
||||
}
|
||||
|
||||
public ThreadDeathRequest createThreadDeathRequest() {
|
||||
return new ThreadDeathRequestImpl();
|
||||
}
|
||||
|
||||
public ThreadStartRequest createThreadStartRequest() {
|
||||
return new ThreadStartRequestImpl();
|
||||
}
|
||||
|
||||
public MethodEntryRequest createMethodEntryRequest() {
|
||||
return new MethodEntryRequestImpl();
|
||||
}
|
||||
|
||||
public MethodExitRequest createMethodExitRequest() {
|
||||
return new MethodExitRequestImpl();
|
||||
}
|
||||
|
||||
public MonitorContendedEnterRequest createMonitorContendedEnterRequest() {
|
||||
if (!vm.canRequestMonitorEvents()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support requesting Monitor events");
|
||||
}
|
||||
return new MonitorContendedEnterRequestImpl();
|
||||
}
|
||||
|
||||
public MonitorContendedEnteredRequest createMonitorContendedEnteredRequest() {
|
||||
if (!vm.canRequestMonitorEvents()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support requesting Monitor events");
|
||||
}
|
||||
return new MonitorContendedEnteredRequestImpl();
|
||||
}
|
||||
|
||||
public MonitorWaitRequest createMonitorWaitRequest() {
|
||||
if (!vm.canRequestMonitorEvents()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support requesting Monitor events");
|
||||
}
|
||||
return new MonitorWaitRequestImpl();
|
||||
}
|
||||
|
||||
public MonitorWaitedRequest createMonitorWaitedRequest() {
|
||||
if (!vm.canRequestMonitorEvents()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support requesting Monitor events");
|
||||
}
|
||||
return new MonitorWaitedRequestImpl();
|
||||
}
|
||||
|
||||
public BreakpointRequest createBreakpointRequest(Location location) {
|
||||
validateMirror(location);
|
||||
if (location.codeIndex() == -1) {
|
||||
throw new NativeMethodException("Cannot set breakpoints on native methods");
|
||||
}
|
||||
return new BreakpointRequestImpl(location);
|
||||
}
|
||||
|
||||
public AccessWatchpointRequest
|
||||
createAccessWatchpointRequest(Field field) {
|
||||
validateMirror(field);
|
||||
if (!vm.canWatchFieldAccess()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support access watchpoints");
|
||||
}
|
||||
return new AccessWatchpointRequestImpl(field);
|
||||
}
|
||||
|
||||
public ModificationWatchpointRequest
|
||||
createModificationWatchpointRequest(Field field) {
|
||||
validateMirror(field);
|
||||
if (!vm.canWatchFieldModification()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support modification watchpoints");
|
||||
}
|
||||
return new ModificationWatchpointRequestImpl(field);
|
||||
}
|
||||
|
||||
public VMDeathRequest createVMDeathRequest() {
|
||||
if (!vm.canRequestVMDeathEvent()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target VM does not support requesting VM death events");
|
||||
}
|
||||
return new VMDeathRequestImpl();
|
||||
}
|
||||
|
||||
public void deleteEventRequest(EventRequest eventRequest) {
|
||||
validateMirror(eventRequest);
|
||||
((EventRequestImpl)eventRequest).delete();
|
||||
}
|
||||
|
||||
public void deleteEventRequests(List<? extends EventRequest> eventRequests) {
|
||||
validateMirrors(eventRequests);
|
||||
// copy the eventRequests to avoid ConcurrentModificationException
|
||||
Iterator<? extends EventRequest> iter = (new ArrayList<>(eventRequests)).iterator();
|
||||
while (iter.hasNext()) {
|
||||
((EventRequestImpl)iter.next()).delete();
|
||||
}
|
||||
}
|
||||
|
||||
public void deleteAllBreakpoints() {
|
||||
requestList(JDWP.EventKind.BREAKPOINT).clear();
|
||||
|
||||
try {
|
||||
JDWP.EventRequest.ClearAllBreakpoints.process(vm);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
public List<StepRequest> stepRequests() {
|
||||
return (List<StepRequest>)unmodifiableRequestList(JDWP.EventKind.SINGLE_STEP);
|
||||
}
|
||||
|
||||
public List<ClassPrepareRequest> classPrepareRequests() {
|
||||
return (List<ClassPrepareRequest>)unmodifiableRequestList(JDWP.EventKind.CLASS_PREPARE);
|
||||
}
|
||||
|
||||
public List<ClassUnloadRequest> classUnloadRequests() {
|
||||
return (List<ClassUnloadRequest>)unmodifiableRequestList(JDWP.EventKind.CLASS_UNLOAD);
|
||||
}
|
||||
|
||||
public List<ThreadStartRequest> threadStartRequests() {
|
||||
return (List<ThreadStartRequest>)unmodifiableRequestList(JDWP.EventKind.THREAD_START);
|
||||
}
|
||||
|
||||
public List<ThreadDeathRequest> threadDeathRequests() {
|
||||
return (List<ThreadDeathRequest>)unmodifiableRequestList(JDWP.EventKind.THREAD_DEATH);
|
||||
}
|
||||
|
||||
public List<ExceptionRequest> exceptionRequests() {
|
||||
return (List<ExceptionRequest>)unmodifiableRequestList(JDWP.EventKind.EXCEPTION);
|
||||
}
|
||||
|
||||
public List<BreakpointRequest> breakpointRequests() {
|
||||
return (List<BreakpointRequest>)unmodifiableRequestList(JDWP.EventKind.BREAKPOINT);
|
||||
}
|
||||
|
||||
public List<AccessWatchpointRequest> accessWatchpointRequests() {
|
||||
return (List<AccessWatchpointRequest>)unmodifiableRequestList(JDWP.EventKind.FIELD_ACCESS);
|
||||
}
|
||||
|
||||
public List<ModificationWatchpointRequest> modificationWatchpointRequests() {
|
||||
return (List<ModificationWatchpointRequest>)unmodifiableRequestList(JDWP.EventKind.FIELD_MODIFICATION);
|
||||
}
|
||||
|
||||
public List<MethodEntryRequest> methodEntryRequests() {
|
||||
return (List<MethodEntryRequest>)unmodifiableRequestList(JDWP.EventKind.METHOD_ENTRY);
|
||||
}
|
||||
|
||||
public List<MethodExitRequest> methodExitRequests() {
|
||||
return (List<MethodExitRequest>)unmodifiableRequestList(
|
||||
EventRequestManagerImpl.methodExitEventCmd);
|
||||
}
|
||||
|
||||
public List<MonitorContendedEnterRequest> monitorContendedEnterRequests() {
|
||||
return (List<MonitorContendedEnterRequest>)unmodifiableRequestList(JDWP.EventKind.MONITOR_CONTENDED_ENTER);
|
||||
}
|
||||
|
||||
public List<MonitorContendedEnteredRequest> monitorContendedEnteredRequests() {
|
||||
return (List<MonitorContendedEnteredRequest>)unmodifiableRequestList(JDWP.EventKind.MONITOR_CONTENDED_ENTERED);
|
||||
}
|
||||
|
||||
public List<MonitorWaitRequest> monitorWaitRequests() {
|
||||
return (List<MonitorWaitRequest>)unmodifiableRequestList(JDWP.EventKind.MONITOR_WAIT);
|
||||
}
|
||||
|
||||
public List<MonitorWaitedRequest> monitorWaitedRequests() {
|
||||
return (List<MonitorWaitedRequest>)unmodifiableRequestList(JDWP.EventKind.MONITOR_WAITED);
|
||||
}
|
||||
|
||||
public List<VMDeathRequest> vmDeathRequests() {
|
||||
return (List<VMDeathRequest>)unmodifiableRequestList(JDWP.EventKind.VM_DEATH);
|
||||
}
|
||||
|
||||
List<? extends EventRequest> unmodifiableRequestList(int eventCmd) {
|
||||
return Collections.unmodifiableList(requestList(eventCmd));
|
||||
}
|
||||
|
||||
EventRequest request(int eventCmd, int requestId) {
|
||||
List<? extends EventRequest> rl = requestList(eventCmd);
|
||||
for (int i = rl.size() - 1; i >= 0; i--) {
|
||||
EventRequestImpl er = (EventRequestImpl)rl.get(i);
|
||||
if (er.id == requestId) {
|
||||
return er;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
List<? extends EventRequest> requestList(int eventCmd) {
|
||||
return requestLists[eventCmd];
|
||||
}
|
||||
|
||||
}
|
||||
879
jdkSrc/jdk8/com/sun/tools/jdi/EventSetImpl.java
Normal file
879
jdkSrc/jdk8/com/sun/tools/jdi/EventSetImpl.java
Normal file
@@ -0,0 +1,879 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
import com.sun.jdi.request.*;
|
||||
|
||||
import java.util.*;
|
||||
enum EventDestination {UNKNOWN_EVENT, INTERNAL_EVENT, CLIENT_EVENT};
|
||||
|
||||
/*
|
||||
* An EventSet is normally created by the transport reader thread when
|
||||
* it reads a JDWP Composite command. The constructor doesn't unpack
|
||||
* the events contained in the Composite command and create EventImpls
|
||||
* for them because that process might involve calling back into the back-end
|
||||
* which should not be done by the transport reader thread. Instead,
|
||||
* the raw bytes of the packet are read and stored in the EventSet.
|
||||
* The EventSet is then added to each EventQueue. When an EventSet is
|
||||
* removed from an EventQueue, the EventSetImpl.build() method is called.
|
||||
* This method reads the packet bytes and creates the actual EventImpl objects.
|
||||
* build() also filters out events for our internal handler and puts them in
|
||||
* their own EventSet. This means that the EventImpls that are in the EventSet
|
||||
* that is on the queues are all for client requests.
|
||||
*/
|
||||
public class EventSetImpl extends ArrayList<Event> implements EventSet {
|
||||
private static final long serialVersionUID = -4857338819787924570L;
|
||||
private VirtualMachineImpl vm; // we implement Mirror
|
||||
private Packet pkt;
|
||||
private byte suspendPolicy;
|
||||
private EventSetImpl internalEventSet;
|
||||
|
||||
public String toString() {
|
||||
String string = "event set, policy:" + suspendPolicy +
|
||||
", count:" + this.size() + " = {";
|
||||
boolean first = true;
|
||||
for (Event event : this) {
|
||||
if (!first) {
|
||||
string += ", ";
|
||||
}
|
||||
string += event.toString();
|
||||
first = false;
|
||||
}
|
||||
string += "}";
|
||||
return string;
|
||||
}
|
||||
|
||||
abstract class EventImpl extends MirrorImpl implements Event {
|
||||
|
||||
private final byte eventCmd;
|
||||
private final int requestID;
|
||||
// This is set only for client requests, not internal requests.
|
||||
private final EventRequest request;
|
||||
|
||||
/**
|
||||
* Constructor for events.
|
||||
*/
|
||||
protected EventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
|
||||
int requestID) {
|
||||
super(EventSetImpl.this.vm);
|
||||
this.eventCmd = evt.eventKind();
|
||||
this.requestID = requestID;
|
||||
EventRequestManagerImpl ermi = EventSetImpl.this.
|
||||
vm.eventRequestManagerImpl();
|
||||
this.request = ermi.request(eventCmd, requestID);
|
||||
}
|
||||
|
||||
/*
|
||||
* Override superclass back to default equality
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
return this == obj;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return System.identityHashCode(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for VM disconnected events.
|
||||
*/
|
||||
protected EventImpl(byte eventCmd) {
|
||||
super(EventSetImpl.this.vm);
|
||||
this.eventCmd = eventCmd;
|
||||
this.requestID = 0;
|
||||
this.request = null;
|
||||
}
|
||||
|
||||
public EventRequest request() {
|
||||
return request;
|
||||
}
|
||||
|
||||
int requestID() {
|
||||
return requestID;
|
||||
}
|
||||
|
||||
EventDestination destination() {
|
||||
/*
|
||||
* We need to decide if this event is for
|
||||
* 1. an internal request
|
||||
* 2. a client request that is no longer available, ie
|
||||
* it has been deleted, or disabled and re-enabled
|
||||
* which gives it a new ID.
|
||||
* 3. a current client request that is disabled
|
||||
* 4. a current enabled client request.
|
||||
*
|
||||
* We will filter this set into a set
|
||||
* that contains only 1s for our internal queue
|
||||
* and a set that contains only 4s for our client queue.
|
||||
* If we get an EventSet that contains only 2 and 3
|
||||
* then we have to resume it if it is not SUSPEND_NONE
|
||||
* because no one else will.
|
||||
*/
|
||||
if (requestID == 0) {
|
||||
/* An unsolicited event. These have traditionally
|
||||
* been treated as client events.
|
||||
*/
|
||||
return EventDestination.CLIENT_EVENT;
|
||||
}
|
||||
|
||||
// Is this an event for a current client request?
|
||||
if (request == null) {
|
||||
// Nope. Is it an event for an internal request?
|
||||
EventRequestManagerImpl ermi = this.vm.getInternalEventRequestManager();
|
||||
if (ermi.request(eventCmd, requestID) != null) {
|
||||
// Yep
|
||||
return EventDestination.INTERNAL_EVENT;
|
||||
}
|
||||
return EventDestination.UNKNOWN_EVENT;
|
||||
}
|
||||
|
||||
// We found a client request
|
||||
if (request.isEnabled()) {
|
||||
return EventDestination.CLIENT_EVENT;
|
||||
}
|
||||
return EventDestination.UNKNOWN_EVENT;
|
||||
}
|
||||
|
||||
abstract String eventName();
|
||||
|
||||
public String toString() {
|
||||
return eventName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
abstract class ThreadedEventImpl extends EventImpl {
|
||||
private ThreadReference thread;
|
||||
|
||||
ThreadedEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
|
||||
int requestID, ThreadReference thread) {
|
||||
super(evt, requestID);
|
||||
this.thread = thread;
|
||||
}
|
||||
|
||||
public ThreadReference thread() {
|
||||
return thread;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return eventName() + " in thread " + thread.name();
|
||||
}
|
||||
}
|
||||
|
||||
abstract class LocatableEventImpl extends ThreadedEventImpl
|
||||
implements Locatable {
|
||||
private Location location;
|
||||
|
||||
LocatableEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
|
||||
int requestID,
|
||||
ThreadReference thread, Location location) {
|
||||
super(evt, requestID, thread);
|
||||
this.location = location;
|
||||
}
|
||||
|
||||
public Location location() {
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* For MethodEntry and MethodExit
|
||||
*/
|
||||
public Method method() {
|
||||
return location.method();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return eventName() + "@" +
|
||||
((location() == null) ? " null" : location().toString()) +
|
||||
" in thread " + thread().name();
|
||||
}
|
||||
}
|
||||
|
||||
class BreakpointEventImpl extends LocatableEventImpl
|
||||
implements BreakpointEvent {
|
||||
BreakpointEventImpl(JDWP.Event.Composite.Events.Breakpoint evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "BreakpointEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class StepEventImpl extends LocatableEventImpl implements StepEvent {
|
||||
StepEventImpl(JDWP.Event.Composite.Events.SingleStep evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "StepEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class MethodEntryEventImpl extends LocatableEventImpl
|
||||
implements MethodEntryEvent {
|
||||
MethodEntryEventImpl(JDWP.Event.Composite.Events.MethodEntry evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "MethodEntryEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class MethodExitEventImpl extends LocatableEventImpl
|
||||
implements MethodExitEvent {
|
||||
private Value returnVal = null;
|
||||
|
||||
MethodExitEventImpl(JDWP.Event.Composite.Events.MethodExit evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
}
|
||||
|
||||
MethodExitEventImpl(JDWP.Event.Composite.Events.MethodExitWithReturnValue evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
returnVal = evt.value;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "MethodExitEvent";
|
||||
}
|
||||
|
||||
public Value returnValue() {
|
||||
if (!this.vm.canGetMethodReturnValues()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target does not support return values in MethodExit events");
|
||||
}
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class MonitorContendedEnterEventImpl extends LocatableEventImpl
|
||||
implements MonitorContendedEnterEvent {
|
||||
private ObjectReference monitor = null;
|
||||
|
||||
MonitorContendedEnterEventImpl(JDWP.Event.Composite.Events.MonitorContendedEnter evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
this.monitor = evt.object;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "MonitorContendedEnter";
|
||||
}
|
||||
|
||||
public ObjectReference monitor() {
|
||||
return monitor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class MonitorContendedEnteredEventImpl extends LocatableEventImpl
|
||||
implements MonitorContendedEnteredEvent {
|
||||
private ObjectReference monitor = null;
|
||||
|
||||
MonitorContendedEnteredEventImpl(JDWP.Event.Composite.Events.MonitorContendedEntered evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
this.monitor = evt.object;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "MonitorContendedEntered";
|
||||
}
|
||||
|
||||
public ObjectReference monitor() {
|
||||
return monitor;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class MonitorWaitEventImpl extends LocatableEventImpl
|
||||
implements MonitorWaitEvent {
|
||||
private ObjectReference monitor = null;
|
||||
private long timeout;
|
||||
|
||||
MonitorWaitEventImpl(JDWP.Event.Composite.Events.MonitorWait evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
this.monitor = evt.object;
|
||||
this.timeout = evt.timeout;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "MonitorWait";
|
||||
}
|
||||
|
||||
public ObjectReference monitor() {
|
||||
return monitor;
|
||||
};
|
||||
|
||||
public long timeout() {
|
||||
return timeout;
|
||||
}
|
||||
}
|
||||
|
||||
class MonitorWaitedEventImpl extends LocatableEventImpl
|
||||
implements MonitorWaitedEvent {
|
||||
private ObjectReference monitor = null;
|
||||
private boolean timed_out;
|
||||
|
||||
MonitorWaitedEventImpl(JDWP.Event.Composite.Events.MonitorWaited evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
this.monitor = evt.object;
|
||||
this.timed_out = evt.timed_out;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "MonitorWaited";
|
||||
}
|
||||
|
||||
public ObjectReference monitor() {
|
||||
return monitor;
|
||||
};
|
||||
|
||||
public boolean timedout() {
|
||||
return timed_out;
|
||||
}
|
||||
}
|
||||
|
||||
class ClassPrepareEventImpl extends ThreadedEventImpl
|
||||
implements ClassPrepareEvent {
|
||||
private ReferenceType referenceType;
|
||||
|
||||
ClassPrepareEventImpl(JDWP.Event.Composite.Events.ClassPrepare evt) {
|
||||
super(evt, evt.requestID, evt.thread);
|
||||
referenceType = this.vm.referenceType(evt.typeID, evt.refTypeTag,
|
||||
evt.signature);
|
||||
((ReferenceTypeImpl)referenceType).setStatus(evt.status);
|
||||
}
|
||||
|
||||
public ReferenceType referenceType() {
|
||||
return referenceType;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "ClassPrepareEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class ClassUnloadEventImpl extends EventImpl implements ClassUnloadEvent {
|
||||
private String classSignature;
|
||||
|
||||
ClassUnloadEventImpl(JDWP.Event.Composite.Events.ClassUnload evt) {
|
||||
super(evt, evt.requestID);
|
||||
this.classSignature = evt.signature;
|
||||
}
|
||||
|
||||
public String className() {
|
||||
return classSignature.substring(1, classSignature.length()-1)
|
||||
.replace('/', '.');
|
||||
}
|
||||
|
||||
public String classSignature() {
|
||||
return classSignature;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "ClassUnloadEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class ExceptionEventImpl extends LocatableEventImpl
|
||||
implements ExceptionEvent {
|
||||
private ObjectReference exception;
|
||||
private Location catchLocation;
|
||||
|
||||
ExceptionEventImpl(JDWP.Event.Composite.Events.Exception evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location);
|
||||
this.exception = evt.exception;
|
||||
this.catchLocation = evt.catchLocation;
|
||||
}
|
||||
|
||||
public ObjectReference exception() {
|
||||
return exception;
|
||||
}
|
||||
|
||||
public Location catchLocation() {
|
||||
return catchLocation;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "ExceptionEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadDeathEventImpl extends ThreadedEventImpl
|
||||
implements ThreadDeathEvent {
|
||||
ThreadDeathEventImpl(JDWP.Event.Composite.Events.ThreadDeath evt) {
|
||||
super(evt, evt.requestID, evt.thread);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "ThreadDeathEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class ThreadStartEventImpl extends ThreadedEventImpl
|
||||
implements ThreadStartEvent {
|
||||
ThreadStartEventImpl(JDWP.Event.Composite.Events.ThreadStart evt) {
|
||||
super(evt, evt.requestID, evt.thread);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "ThreadStartEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class VMStartEventImpl extends ThreadedEventImpl
|
||||
implements VMStartEvent {
|
||||
VMStartEventImpl(JDWP.Event.Composite.Events.VMStart evt) {
|
||||
super(evt, evt.requestID, evt.thread);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "VMStartEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class VMDeathEventImpl extends EventImpl implements VMDeathEvent {
|
||||
|
||||
VMDeathEventImpl(JDWP.Event.Composite.Events.VMDeath evt) {
|
||||
super(evt, evt.requestID);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "VMDeathEvent";
|
||||
}
|
||||
}
|
||||
|
||||
class VMDisconnectEventImpl extends EventImpl
|
||||
implements VMDisconnectEvent {
|
||||
|
||||
VMDisconnectEventImpl() {
|
||||
super((byte)JDWP.EventKind.VM_DISCONNECTED);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "VMDisconnectEvent";
|
||||
}
|
||||
}
|
||||
|
||||
abstract class WatchpointEventImpl extends LocatableEventImpl
|
||||
implements WatchpointEvent {
|
||||
private final ReferenceTypeImpl refType;
|
||||
private final long fieldID;
|
||||
private final ObjectReference object;
|
||||
private Field field = null;
|
||||
|
||||
WatchpointEventImpl(JDWP.Event.Composite.Events.EventsCommon evt,
|
||||
int requestID,
|
||||
ThreadReference thread, Location location,
|
||||
byte refTypeTag, long typeID, long fieldID,
|
||||
ObjectReference object) {
|
||||
super(evt, requestID, thread, location);
|
||||
this.refType = this.vm.referenceType(typeID, refTypeTag);
|
||||
this.fieldID = fieldID;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public Field field() {
|
||||
if (field == null) {
|
||||
field = refType.getFieldMirror(fieldID);
|
||||
}
|
||||
return field;
|
||||
}
|
||||
|
||||
public ObjectReference object() {
|
||||
return object;
|
||||
}
|
||||
|
||||
public Value valueCurrent() {
|
||||
if (object == null) {
|
||||
return refType.getValue(field());
|
||||
} else {
|
||||
return object.getValue(field());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class AccessWatchpointEventImpl extends WatchpointEventImpl
|
||||
implements AccessWatchpointEvent {
|
||||
|
||||
AccessWatchpointEventImpl(JDWP.Event.Composite.Events.FieldAccess evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location,
|
||||
evt.refTypeTag, evt.typeID, evt.fieldID, evt.object);
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "AccessWatchpoint";
|
||||
}
|
||||
}
|
||||
|
||||
class ModificationWatchpointEventImpl extends WatchpointEventImpl
|
||||
implements ModificationWatchpointEvent {
|
||||
Value newValue;
|
||||
|
||||
ModificationWatchpointEventImpl(
|
||||
JDWP.Event.Composite.Events.FieldModification evt) {
|
||||
super(evt, evt.requestID, evt.thread, evt.location,
|
||||
evt.refTypeTag, evt.typeID, evt.fieldID, evt.object);
|
||||
this.newValue = evt.valueToBe;
|
||||
}
|
||||
|
||||
public Value valueToBe() {
|
||||
return newValue;
|
||||
}
|
||||
|
||||
String eventName() {
|
||||
return "ModificationWatchpoint";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Events are constructed on the thread which reads all data from the
|
||||
* transport. This means that the packet cannot be converted to real
|
||||
* JDI objects as that may involve further communications with the
|
||||
* back end which would deadlock.
|
||||
*
|
||||
* Hence the {@link #build()} method below called by EventQueue.
|
||||
*/
|
||||
EventSetImpl(VirtualMachine aVm, Packet pkt) {
|
||||
super();
|
||||
|
||||
// From "MirrorImpl":
|
||||
// Yes, its a bit of a hack. But by doing it this
|
||||
// way, this is the only place we have to change
|
||||
// typing to substitute a new impl.
|
||||
vm = (VirtualMachineImpl)aVm;
|
||||
|
||||
this.pkt = pkt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for special events like VM disconnected
|
||||
*/
|
||||
EventSetImpl(VirtualMachine aVm, byte eventCmd) {
|
||||
this(aVm, null);
|
||||
suspendPolicy = JDWP.SuspendPolicy.NONE;
|
||||
switch (eventCmd) {
|
||||
case JDWP.EventKind.VM_DISCONNECTED:
|
||||
addEvent(new VMDisconnectEventImpl());
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new InternalException("Bad singleton event code");
|
||||
}
|
||||
}
|
||||
|
||||
private void addEvent(EventImpl evt) {
|
||||
// Note that this class has a public add method that throws
|
||||
// an exception so that clients can't modify the EventSet
|
||||
super.add(evt);
|
||||
}
|
||||
|
||||
/*
|
||||
* Complete the construction of an EventSet. This is called from
|
||||
* an event handler thread. It upacks the JDWP events inside
|
||||
* the packet and creates EventImpls for them. The EventSet is already
|
||||
* on EventQueues when this is called, so it has to be synch.
|
||||
*/
|
||||
synchronized void build() {
|
||||
if (pkt == null) {
|
||||
return;
|
||||
}
|
||||
PacketStream ps = new PacketStream(vm, pkt);
|
||||
JDWP.Event.Composite compEvt = new JDWP.Event.Composite(vm, ps);
|
||||
suspendPolicy = compEvt.suspendPolicy;
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
switch(suspendPolicy) {
|
||||
case JDWP.SuspendPolicy.ALL:
|
||||
vm.printTrace("EventSet: SUSPEND_ALL");
|
||||
break;
|
||||
|
||||
case JDWP.SuspendPolicy.EVENT_THREAD:
|
||||
vm.printTrace("EventSet: SUSPEND_EVENT_THREAD");
|
||||
break;
|
||||
|
||||
case JDWP.SuspendPolicy.NONE:
|
||||
vm.printTrace("EventSet: SUSPEND_NONE");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ThreadReference fix6485605 = null;
|
||||
for (int i = 0; i < compEvt.events.length; i++) {
|
||||
EventImpl evt = createEvent(compEvt.events[i]);
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
try {
|
||||
vm.printTrace("Event: " + evt);
|
||||
} catch (VMDisconnectedException ee) {
|
||||
// ignore - see bug 6502716
|
||||
}
|
||||
}
|
||||
|
||||
switch (evt.destination()) {
|
||||
case UNKNOWN_EVENT:
|
||||
// Ignore disabled, deleted, unknown events, but
|
||||
// save the thread if there is one since we might
|
||||
// have to resume it. Note that events for different
|
||||
// threads can't be in the same event set.
|
||||
if (evt instanceof ThreadedEventImpl &&
|
||||
suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
|
||||
fix6485605 = ((ThreadedEventImpl)evt).thread();
|
||||
}
|
||||
continue;
|
||||
case CLIENT_EVENT:
|
||||
addEvent(evt);
|
||||
break;
|
||||
case INTERNAL_EVENT:
|
||||
if (internalEventSet == null) {
|
||||
internalEventSet = new EventSetImpl(this.vm, null);
|
||||
}
|
||||
internalEventSet.addEvent(evt);
|
||||
break;
|
||||
default:
|
||||
throw new InternalException("Invalid event destination");
|
||||
}
|
||||
}
|
||||
pkt = null; // No longer needed - free it up
|
||||
|
||||
// Avoid hangs described in 6296125, 6293795
|
||||
if (super.size() == 0) {
|
||||
// This set has no client events. If we don't do
|
||||
// needed resumes, no one else is going to.
|
||||
if (suspendPolicy == JDWP.SuspendPolicy.ALL) {
|
||||
vm.resume();
|
||||
} else if (suspendPolicy == JDWP.SuspendPolicy.EVENT_THREAD) {
|
||||
// See bug 6485605.
|
||||
if (fix6485605 != null) {
|
||||
fix6485605.resume();
|
||||
} else {
|
||||
// apparently, there is nothing to resume.
|
||||
}
|
||||
}
|
||||
suspendPolicy = JDWP.SuspendPolicy.NONE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out internal events
|
||||
*/
|
||||
EventSet userFilter() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter out user events.
|
||||
*/
|
||||
EventSet internalFilter() {
|
||||
return this.internalEventSet;
|
||||
}
|
||||
|
||||
EventImpl createEvent(JDWP.Event.Composite.Events evt) {
|
||||
JDWP.Event.Composite.Events.EventsCommon comm = evt.aEventsCommon;
|
||||
switch (evt.eventKind) {
|
||||
case JDWP.EventKind.THREAD_START:
|
||||
return new ThreadStartEventImpl(
|
||||
(JDWP.Event.Composite.Events.ThreadStart)comm);
|
||||
|
||||
case JDWP.EventKind.THREAD_END:
|
||||
return new ThreadDeathEventImpl(
|
||||
(JDWP.Event.Composite.Events.ThreadDeath)comm);
|
||||
|
||||
case JDWP.EventKind.EXCEPTION:
|
||||
return new ExceptionEventImpl(
|
||||
(JDWP.Event.Composite.Events.Exception)comm);
|
||||
|
||||
case JDWP.EventKind.BREAKPOINT:
|
||||
return new BreakpointEventImpl(
|
||||
(JDWP.Event.Composite.Events.Breakpoint)comm);
|
||||
|
||||
case JDWP.EventKind.METHOD_ENTRY:
|
||||
return new MethodEntryEventImpl(
|
||||
(JDWP.Event.Composite.Events.MethodEntry)comm);
|
||||
|
||||
case JDWP.EventKind.METHOD_EXIT:
|
||||
return new MethodExitEventImpl(
|
||||
(JDWP.Event.Composite.Events.MethodExit)comm);
|
||||
|
||||
case JDWP.EventKind.METHOD_EXIT_WITH_RETURN_VALUE:
|
||||
return new MethodExitEventImpl(
|
||||
(JDWP.Event.Composite.Events.MethodExitWithReturnValue)comm);
|
||||
|
||||
case JDWP.EventKind.FIELD_ACCESS:
|
||||
return new AccessWatchpointEventImpl(
|
||||
(JDWP.Event.Composite.Events.FieldAccess)comm);
|
||||
|
||||
case JDWP.EventKind.FIELD_MODIFICATION:
|
||||
return new ModificationWatchpointEventImpl(
|
||||
(JDWP.Event.Composite.Events.FieldModification)comm);
|
||||
|
||||
case JDWP.EventKind.SINGLE_STEP:
|
||||
return new StepEventImpl(
|
||||
(JDWP.Event.Composite.Events.SingleStep)comm);
|
||||
|
||||
case JDWP.EventKind.CLASS_PREPARE:
|
||||
return new ClassPrepareEventImpl(
|
||||
(JDWP.Event.Composite.Events.ClassPrepare)comm);
|
||||
|
||||
case JDWP.EventKind.CLASS_UNLOAD:
|
||||
return new ClassUnloadEventImpl(
|
||||
(JDWP.Event.Composite.Events.ClassUnload)comm);
|
||||
|
||||
case JDWP.EventKind.MONITOR_CONTENDED_ENTER:
|
||||
return new MonitorContendedEnterEventImpl(
|
||||
(JDWP.Event.Composite.Events.MonitorContendedEnter)comm);
|
||||
|
||||
case JDWP.EventKind.MONITOR_CONTENDED_ENTERED:
|
||||
return new MonitorContendedEnteredEventImpl(
|
||||
(JDWP.Event.Composite.Events.MonitorContendedEntered)comm);
|
||||
|
||||
case JDWP.EventKind.MONITOR_WAIT:
|
||||
return new MonitorWaitEventImpl(
|
||||
(JDWP.Event.Composite.Events.MonitorWait)comm);
|
||||
|
||||
case JDWP.EventKind.MONITOR_WAITED:
|
||||
return new MonitorWaitedEventImpl(
|
||||
(JDWP.Event.Composite.Events.MonitorWaited)comm);
|
||||
|
||||
case JDWP.EventKind.VM_START:
|
||||
return new VMStartEventImpl(
|
||||
(JDWP.Event.Composite.Events.VMStart)comm);
|
||||
|
||||
case JDWP.EventKind.VM_DEATH:
|
||||
return new VMDeathEventImpl(
|
||||
(JDWP.Event.Composite.Events.VMDeath)comm);
|
||||
|
||||
default:
|
||||
// Ignore unknown event types
|
||||
System.err.println("Ignoring event cmd " +
|
||||
evt.eventKind + " from the VM");
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public VirtualMachine virtualMachine() {
|
||||
return vm;
|
||||
}
|
||||
|
||||
public int suspendPolicy() {
|
||||
return EventRequestManagerImpl.JDWPtoJDISuspendPolicy(suspendPolicy);
|
||||
}
|
||||
|
||||
private ThreadReference eventThread() {
|
||||
for (Event event : this) {
|
||||
if (event instanceof ThreadedEventImpl) {
|
||||
return ((ThreadedEventImpl)event).thread();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
switch (suspendPolicy()) {
|
||||
case EventRequest.SUSPEND_ALL:
|
||||
vm.resume();
|
||||
break;
|
||||
case EventRequest.SUSPEND_EVENT_THREAD:
|
||||
ThreadReference thread = eventThread();
|
||||
if (thread == null) {
|
||||
throw new InternalException("Inconsistent suspend policy");
|
||||
}
|
||||
thread.resume();
|
||||
break;
|
||||
case EventRequest.SUSPEND_NONE:
|
||||
// Do nothing
|
||||
break;
|
||||
default:
|
||||
throw new InternalException("Invalid suspend policy");
|
||||
}
|
||||
}
|
||||
|
||||
public Iterator<Event> iterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
public EventIterator eventIterator() {
|
||||
return new Itr();
|
||||
}
|
||||
|
||||
public class Itr implements EventIterator {
|
||||
/**
|
||||
* Index of element to be returned by subsequent call to next.
|
||||
*/
|
||||
int cursor = 0;
|
||||
|
||||
public boolean hasNext() {
|
||||
return cursor != size();
|
||||
}
|
||||
|
||||
public Event next() {
|
||||
try {
|
||||
Event nxt = get(cursor);
|
||||
++cursor;
|
||||
return nxt;
|
||||
} catch(IndexOutOfBoundsException e) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
}
|
||||
|
||||
public Event nextEvent() {
|
||||
return next();
|
||||
}
|
||||
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Spliterator<Event> spliterator() {
|
||||
return Spliterators.spliterator(this, Spliterator.DISTINCT);
|
||||
}
|
||||
|
||||
/* below make this unmodifiable */
|
||||
|
||||
public boolean add(Event o){
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean remove(Object o) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean addAll(Collection<? extends Event> coll) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean removeAll(Collection<?> coll) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public boolean retainAll(Collection<?> coll) {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
public void clear() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
}
|
||||
106
jdkSrc/jdk8/com/sun/tools/jdi/FieldImpl.java
Normal file
106
jdkSrc/jdk8/com/sun/tools/jdi/FieldImpl.java
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
|
||||
public class FieldImpl extends TypeComponentImpl
|
||||
implements Field, ValueContainer {
|
||||
|
||||
FieldImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
|
||||
long ref,
|
||||
String name, String signature,
|
||||
String genericSignature, int modifiers) {
|
||||
super(vm, declaringType, ref, name, signature,
|
||||
genericSignature, modifiers);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof FieldImpl)) {
|
||||
FieldImpl other = (FieldImpl)obj;
|
||||
return (declaringType().equals(other.declaringType())) &&
|
||||
(ref() == other.ref()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (int)ref();
|
||||
}
|
||||
|
||||
public int compareTo(Field field) {
|
||||
ReferenceTypeImpl declaringType = (ReferenceTypeImpl)declaringType();
|
||||
int rc = declaringType.compareTo(field.declaringType());
|
||||
if (rc == 0) {
|
||||
rc = declaringType.indexOf(this) -
|
||||
declaringType.indexOf(field);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public Type type() throws ClassNotLoadedException {
|
||||
return findType(signature());
|
||||
}
|
||||
|
||||
public Type findType(String signature) throws ClassNotLoadedException {
|
||||
ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType();
|
||||
return enclosing.findType(signature);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a text representation of the declared type
|
||||
* of this field.
|
||||
*/
|
||||
public String typeName() {
|
||||
JNITypeParser parser = new JNITypeParser(signature());
|
||||
return parser.typeName();
|
||||
}
|
||||
|
||||
public boolean isTransient() {
|
||||
return isModifierSet(VMModifiers.TRANSIENT);
|
||||
}
|
||||
|
||||
public boolean isVolatile() {
|
||||
return isModifierSet(VMModifiers.VOLATILE);
|
||||
}
|
||||
|
||||
public boolean isEnumConstant() {
|
||||
return isModifierSet(VMModifiers.ENUM_CONSTANT);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
|
||||
buf.append(declaringType().name());
|
||||
buf.append('.');
|
||||
buf.append(name());
|
||||
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/FloatTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/FloatTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class FloatTypeImpl extends PrimitiveTypeImpl implements FloatType {
|
||||
FloatTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.FLOAT);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedFloatValue());
|
||||
}
|
||||
|
||||
}
|
||||
156
jdkSrc/jdk8/com/sun/tools/jdi/FloatValueImpl.java
Normal file
156
jdkSrc/jdk8/com/sun/tools/jdi/FloatValueImpl.java
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class FloatValueImpl extends PrimitiveValueImpl
|
||||
implements FloatValue {
|
||||
private float value;
|
||||
|
||||
FloatValueImpl(VirtualMachine aVm,float aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof FloatValue)) {
|
||||
return (value == ((FloatValue)obj).value()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public int compareTo(FloatValue obj) {
|
||||
float other = obj.value();
|
||||
if (value() < other) {
|
||||
return -1;
|
||||
} else if (value() == other) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theFloatType();
|
||||
}
|
||||
|
||||
public float value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0.0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return(int)value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return(double)value;
|
||||
}
|
||||
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
if ((value > Byte.MAX_VALUE) || (value < Byte.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to byte");
|
||||
} else {
|
||||
return super.checkedByteValue();
|
||||
}
|
||||
}
|
||||
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to char");
|
||||
} else {
|
||||
return super.checkedCharValue();
|
||||
}
|
||||
}
|
||||
|
||||
short checkedShortValue() throws InvalidTypeException {
|
||||
if ((value > Short.MAX_VALUE) || (value < Short.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to short");
|
||||
} else {
|
||||
return super.checkedShortValue();
|
||||
}
|
||||
}
|
||||
|
||||
int checkedIntValue() throws InvalidTypeException {
|
||||
int intValue = (int)value;
|
||||
if (intValue != value) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to int");
|
||||
} else {
|
||||
return super.checkedIntValue();
|
||||
}
|
||||
}
|
||||
|
||||
long checkedLongValue() throws InvalidTypeException {
|
||||
long longValue = (long)value;
|
||||
if (longValue != value) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to long");
|
||||
} else {
|
||||
return super.checkedLongValue();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.FLOAT;
|
||||
}
|
||||
}
|
||||
145
jdkSrc/jdk8/com/sun/tools/jdi/GenericAttachingConnector.java
Normal file
145
jdkSrc/jdk8/com/sun/tools/jdi/GenericAttachingConnector.java
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.jdi.Bootstrap;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
|
||||
/*
|
||||
* An AttachingConnector to attach to a running VM using any
|
||||
* TransportService.
|
||||
*/
|
||||
|
||||
public class GenericAttachingConnector
|
||||
extends ConnectorImpl implements AttachingConnector
|
||||
{
|
||||
/*
|
||||
* The arguments that this connector supports
|
||||
*/
|
||||
static final String ARG_ADDRESS = "address";
|
||||
static final String ARG_TIMEOUT = "timeout";
|
||||
|
||||
TransportService transportService;
|
||||
Transport transport;
|
||||
|
||||
/*
|
||||
* Initialize a new instance of this connector. The connector
|
||||
* encapsulates a transport service and optionally has an
|
||||
* "address" connector argument.
|
||||
*/
|
||||
private GenericAttachingConnector(TransportService ts,
|
||||
boolean addAddressArgument)
|
||||
{
|
||||
transportService = ts;
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
// delegate name to the transport service
|
||||
return transportService.name();
|
||||
}
|
||||
};
|
||||
|
||||
if (addAddressArgument) {
|
||||
addStringArgument(
|
||||
ARG_ADDRESS,
|
||||
getString("generic_attaching.address.label"),
|
||||
getString("generic_attaching.address"),
|
||||
"",
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
addIntegerArgument(
|
||||
ARG_TIMEOUT,
|
||||
getString("generic_attaching.timeout.label"),
|
||||
getString("generic_attaching.timeout"),
|
||||
"",
|
||||
false,
|
||||
0, Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes a new instance of this connector. This constructor
|
||||
* is used when sub-classing - the resulting connector will have
|
||||
* a "timeout" connector argument.
|
||||
*/
|
||||
protected GenericAttachingConnector(TransportService ts) {
|
||||
this(ts, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an instance of this connector. The resulting AttachingConnector
|
||||
* will have address and timeout connector arguments.
|
||||
*/
|
||||
public static GenericAttachingConnector create(TransportService ts) {
|
||||
return new GenericAttachingConnector(ts, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach to a target VM using the specified address and Connector arguments.
|
||||
*/
|
||||
public VirtualMachine attach(String address, Map<String, ? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String ts = argument(ARG_TIMEOUT, args).value();
|
||||
int timeout = 0;
|
||||
if (ts.length() > 0) {
|
||||
timeout = Integer.decode(ts).intValue();
|
||||
}
|
||||
Connection connection = transportService.attach(address, timeout, 0);
|
||||
return Bootstrap.virtualMachineManager().createVirtualMachine(connection);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attach to a target VM using the specified arguments - the address
|
||||
* of the target VM is specified by the <code>address</code> connector
|
||||
* argument.
|
||||
*/
|
||||
public VirtualMachine
|
||||
attach(Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String address = argument(ARG_ADDRESS, args).value();
|
||||
return attach(address, args);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return transport.name() + "Attach";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return transportService.description();
|
||||
}
|
||||
|
||||
public Transport transport() {
|
||||
return transport;
|
||||
}
|
||||
|
||||
}
|
||||
187
jdkSrc/jdk8/com/sun/tools/jdi/GenericListeningConnector.java
Normal file
187
jdkSrc/jdk8/com/sun/tools/jdi/GenericListeningConnector.java
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2018, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.io.IOException;
|
||||
|
||||
import com.sun.jdi.Bootstrap;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
|
||||
/*
|
||||
* A ListeningConnector to listen for connections from target VM
|
||||
* using the configured transport service
|
||||
*/
|
||||
public class GenericListeningConnector
|
||||
extends ConnectorImpl implements ListeningConnector
|
||||
{
|
||||
static final String ARG_ADDRESS = "address";
|
||||
static final String ARG_TIMEOUT = "timeout";
|
||||
|
||||
Map<Map<String,? extends Connector.Argument>, TransportService.ListenKey> listenMap;
|
||||
TransportService transportService;
|
||||
Transport transport;
|
||||
|
||||
/**
|
||||
* Initialize a new instance of this connector. The connector
|
||||
* encapsulates a transport service, has a "timeout" connector argument,
|
||||
* and optionally an "address" connector argument.
|
||||
*/
|
||||
private GenericListeningConnector(TransportService ts,
|
||||
boolean addAddressArgument)
|
||||
{
|
||||
transportService = ts;
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return transportService.name();
|
||||
}
|
||||
};
|
||||
|
||||
if (addAddressArgument) {
|
||||
addStringArgument(
|
||||
ARG_ADDRESS,
|
||||
getString("generic_listening.address.label"),
|
||||
getString("generic_listening.address"),
|
||||
"",
|
||||
false);
|
||||
}
|
||||
|
||||
addIntegerArgument(
|
||||
ARG_TIMEOUT,
|
||||
getString("generic_listening.timeout.label"),
|
||||
getString("generic_listening.timeout"),
|
||||
"",
|
||||
false,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
listenMap = new HashMap<Map<String,? extends Connector.Argument>,TransportService.ListenKey>(10);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize a new instance of this connector. This constructor is used
|
||||
* when sub-classing - the resulting connector will a "timeout" connector
|
||||
* argument.
|
||||
*/
|
||||
protected GenericListeningConnector(TransportService ts) {
|
||||
this(ts, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an instance of this Connector. The resulting ListeningConnector will
|
||||
* have "address" and "timeout" connector arguments.
|
||||
*/
|
||||
public static GenericListeningConnector create(TransportService ts) {
|
||||
return new GenericListeningConnector(ts, true);
|
||||
}
|
||||
|
||||
public String startListening(String address, Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
TransportService.ListenKey listener = listenMap.get(args);
|
||||
if (listener != null) {
|
||||
throw new IllegalConnectorArgumentsException("Already listening",
|
||||
new ArrayList<String>(args.keySet()));
|
||||
}
|
||||
listener = transportService.startListening(address);
|
||||
updateArgumentMapIfRequired(args, listener);
|
||||
listenMap.put(args, listener);
|
||||
return listener.address();
|
||||
}
|
||||
|
||||
public String
|
||||
startListening(Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String address = argument(ARG_ADDRESS, args).value();
|
||||
return startListening(address, args);
|
||||
}
|
||||
|
||||
public void stopListening(Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
TransportService.ListenKey listener = listenMap.get(args);
|
||||
if (listener == null) {
|
||||
throw new IllegalConnectorArgumentsException("Not listening",
|
||||
new ArrayList<String>(args.keySet()));
|
||||
}
|
||||
transportService.stopListening(listener);
|
||||
listenMap.remove(args);
|
||||
}
|
||||
|
||||
public VirtualMachine
|
||||
accept(Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String ts = argument(ARG_TIMEOUT, args).value();
|
||||
int timeout = 0;
|
||||
if (ts.length() > 0) {
|
||||
timeout = Integer.decode(ts).intValue();
|
||||
}
|
||||
|
||||
TransportService.ListenKey listener = listenMap.get(args);
|
||||
Connection connection;
|
||||
if (listener != null) {
|
||||
connection = transportService.accept(listener, timeout, 0);
|
||||
} else {
|
||||
/*
|
||||
* Keep compatibility with previous releases - if the
|
||||
* debugger hasn't called startListening then we do a
|
||||
* once-off accept
|
||||
*/
|
||||
startListening(args);
|
||||
listener = listenMap.get(args);
|
||||
assert listener != null;
|
||||
connection = transportService.accept(listener, timeout, 0);
|
||||
stopListening(args);
|
||||
}
|
||||
return Bootstrap.virtualMachineManager().createVirtualMachine(connection);
|
||||
}
|
||||
|
||||
public boolean supportsMultipleConnections() {
|
||||
return transportService.capabilities().supportsMultipleConnections();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return transport.name() + "Listen";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return transportService.description();
|
||||
}
|
||||
|
||||
public Transport transport() {
|
||||
return transport;
|
||||
}
|
||||
|
||||
protected void updateArgumentMapIfRequired(
|
||||
Map<String, ? extends Connector.Argument> args, TransportService.ListenKey listener) {
|
||||
}
|
||||
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/IntegerTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/IntegerTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class IntegerTypeImpl extends PrimitiveTypeImpl implements IntegerType {
|
||||
IntegerTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.INT);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedIntValue());
|
||||
}
|
||||
|
||||
}
|
||||
132
jdkSrc/jdk8/com/sun/tools/jdi/IntegerValueImpl.java
Normal file
132
jdkSrc/jdk8/com/sun/tools/jdi/IntegerValueImpl.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class IntegerValueImpl extends PrimitiveValueImpl
|
||||
implements IntegerValue {
|
||||
private int value;
|
||||
|
||||
IntegerValueImpl(VirtualMachine aVm,int aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof IntegerValue)) {
|
||||
return (value == ((IntegerValue)obj).value()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public int compareTo(IntegerValue obj) {
|
||||
int other = obj.value();
|
||||
return (value()<other ? -1 : (value()==other ? 0 : 1));
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theIntegerType();
|
||||
}
|
||||
|
||||
public int value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return(double)value;
|
||||
}
|
||||
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
if ((value > Byte.MAX_VALUE) || (value < Byte.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to byte");
|
||||
} else {
|
||||
return super.checkedByteValue();
|
||||
}
|
||||
}
|
||||
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to char");
|
||||
} else {
|
||||
return super.checkedCharValue();
|
||||
}
|
||||
}
|
||||
|
||||
short checkedShortValue() throws InvalidTypeException {
|
||||
if ((value > Short.MAX_VALUE) || (value < Short.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to short");
|
||||
} else {
|
||||
return super.checkedShortValue();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.INT;
|
||||
}
|
||||
}
|
||||
152
jdkSrc/jdk8/com/sun/tools/jdi/InterfaceTypeImpl.java
Normal file
152
jdkSrc/jdk8/com/sun/tools/jdi/InterfaceTypeImpl.java
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Set;
|
||||
import java.lang.ref.SoftReference;
|
||||
|
||||
final public class InterfaceTypeImpl extends InvokableTypeImpl
|
||||
implements InterfaceType {
|
||||
|
||||
private static class IResult implements InvocationResult {
|
||||
final private JDWP.InterfaceType.InvokeMethod rslt;
|
||||
|
||||
public IResult(JDWP.InterfaceType.InvokeMethod rslt) {
|
||||
this.rslt = rslt;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ObjectReferenceImpl getException() {
|
||||
return rslt.exception;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ValueImpl getResult() {
|
||||
return rslt.returnValue;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private SoftReference<List<InterfaceType>> superinterfacesRef = null;
|
||||
|
||||
protected InterfaceTypeImpl(VirtualMachine aVm,long aRef) {
|
||||
super(aVm, aRef);
|
||||
}
|
||||
|
||||
public List<InterfaceType> superinterfaces() {
|
||||
List<InterfaceType> superinterfaces = (superinterfacesRef == null) ? null :
|
||||
superinterfacesRef.get();
|
||||
if (superinterfaces == null) {
|
||||
superinterfaces = getInterfaces();
|
||||
superinterfaces = Collections.unmodifiableList(superinterfaces);
|
||||
superinterfacesRef = new SoftReference<List<InterfaceType>>(superinterfaces);
|
||||
}
|
||||
return superinterfaces;
|
||||
}
|
||||
|
||||
public List<InterfaceType> subinterfaces() {
|
||||
List<InterfaceType> subs = new ArrayList<InterfaceType>();
|
||||
for (ReferenceType refType : vm.allClasses()) {
|
||||
if (refType instanceof InterfaceType) {
|
||||
InterfaceType interfaze = (InterfaceType)refType;
|
||||
if (interfaze.isPrepared() && interfaze.superinterfaces().contains(this)) {
|
||||
subs.add(interfaze);
|
||||
}
|
||||
}
|
||||
}
|
||||
return subs;
|
||||
}
|
||||
|
||||
public List<ClassType> implementors() {
|
||||
List<ClassType> implementors = new ArrayList<ClassType>();
|
||||
for (ReferenceType refType : vm.allClasses()) {
|
||||
if (refType instanceof ClassType) {
|
||||
ClassType clazz = (ClassType)refType;
|
||||
if (clazz.isPrepared() && clazz.interfaces().contains(this)) {
|
||||
implementors.add(clazz);
|
||||
}
|
||||
}
|
||||
}
|
||||
return implementors;
|
||||
}
|
||||
|
||||
public boolean isInitialized() {
|
||||
return isPrepared();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "interface " + name() + " (" + loaderString() + ")";
|
||||
}
|
||||
|
||||
@Override
|
||||
InvocationResult waitForReply(PacketStream stream) throws JDWPException {
|
||||
return new IResult(JDWP.InterfaceType.InvokeMethod.waitForReply(vm, stream));
|
||||
}
|
||||
|
||||
@Override
|
||||
CommandSender getInvokeMethodSender(final ThreadReferenceImpl thread,
|
||||
final MethodImpl method,
|
||||
final ValueImpl[] args,
|
||||
final int options) {
|
||||
return () ->
|
||||
JDWP.InterfaceType.InvokeMethod.enqueueCommand(vm,
|
||||
InterfaceTypeImpl.this,
|
||||
thread,
|
||||
method.ref(),
|
||||
args,
|
||||
options);
|
||||
}
|
||||
|
||||
@Override
|
||||
ClassType superclass() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isAssignableTo(ReferenceType type) {
|
||||
if (type.name().equals("java.lang.Object")) {
|
||||
// interfaces are always assignable to j.l.Object
|
||||
return true;
|
||||
}
|
||||
return super.isAssignableTo(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
List<InterfaceType> interfaces() {
|
||||
return superinterfaces();
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean canInvoke(Method method) {
|
||||
// method must be directly in this interface
|
||||
return this.equals(method.declaringType());
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/com/sun/tools/jdi/InternalEventHandler.java
Normal file
113
jdkSrc/jdk8/com/sun/tools/jdi/InternalEventHandler.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
import java.util.*;
|
||||
|
||||
public class InternalEventHandler implements Runnable
|
||||
{
|
||||
EventQueueImpl queue;
|
||||
VirtualMachineImpl vm;
|
||||
|
||||
InternalEventHandler(VirtualMachineImpl vm, EventQueueImpl queue)
|
||||
{
|
||||
this.vm = vm;
|
||||
this.queue = queue;
|
||||
Thread thread = new Thread(vm.threadGroupForJDI(), this,
|
||||
"JDI Internal Event Handler");
|
||||
thread.setDaemon(true);
|
||||
thread.start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
vm.printTrace("Internal event handler running");
|
||||
}
|
||||
try {
|
||||
while (true) {
|
||||
try {
|
||||
EventSet eventSet = queue.removeInternal();
|
||||
EventIterator it = eventSet.eventIterator();
|
||||
while (it.hasNext()) {
|
||||
Event event = it.nextEvent();
|
||||
if (event instanceof ClassUnloadEvent) {
|
||||
ClassUnloadEvent cuEvent = (ClassUnloadEvent)event;
|
||||
vm.removeReferenceType(cuEvent.classSignature());
|
||||
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
vm.printTrace("Handled Unload Event for " +
|
||||
cuEvent.classSignature());
|
||||
}
|
||||
} else if (event instanceof ClassPrepareEvent) {
|
||||
ClassPrepareEvent cpEvent = (ClassPrepareEvent)event;
|
||||
((ReferenceTypeImpl)cpEvent.referenceType())
|
||||
.markPrepared();
|
||||
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
vm.printTrace("Handled Prepare Event for " +
|
||||
cpEvent.referenceType().name());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle exceptions that can occur in normal operation
|
||||
* but which can't be accounted for by event builder
|
||||
* methods. The thread should not be terminated if they
|
||||
* occur.
|
||||
*
|
||||
* TO DO: We need a better way to log these conditions.
|
||||
*/
|
||||
} catch (VMOutOfMemoryException vmme) {
|
||||
vmme.printStackTrace();
|
||||
} catch (InconsistentDebugInfoException idie) {
|
||||
idie.printStackTrace();
|
||||
|
||||
/*
|
||||
* If any of these exceptions below occurs, there is some
|
||||
* sort of programming error that should be addressed in
|
||||
* the JDI implemementation. However, it would cripple
|
||||
* the implementation if we let this thread die due to
|
||||
* one of them. So, a notification of the exception is
|
||||
* given and we attempt to continue.
|
||||
*/
|
||||
} catch (ObjectCollectedException oce) {
|
||||
oce.printStackTrace();
|
||||
} catch (ClassNotPreparedException cnpe) {
|
||||
cnpe.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (InterruptedException e) { // should we really die here
|
||||
} catch (VMDisconnectedException e) { // time to die
|
||||
}
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
vm.printTrace("Internal event handler exiting");
|
||||
}
|
||||
}
|
||||
}
|
||||
306
jdkSrc/jdk8/com/sun/tools/jdi/InvokableTypeImpl.java
Normal file
306
jdkSrc/jdk8/com/sun/tools/jdi/InvokableTypeImpl.java
Normal file
@@ -0,0 +1,306 @@
|
||||
/*
|
||||
* Copyright (c) 2014, 2018, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.ClassNotLoadedException;
|
||||
import com.sun.jdi.ClassType;
|
||||
import com.sun.jdi.IncompatibleThreadStateException;
|
||||
import com.sun.jdi.InterfaceType;
|
||||
import com.sun.jdi.InvalidTypeException;
|
||||
import com.sun.jdi.InvocationException;
|
||||
import com.sun.jdi.Method;
|
||||
import com.sun.jdi.ReferenceType;
|
||||
import com.sun.jdi.ThreadReference;
|
||||
import com.sun.jdi.Value;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* A supertype for ReferenceTypes allowing method invocations
|
||||
*/
|
||||
abstract class InvokableTypeImpl extends ReferenceTypeImpl {
|
||||
/**
|
||||
* The invocation result wrapper
|
||||
* It is necessary because both ClassType and InterfaceType
|
||||
* use their own type to represent the invocation result
|
||||
*/
|
||||
static interface InvocationResult {
|
||||
ObjectReferenceImpl getException();
|
||||
ValueImpl getResult();
|
||||
}
|
||||
|
||||
InvokableTypeImpl(VirtualMachine aVm, long aRef) {
|
||||
super(aVm, aRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Method invocation support.
|
||||
* Shared by ClassType and InterfaceType
|
||||
* @param threadIntf the thread in which to invoke.
|
||||
* @param methodIntf method the {@link Method} to invoke.
|
||||
* @param origArguments the list of {@link Value} arguments bound to the
|
||||
* invoked method. Values from the list are assigned to arguments
|
||||
* in the order they appear in the method signature.
|
||||
* @param options the integer bit flag options.
|
||||
* @return a {@link Value} mirror of the invoked method's return value.
|
||||
* @throws java.lang.IllegalArgumentException if the method is not
|
||||
* a member of this type, if the size of the argument list
|
||||
* does not match the number of declared arguments for the method, or
|
||||
* if the method is not static or is a static initializer.
|
||||
* @throws {@link InvalidTypeException} if any argument in the
|
||||
* argument list is not assignable to the corresponding method argument
|
||||
* type.
|
||||
* @throws ClassNotLoadedException if any argument type has not yet been loaded
|
||||
* through the appropriate class loader.
|
||||
* @throws IncompatibleThreadStateException if the specified thread has not
|
||||
* been suspended by an event.
|
||||
* @throws InvocationException if the method invocation resulted in
|
||||
* an exception in the target VM.
|
||||
* @throws InvalidTypeException If the arguments do not meet this requirement --
|
||||
* Object arguments must be assignment compatible with the argument
|
||||
* type. This implies that the argument type must be
|
||||
* loaded through the enclosing class's class loader.
|
||||
* Primitive arguments must be either assignment compatible with the
|
||||
* argument type or must be convertible to the argument type without loss
|
||||
* of information. See JLS section 5.2 for more information on assignment
|
||||
* compatibility.
|
||||
* @throws VMCannotBeModifiedException if the VirtualMachine is read-only - see {@link VirtualMachine#canBeModified()}.
|
||||
*/
|
||||
final public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
|
||||
List<? extends Value> origArguments, int options)
|
||||
throws InvalidTypeException,
|
||||
ClassNotLoadedException,
|
||||
IncompatibleThreadStateException,
|
||||
InvocationException {
|
||||
validateMirror(threadIntf);
|
||||
validateMirror(methodIntf);
|
||||
validateMirrorsOrNulls(origArguments);
|
||||
MethodImpl method = (MethodImpl) methodIntf;
|
||||
ThreadReferenceImpl thread = (ThreadReferenceImpl) threadIntf;
|
||||
validateMethodInvocation(method);
|
||||
List<? extends Value> arguments = method.validateAndPrepareArgumentsForInvoke(origArguments);
|
||||
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
|
||||
InvocationResult ret;
|
||||
try {
|
||||
PacketStream stream = sendInvokeCommand(thread, method, args, options);
|
||||
ret = waitForReply(stream);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
|
||||
throw new IncompatibleThreadStateException();
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
/*
|
||||
* There is an implict VM-wide suspend at the conclusion
|
||||
* of a normal (non-single-threaded) method invoke
|
||||
*/
|
||||
if ((options & ClassType.INVOKE_SINGLE_THREADED) == 0) {
|
||||
vm.notifySuspend();
|
||||
}
|
||||
if (ret.getException() != null) {
|
||||
throw new InvocationException(ret.getException());
|
||||
} else {
|
||||
return ret.getResult();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
boolean isAssignableTo(ReferenceType type) {
|
||||
ClassTypeImpl superclazz = (ClassTypeImpl) superclass();
|
||||
if (this.equals(type)) {
|
||||
return true;
|
||||
} else if ((superclazz != null) && superclazz.isAssignableTo(type)) {
|
||||
return true;
|
||||
} else {
|
||||
List<InterfaceType> interfaces = interfaces();
|
||||
Iterator<InterfaceType> iter = interfaces.iterator();
|
||||
while (iter.hasNext()) {
|
||||
InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
|
||||
if (interfaze.isAssignableTo(type)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
final void addVisibleMethods(Map<String, Method> methodMap, Set<InterfaceType> seenInterfaces) {
|
||||
/*
|
||||
* Add methods from
|
||||
* parent types first, so that the methods in this class will
|
||||
* overwrite them in the hash table
|
||||
*/
|
||||
Iterator<InterfaceType> iter = interfaces().iterator();
|
||||
while (iter.hasNext()) {
|
||||
InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
|
||||
if (!seenInterfaces.contains(interfaze)) {
|
||||
interfaze.addVisibleMethods(methodMap, seenInterfaces);
|
||||
seenInterfaces.add(interfaze);
|
||||
}
|
||||
}
|
||||
ClassTypeImpl clazz = (ClassTypeImpl) superclass();
|
||||
if (clazz != null) {
|
||||
clazz.addVisibleMethods(methodMap, seenInterfaces);
|
||||
}
|
||||
addToMethodMap(methodMap, methods());
|
||||
}
|
||||
|
||||
final void addInterfaces(List<InterfaceType> list) {
|
||||
List<InterfaceType> immediate = interfaces();
|
||||
list.addAll(interfaces());
|
||||
Iterator<InterfaceType> iter = immediate.iterator();
|
||||
while (iter.hasNext()) {
|
||||
InterfaceTypeImpl interfaze = (InterfaceTypeImpl) iter.next();
|
||||
interfaze.addInterfaces(list);
|
||||
}
|
||||
ClassTypeImpl superclass = (ClassTypeImpl) superclass();
|
||||
if (superclass != null) {
|
||||
superclass.addInterfaces(list);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the implemented interfaces recursively
|
||||
* @return A list of all the implemented interfaces (recursively)
|
||||
*/
|
||||
final List<InterfaceType> getAllInterfaces() {
|
||||
List<InterfaceType> all = new ArrayList<>();
|
||||
addInterfaces(all);
|
||||
return all;
|
||||
}
|
||||
|
||||
/**
|
||||
* Shared implementation of {@linkplain ClassType#allMethods()} and
|
||||
* {@linkplain InterfaceType#allMethods()}
|
||||
* @return A list of all methods (recursively)
|
||||
*/
|
||||
public final List<Method> allMethods() {
|
||||
ArrayList<Method> list = new ArrayList<>(methods());
|
||||
ClassType clazz = superclass();
|
||||
while (clazz != null) {
|
||||
list.addAll(clazz.methods());
|
||||
clazz = clazz.superclass();
|
||||
}
|
||||
/*
|
||||
* Avoid duplicate checking on each method by iterating through
|
||||
* duplicate-free allInterfaces() rather than recursing
|
||||
*/
|
||||
for (InterfaceType interfaze : getAllInterfaces()) {
|
||||
list.addAll(interfaze.methods());
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Override
|
||||
final List<ReferenceType> inheritedTypes() {
|
||||
List<ReferenceType> inherited = new ArrayList<>();
|
||||
if (superclass() != null) {
|
||||
inherited.add(0, superclass()); /* insert at front */
|
||||
}
|
||||
for (ReferenceType rt : interfaces()) {
|
||||
inherited.add(rt);
|
||||
}
|
||||
return inherited;
|
||||
}
|
||||
|
||||
private PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
|
||||
final MethodImpl method,
|
||||
final ValueImpl[] args,
|
||||
final int options) {
|
||||
|
||||
CommandSender sender = getInvokeMethodSender(thread, method, args, options);
|
||||
PacketStream stream;
|
||||
if ((options & ClassType.INVOKE_SINGLE_THREADED) != 0) {
|
||||
stream = thread.sendResumingCommand(sender);
|
||||
} else {
|
||||
stream = vm.sendResumingCommand(sender);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
private void validateMethodInvocation(Method method)
|
||||
throws InvalidTypeException,
|
||||
InvocationException {
|
||||
if (!canInvoke(method)) {
|
||||
throw new IllegalArgumentException("Invalid method");
|
||||
}
|
||||
/*
|
||||
* Method must be a static and not a static initializer
|
||||
*/
|
||||
if (!method.isStatic()) {
|
||||
throw new IllegalArgumentException("Cannot invoke instance method on a class/interface type");
|
||||
} else if (method.isStaticInitializer()) {
|
||||
throw new IllegalArgumentException("Cannot invoke static initializer");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A subclass will provide specific {@linkplain CommandSender}
|
||||
* @param thread the current invocation thread
|
||||
* @param method the method to invoke
|
||||
* @param args the arguments to pass to the method
|
||||
* @param options the integer bit flag options
|
||||
* @return the specific {@literal CommandSender} instance
|
||||
*/
|
||||
abstract CommandSender getInvokeMethodSender(ThreadReferenceImpl thread,
|
||||
MethodImpl method,
|
||||
ValueImpl[] args,
|
||||
int options);
|
||||
|
||||
/**
|
||||
* Waits for the reply to the last sent command
|
||||
* @param stream the stream to listen for the reply on
|
||||
* @return the {@linkplain InvocationResult} instance
|
||||
* @throws JDWPException when something goes wrong in JDWP
|
||||
*/
|
||||
abstract InvocationResult waitForReply(PacketStream stream) throws JDWPException;
|
||||
|
||||
/**
|
||||
* Get the {@linkplain ReferenceType} superclass
|
||||
* @return the superclass or null
|
||||
*/
|
||||
abstract ClassType superclass();
|
||||
|
||||
/**
|
||||
* Get the implemented/extended interfaces
|
||||
* @return the list of implemented/extended interfaces
|
||||
*/
|
||||
abstract List<InterfaceType> interfaces();
|
||||
|
||||
/**
|
||||
* Checks the provided method whether it can be invoked
|
||||
* @param method the method to check
|
||||
* @return {@code TRUE} if the implementation knows how to invoke the method,
|
||||
* {@code FALSE} otherwise
|
||||
*/
|
||||
abstract boolean canInvoke(Method method);
|
||||
}
|
||||
8756
jdkSrc/jdk8/com/sun/tools/jdi/JDWP.java
Normal file
8756
jdkSrc/jdk8/com/sun/tools/jdi/JDWP.java
Normal file
File diff suppressed because it is too large
Load Diff
68
jdkSrc/jdk8/com/sun/tools/jdi/JDWPException.java
Normal file
68
jdkSrc/jdk8/com/sun/tools/jdi/JDWPException.java
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
import com.sun.jdi.*;
|
||||
|
||||
class JDWPException extends Exception {
|
||||
private static final long serialVersionUID = -6321344442751299874L;
|
||||
short errorCode;
|
||||
|
||||
JDWPException(short errorCode) {
|
||||
super();
|
||||
this.errorCode = errorCode;
|
||||
}
|
||||
|
||||
short errorCode() {
|
||||
return errorCode;
|
||||
}
|
||||
|
||||
RuntimeException toJDIException() {
|
||||
switch (errorCode) {
|
||||
case JDWP.Error.INVALID_OBJECT:
|
||||
return new ObjectCollectedException();
|
||||
case JDWP.Error.VM_DEAD:
|
||||
return new VMDisconnectedException();
|
||||
case JDWP.Error.OUT_OF_MEMORY:
|
||||
return new VMOutOfMemoryException();
|
||||
case JDWP.Error.CLASS_NOT_PREPARED:
|
||||
return new ClassNotPreparedException();
|
||||
case JDWP.Error.INVALID_FRAMEID:
|
||||
case JDWP.Error.NOT_CURRENT_FRAME:
|
||||
return new InvalidStackFrameException();
|
||||
case JDWP.Error.NOT_IMPLEMENTED:
|
||||
return new UnsupportedOperationException();
|
||||
case JDWP.Error.INVALID_INDEX:
|
||||
case JDWP.Error.INVALID_LENGTH:
|
||||
return new IndexOutOfBoundsException();
|
||||
case JDWP.Error.TYPE_MISMATCH:
|
||||
return new InconsistentDebugInfoException();
|
||||
case JDWP.Error.INVALID_THREAD:
|
||||
return new IllegalThreadStateException();
|
||||
default:
|
||||
return new InternalException("Unexpected JDWP Error: " + errorCode, errorCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
241
jdkSrc/jdk8/com/sun/tools/jdi/JNITypeParser.java
Normal file
241
jdkSrc/jdk8/com/sun/tools/jdi/JNITypeParser.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class JNITypeParser {
|
||||
|
||||
static final char SIGNATURE_ENDCLASS = ';';
|
||||
static final char SIGNATURE_FUNC = '(';
|
||||
static final char SIGNATURE_ENDFUNC = ')';
|
||||
|
||||
private String signature;
|
||||
private List<String> typeNameList;
|
||||
private List<String> signatureList;
|
||||
private int currentIndex;
|
||||
|
||||
JNITypeParser(String signature) {
|
||||
this.signature = signature;
|
||||
}
|
||||
|
||||
static String typeNameToSignature(String signature) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
int firstIndex = signature.indexOf('[');
|
||||
int index = firstIndex;
|
||||
while (index != -1) {
|
||||
buffer.append('[');
|
||||
index = signature.indexOf('[', index + 1);
|
||||
}
|
||||
|
||||
if (firstIndex != -1) {
|
||||
signature = signature.substring(0, firstIndex);
|
||||
}
|
||||
|
||||
if (signature.equals("boolean")) {
|
||||
buffer.append('Z');
|
||||
} else if (signature.equals("byte")) {
|
||||
buffer.append('B');
|
||||
} else if (signature.equals("char")) {
|
||||
buffer.append('C');
|
||||
} else if (signature.equals("short")) {
|
||||
buffer.append('S');
|
||||
} else if (signature.equals("int")) {
|
||||
buffer.append('I');
|
||||
} else if (signature.equals("long")) {
|
||||
buffer.append('J');
|
||||
} else if (signature.equals("float")) {
|
||||
buffer.append('F');
|
||||
} else if (signature.equals("double")) {
|
||||
buffer.append('D');
|
||||
} else {
|
||||
buffer.append('L');
|
||||
buffer.append(signature.replace('.', '/'));
|
||||
buffer.append(';');
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
String typeName() {
|
||||
return typeNameList().get(typeNameList().size()-1);
|
||||
}
|
||||
|
||||
List<String> argumentTypeNames() {
|
||||
return typeNameList().subList(0, typeNameList().size() - 1);
|
||||
}
|
||||
|
||||
String signature() {
|
||||
return signatureList().get(signatureList().size()-1);
|
||||
}
|
||||
|
||||
List<String> argumentSignatures() {
|
||||
return signatureList().subList(0, signatureList().size() - 1);
|
||||
}
|
||||
|
||||
int dimensionCount() {
|
||||
int count = 0;
|
||||
String signature = signature();
|
||||
while (signature.charAt(count) == '[') {
|
||||
count++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
String componentSignature(int level) {
|
||||
return signature().substring(level);
|
||||
}
|
||||
|
||||
private synchronized List<String> signatureList() {
|
||||
if (signatureList == null) {
|
||||
signatureList = new ArrayList<String>(10);
|
||||
String elem;
|
||||
|
||||
currentIndex = 0;
|
||||
|
||||
while(currentIndex < signature.length()) {
|
||||
elem = nextSignature();
|
||||
signatureList.add(elem);
|
||||
}
|
||||
if (signatureList.size() == 0) {
|
||||
throw new IllegalArgumentException("Invalid JNI signature '" +
|
||||
signature + "'");
|
||||
}
|
||||
}
|
||||
return signatureList;
|
||||
}
|
||||
|
||||
private synchronized List<String> typeNameList() {
|
||||
if (typeNameList == null) {
|
||||
typeNameList = new ArrayList<String>(10);
|
||||
String elem;
|
||||
|
||||
currentIndex = 0;
|
||||
|
||||
while(currentIndex < signature.length()) {
|
||||
elem = nextTypeName();
|
||||
typeNameList.add(elem);
|
||||
}
|
||||
if (typeNameList.size() == 0) {
|
||||
throw new IllegalArgumentException("Invalid JNI signature '" +
|
||||
signature + "'");
|
||||
}
|
||||
}
|
||||
return typeNameList;
|
||||
}
|
||||
|
||||
private String nextSignature() {
|
||||
char key = signature.charAt(currentIndex++);
|
||||
|
||||
switch(key) {
|
||||
case (JDWP.Tag.ARRAY):
|
||||
return key + nextSignature();
|
||||
|
||||
case (JDWP.Tag.OBJECT):
|
||||
int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
|
||||
currentIndex);
|
||||
String retVal = signature.substring(currentIndex - 1,
|
||||
endClass + 1);
|
||||
currentIndex = endClass + 1;
|
||||
return retVal;
|
||||
|
||||
case (JDWP.Tag.VOID):
|
||||
case (JDWP.Tag.BOOLEAN):
|
||||
case (JDWP.Tag.BYTE):
|
||||
case (JDWP.Tag.CHAR):
|
||||
case (JDWP.Tag.SHORT):
|
||||
case (JDWP.Tag.INT):
|
||||
case (JDWP.Tag.LONG):
|
||||
case (JDWP.Tag.FLOAT):
|
||||
case (JDWP.Tag.DOUBLE):
|
||||
return String.valueOf(key);
|
||||
|
||||
case SIGNATURE_ENDFUNC:
|
||||
case SIGNATURE_FUNC:
|
||||
return nextSignature();
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid JNI signature character '" + key + "'");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private String nextTypeName() {
|
||||
char key = signature.charAt(currentIndex++);
|
||||
|
||||
switch(key) {
|
||||
case (JDWP.Tag.ARRAY):
|
||||
return nextTypeName() + "[]";
|
||||
|
||||
case (JDWP.Tag.BYTE):
|
||||
return "byte";
|
||||
|
||||
case (JDWP.Tag.CHAR):
|
||||
return "char";
|
||||
|
||||
case (JDWP.Tag.OBJECT):
|
||||
int endClass = signature.indexOf(SIGNATURE_ENDCLASS,
|
||||
currentIndex);
|
||||
String retVal = signature.substring(currentIndex,
|
||||
endClass);
|
||||
retVal = retVal.replace('/','.');
|
||||
currentIndex = endClass + 1;
|
||||
return retVal;
|
||||
|
||||
case (JDWP.Tag.FLOAT):
|
||||
return "float";
|
||||
|
||||
case (JDWP.Tag.DOUBLE):
|
||||
return "double";
|
||||
|
||||
case (JDWP.Tag.INT):
|
||||
return "int";
|
||||
|
||||
case (JDWP.Tag.LONG):
|
||||
return "long";
|
||||
|
||||
case (JDWP.Tag.SHORT):
|
||||
return "short";
|
||||
|
||||
case (JDWP.Tag.VOID):
|
||||
return "void";
|
||||
|
||||
case (JDWP.Tag.BOOLEAN):
|
||||
return "boolean";
|
||||
|
||||
case SIGNATURE_ENDFUNC:
|
||||
case SIGNATURE_FUNC:
|
||||
return nextTypeName();
|
||||
|
||||
default:
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid JNI signature character '" + key + "'");
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
39
jdkSrc/jdk8/com/sun/tools/jdi/LineInfo.java
Normal file
39
jdkSrc/jdk8/com/sun/tools/jdi/LineInfo.java
Normal file
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
interface LineInfo {
|
||||
|
||||
String liStratum();
|
||||
|
||||
int liLineNumber();
|
||||
|
||||
String liSourceName() throws AbsentInformationException;
|
||||
|
||||
String liSourcePath() throws AbsentInformationException;
|
||||
}
|
||||
178
jdkSrc/jdk8/com/sun/tools/jdi/LocalVariableImpl.java
Normal file
178
jdkSrc/jdk8/com/sun/tools/jdi/LocalVariableImpl.java
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class LocalVariableImpl extends MirrorImpl
|
||||
implements LocalVariable, ValueContainer
|
||||
{
|
||||
private final Method method;
|
||||
private final int slot;
|
||||
private final Location scopeStart;
|
||||
private final Location scopeEnd;
|
||||
private final String name;
|
||||
private final String signature;
|
||||
private String genericSignature = null;
|
||||
|
||||
LocalVariableImpl(VirtualMachine vm, Method method,
|
||||
int slot, Location scopeStart, Location scopeEnd,
|
||||
String name, String signature,
|
||||
String genericSignature) {
|
||||
super(vm);
|
||||
this.method = method;
|
||||
this.slot = slot;
|
||||
this.scopeStart = scopeStart;
|
||||
this.scopeEnd = scopeEnd;
|
||||
this.name = name;
|
||||
this.signature = signature;
|
||||
if (genericSignature != null && genericSignature.length() > 0) {
|
||||
this.genericSignature = genericSignature;
|
||||
} else {
|
||||
// The Spec says to return null for non-generic types
|
||||
this.genericSignature = null;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof LocalVariableImpl)) {
|
||||
LocalVariableImpl other = (LocalVariableImpl)obj;
|
||||
return ((slot() == other.slot()) &&
|
||||
(scopeStart != null) &&
|
||||
(scopeStart.equals(other.scopeStart)) &&
|
||||
(super.equals(obj)));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return ((scopeStart.hashCode() << 4) + slot());
|
||||
}
|
||||
|
||||
public int compareTo(LocalVariable object) {
|
||||
LocalVariableImpl other = (LocalVariableImpl)object;
|
||||
|
||||
int rc = scopeStart.compareTo(other.scopeStart);
|
||||
if (rc == 0) {
|
||||
rc = slot() - other.slot();
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a text representation of the declared type
|
||||
* of this variable.
|
||||
*/
|
||||
public String typeName() {
|
||||
JNITypeParser parser = new JNITypeParser(signature);
|
||||
return parser.typeName();
|
||||
}
|
||||
|
||||
public Type type() throws ClassNotLoadedException {
|
||||
return findType(signature());
|
||||
}
|
||||
|
||||
public Type findType(String signature) throws ClassNotLoadedException {
|
||||
ReferenceTypeImpl enclosing = (ReferenceTypeImpl)method.declaringType();
|
||||
return enclosing.findType(signature);
|
||||
}
|
||||
|
||||
public String signature() {
|
||||
return signature;
|
||||
}
|
||||
|
||||
public String genericSignature() {
|
||||
return genericSignature;
|
||||
}
|
||||
|
||||
public boolean isVisible(StackFrame frame) {
|
||||
validateMirror(frame);
|
||||
Method frameMethod = frame.location().method();
|
||||
|
||||
if (!frameMethod.equals(method)) {
|
||||
throw new IllegalArgumentException(
|
||||
"frame method different than variable's method");
|
||||
}
|
||||
|
||||
// this is here to cover the possibility that we will
|
||||
// allow LocalVariables for native methods. If we do
|
||||
// so we will have to re-examinine this.
|
||||
if (frameMethod.isNative()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ((scopeStart.compareTo(frame.location()) <= 0)
|
||||
&& (scopeEnd.compareTo(frame.location()) >= 0));
|
||||
}
|
||||
|
||||
public boolean isArgument() {
|
||||
try {
|
||||
MethodImpl method = (MethodImpl)scopeStart.method();
|
||||
return (slot < method.argSlotCount());
|
||||
} catch (AbsentInformationException e) {
|
||||
// If this variable object exists, there shouldn't be absent info
|
||||
throw new InternalException();
|
||||
}
|
||||
}
|
||||
|
||||
int slot() {
|
||||
return slot;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compilers/VMs can have byte code ranges for variables of the
|
||||
* same names that overlap. This is because the byte code ranges
|
||||
* aren't necessarily scopes; they may have more to do with the
|
||||
* lifetime of the variable's slot, depending on implementation.
|
||||
*
|
||||
* This method determines whether this variable hides an
|
||||
* identically named variable; ie, their byte code ranges overlap
|
||||
* this one starts after the given one. If it returns true this
|
||||
* variable should be preferred when looking for a single variable
|
||||
* with its name when both variables are visible.
|
||||
*/
|
||||
boolean hides(LocalVariable other) {
|
||||
LocalVariableImpl otherImpl = (LocalVariableImpl)other;
|
||||
if (!method.equals(otherImpl.method) ||
|
||||
!name.equals(otherImpl.name)) {
|
||||
return false;
|
||||
} else {
|
||||
return (scopeStart.compareTo(otherImpl.scopeStart) > 0);
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name() + " in " + method.toString() +
|
||||
"@" + scopeStart.toString();
|
||||
}
|
||||
}
|
||||
227
jdkSrc/jdk8/com/sun/tools/jdi/LocationImpl.java
Normal file
227
jdkSrc/jdk8/com/sun/tools/jdi/LocationImpl.java
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class LocationImpl extends MirrorImpl implements Location {
|
||||
private final ReferenceTypeImpl declaringType;
|
||||
private Method method;
|
||||
private long methodRef;
|
||||
private long codeIndex;
|
||||
private LineInfo baseLineInfo = null;
|
||||
private LineInfo otherLineInfo = null;
|
||||
|
||||
LocationImpl(VirtualMachine vm,
|
||||
Method method, long codeIndex) {
|
||||
super(vm);
|
||||
|
||||
this.method = method;
|
||||
this.codeIndex = method.isNative()? -1 : codeIndex;
|
||||
this.declaringType = (ReferenceTypeImpl)method.declaringType();
|
||||
}
|
||||
|
||||
/*
|
||||
* This constructor allows lazy creation of the method mirror. This
|
||||
* can be a performance savings if the method mirror does not yet
|
||||
* exist.
|
||||
*/
|
||||
LocationImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
|
||||
long methodRef, long codeIndex) {
|
||||
super(vm);
|
||||
|
||||
this.method = null;
|
||||
this.codeIndex = codeIndex;
|
||||
this.declaringType = declaringType;
|
||||
this.methodRef = methodRef;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof Location)) {
|
||||
Location other = (Location)obj;
|
||||
return (method().equals(other.method())) &&
|
||||
(codeIndex() == other.codeIndex()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: better hash code?
|
||||
*/
|
||||
return method().hashCode() + (int)codeIndex();
|
||||
}
|
||||
|
||||
public int compareTo(Location object) {
|
||||
LocationImpl other = (LocationImpl)object;
|
||||
int rc = method().compareTo(other.method());
|
||||
if (rc == 0) {
|
||||
long diff = codeIndex() - other.codeIndex();
|
||||
if (diff < 0)
|
||||
return -1;
|
||||
else if (diff > 0)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public ReferenceType declaringType() {
|
||||
return declaringType;
|
||||
}
|
||||
|
||||
public Method method() {
|
||||
if (method == null) {
|
||||
method = declaringType.getMethodMirror(methodRef);
|
||||
if (method.isNative()) {
|
||||
codeIndex = -1;
|
||||
}
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
public long codeIndex() {
|
||||
method(); // be sure information is up-to-date
|
||||
return codeIndex;
|
||||
}
|
||||
|
||||
LineInfo getBaseLineInfo(SDE.Stratum stratum) {
|
||||
LineInfo lineInfo;
|
||||
|
||||
/* check if there is cached info to use */
|
||||
if (baseLineInfo != null) {
|
||||
return baseLineInfo;
|
||||
}
|
||||
|
||||
/* compute the line info */
|
||||
MethodImpl methodImpl = (MethodImpl)method();
|
||||
lineInfo = methodImpl.codeIndexToLineInfo(stratum,
|
||||
codeIndex());
|
||||
|
||||
/* cache it */
|
||||
addBaseLineInfo(lineInfo);
|
||||
|
||||
return lineInfo;
|
||||
}
|
||||
|
||||
LineInfo getLineInfo(SDE.Stratum stratum) {
|
||||
LineInfo lineInfo;
|
||||
|
||||
/* base stratum is done slighly differently */
|
||||
if (stratum.isJava()) {
|
||||
return getBaseLineInfo(stratum);
|
||||
}
|
||||
|
||||
/* check if there is cached info to use */
|
||||
lineInfo = otherLineInfo; // copy because of concurrency
|
||||
if (lineInfo != null &&
|
||||
stratum.id().equals(lineInfo.liStratum())) {
|
||||
return lineInfo;
|
||||
}
|
||||
|
||||
int baseLineNumber = lineNumber(SDE.BASE_STRATUM_NAME);
|
||||
SDE.LineStratum lineStratum =
|
||||
stratum.lineStratum(declaringType, baseLineNumber);
|
||||
|
||||
if (lineStratum != null && lineStratum.lineNumber() != -1) {
|
||||
lineInfo = new StratumLineInfo(stratum.id(),
|
||||
lineStratum.lineNumber(),
|
||||
lineStratum.sourceName(),
|
||||
lineStratum.sourcePath());
|
||||
} else {
|
||||
/* find best match */
|
||||
MethodImpl methodImpl = (MethodImpl)method();
|
||||
lineInfo = methodImpl.codeIndexToLineInfo(stratum,
|
||||
codeIndex());
|
||||
}
|
||||
|
||||
/* cache it */
|
||||
addStratumLineInfo(lineInfo);
|
||||
|
||||
return lineInfo;
|
||||
}
|
||||
|
||||
void addStratumLineInfo(LineInfo lineInfo) {
|
||||
otherLineInfo = lineInfo;
|
||||
}
|
||||
|
||||
void addBaseLineInfo(LineInfo lineInfo) {
|
||||
baseLineInfo = lineInfo;
|
||||
}
|
||||
|
||||
public String sourceName() throws AbsentInformationException {
|
||||
return sourceName(vm.getDefaultStratum());
|
||||
}
|
||||
|
||||
public String sourceName(String stratumID)
|
||||
throws AbsentInformationException {
|
||||
return sourceName(declaringType.stratum(stratumID));
|
||||
}
|
||||
|
||||
String sourceName(SDE.Stratum stratum)
|
||||
throws AbsentInformationException {
|
||||
return getLineInfo(stratum).liSourceName();
|
||||
}
|
||||
|
||||
public String sourcePath() throws AbsentInformationException {
|
||||
return sourcePath(vm.getDefaultStratum());
|
||||
}
|
||||
|
||||
public String sourcePath(String stratumID)
|
||||
throws AbsentInformationException {
|
||||
return sourcePath(declaringType.stratum(stratumID));
|
||||
}
|
||||
|
||||
String sourcePath(SDE.Stratum stratum)
|
||||
throws AbsentInformationException {
|
||||
return getLineInfo(stratum).liSourcePath();
|
||||
}
|
||||
|
||||
public int lineNumber() {
|
||||
return lineNumber(vm.getDefaultStratum());
|
||||
}
|
||||
|
||||
public int lineNumber(String stratumID) {
|
||||
return lineNumber(declaringType.stratum(stratumID));
|
||||
}
|
||||
|
||||
int lineNumber(SDE.Stratum stratum) {
|
||||
return getLineInfo(stratum).liLineNumber();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (lineNumber() == -1) {
|
||||
return method().toString() + "+" + codeIndex();
|
||||
} else {
|
||||
return declaringType().name() + ":" + lineNumber();
|
||||
}
|
||||
}
|
||||
}
|
||||
38
jdkSrc/jdk8/com/sun/tools/jdi/LockObject.java
Normal file
38
jdkSrc/jdk8/com/sun/tools/jdi/LockObject.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
/**
|
||||
* This class is used by the back end to do thread synchronization.
|
||||
* We don't want to use java.lang.Object(s) for two reasons: we can't
|
||||
* filter them out, and this class should use less heap.
|
||||
*/
|
||||
|
||||
public class LockObject
|
||||
{
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/LongTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/LongTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class LongTypeImpl extends PrimitiveTypeImpl implements LongType {
|
||||
LongTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.LONG);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedLongValue());
|
||||
}
|
||||
|
||||
}
|
||||
146
jdkSrc/jdk8/com/sun/tools/jdi/LongValueImpl.java
Normal file
146
jdkSrc/jdk8/com/sun/tools/jdi/LongValueImpl.java
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class LongValueImpl extends PrimitiveValueImpl
|
||||
implements LongValue {
|
||||
private long value;
|
||||
|
||||
LongValueImpl(VirtualMachine aVm,long aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof LongValue)) {
|
||||
return (value == ((LongValue)obj).value()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public int compareTo(LongValue obj) {
|
||||
long other = obj.value();
|
||||
if (value() < other) {
|
||||
return -1;
|
||||
} else if (value() == other) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theLongType();
|
||||
}
|
||||
|
||||
public long value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return(short)value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return(int)value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return(double)value;
|
||||
}
|
||||
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
if ((value > Byte.MAX_VALUE) || (value < Byte.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to byte");
|
||||
} else {
|
||||
return super.checkedByteValue();
|
||||
}
|
||||
}
|
||||
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to char");
|
||||
} else {
|
||||
return super.checkedCharValue();
|
||||
}
|
||||
}
|
||||
|
||||
short checkedShortValue() throws InvalidTypeException {
|
||||
if ((value > Short.MAX_VALUE) || (value < Short.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to short");
|
||||
} else {
|
||||
return super.checkedShortValue();
|
||||
}
|
||||
}
|
||||
|
||||
int checkedIntValue() throws InvalidTypeException {
|
||||
if ((value > Integer.MAX_VALUE) || (value < Integer.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to int");
|
||||
} else {
|
||||
return super.checkedIntValue();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.LONG;
|
||||
}
|
||||
}
|
||||
410
jdkSrc/jdk8/com/sun/tools/jdi/MethodImpl.java
Normal file
410
jdkSrc/jdk8/com/sun/tools/jdi/MethodImpl.java
Normal file
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2016, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Iterator;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
|
||||
public abstract class MethodImpl extends TypeComponentImpl
|
||||
implements Method {
|
||||
private JNITypeParser signatureParser;
|
||||
abstract int argSlotCount() throws AbsentInformationException;
|
||||
|
||||
abstract List<Location> allLineLocations(SDE.Stratum stratum,
|
||||
String sourceName)
|
||||
throws AbsentInformationException;
|
||||
|
||||
abstract List<Location> locationsOfLine(SDE.Stratum stratum,
|
||||
String sourceName,
|
||||
int lineNumber)
|
||||
throws AbsentInformationException;
|
||||
|
||||
MethodImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
|
||||
long ref,
|
||||
String name, String signature,
|
||||
String genericSignature, int modifiers) {
|
||||
super(vm, declaringType, ref, name, signature,
|
||||
genericSignature, modifiers);
|
||||
signatureParser = new JNITypeParser(signature);
|
||||
}
|
||||
|
||||
static MethodImpl createMethodImpl(VirtualMachine vm,
|
||||
ReferenceTypeImpl declaringType,
|
||||
long ref,
|
||||
String name,
|
||||
String signature,
|
||||
String genericSignature,
|
||||
int modifiers) {
|
||||
if ((modifiers &
|
||||
(VMModifiers.NATIVE | VMModifiers.ABSTRACT)) != 0) {
|
||||
return new NonConcreteMethodImpl(vm, declaringType, ref,
|
||||
name, signature,
|
||||
genericSignature,
|
||||
modifiers);
|
||||
} else {
|
||||
return new ConcreteMethodImpl(vm, declaringType, ref,
|
||||
name, signature,
|
||||
genericSignature,
|
||||
modifiers);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof MethodImpl)) {
|
||||
MethodImpl other = (MethodImpl)obj;
|
||||
return (declaringType().equals(other.declaringType())) &&
|
||||
(ref() == other.ref()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (int)ref();
|
||||
}
|
||||
|
||||
public final List<Location> allLineLocations()
|
||||
throws AbsentInformationException {
|
||||
return allLineLocations(vm.getDefaultStratum(), null);
|
||||
}
|
||||
|
||||
public List<Location> allLineLocations(String stratumID,
|
||||
String sourceName)
|
||||
throws AbsentInformationException {
|
||||
return allLineLocations(declaringType.stratum(stratumID),
|
||||
sourceName);
|
||||
}
|
||||
|
||||
public final List<Location> locationsOfLine(int lineNumber)
|
||||
throws AbsentInformationException {
|
||||
return locationsOfLine(vm.getDefaultStratum(),
|
||||
null, lineNumber);
|
||||
}
|
||||
|
||||
public List<Location> locationsOfLine(String stratumID,
|
||||
String sourceName,
|
||||
int lineNumber)
|
||||
throws AbsentInformationException {
|
||||
return locationsOfLine(declaringType.stratum(stratumID),
|
||||
sourceName, lineNumber);
|
||||
}
|
||||
|
||||
LineInfo codeIndexToLineInfo(SDE.Stratum stratum,
|
||||
long codeIndex) {
|
||||
if (stratum.isJava()) {
|
||||
return new BaseLineInfo(-1, declaringType);
|
||||
} else {
|
||||
return new StratumLineInfo(stratum.id(), -1,
|
||||
null, null);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return a text representation of the declared return type
|
||||
* of this method.
|
||||
*/
|
||||
public String returnTypeName() {
|
||||
return signatureParser.typeName();
|
||||
}
|
||||
|
||||
private String returnSignature() {
|
||||
return signatureParser.signature();
|
||||
}
|
||||
|
||||
public Type returnType() throws ClassNotLoadedException {
|
||||
return findType(returnSignature());
|
||||
}
|
||||
|
||||
public Type findType(String signature) throws ClassNotLoadedException {
|
||||
ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType();
|
||||
return enclosing.findType(signature);
|
||||
}
|
||||
|
||||
public List<String> argumentTypeNames() {
|
||||
return signatureParser.argumentTypeNames();
|
||||
}
|
||||
|
||||
public List<String> argumentSignatures() {
|
||||
return signatureParser.argumentSignatures();
|
||||
}
|
||||
|
||||
Type argumentType(int index) throws ClassNotLoadedException {
|
||||
ReferenceTypeImpl enclosing = (ReferenceTypeImpl)declaringType();
|
||||
String signature = argumentSignatures().get(index);
|
||||
return enclosing.findType(signature);
|
||||
}
|
||||
|
||||
public List<Type> argumentTypes() throws ClassNotLoadedException {
|
||||
int size = argumentSignatures().size();
|
||||
ArrayList<Type> types = new ArrayList<Type>(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
Type type = argumentType(i);
|
||||
types.add(type);
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
public int compareTo(Method method) {
|
||||
ReferenceTypeImpl declaringType = (ReferenceTypeImpl)declaringType();
|
||||
int rc = declaringType.compareTo(method.declaringType());
|
||||
if (rc == 0) {
|
||||
rc = declaringType.indexOf(this) -
|
||||
declaringType.indexOf(method);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return isModifierSet(VMModifiers.ABSTRACT);
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return !isModifierSet(VMModifiers.ABSTRACT) &&
|
||||
!isModifierSet(VMModifiers.STATIC) &&
|
||||
!isModifierSet(VMModifiers.PRIVATE) &&
|
||||
declaringType() instanceof InterfaceType;
|
||||
}
|
||||
|
||||
public boolean isSynchronized() {
|
||||
return isModifierSet(VMModifiers.SYNCHRONIZED);
|
||||
}
|
||||
|
||||
public boolean isNative() {
|
||||
return isModifierSet(VMModifiers.NATIVE);
|
||||
}
|
||||
|
||||
public boolean isVarArgs() {
|
||||
return isModifierSet(VMModifiers.VARARGS);
|
||||
}
|
||||
|
||||
public boolean isBridge() {
|
||||
return isModifierSet(VMModifiers.BRIDGE);
|
||||
}
|
||||
|
||||
public boolean isConstructor() {
|
||||
return name().equals("<init>");
|
||||
}
|
||||
|
||||
public boolean isStaticInitializer() {
|
||||
return name().equals("<clinit>");
|
||||
}
|
||||
|
||||
public boolean isObsolete() {
|
||||
try {
|
||||
return JDWP.Method.IsObsolete.process(vm,
|
||||
declaringType, ref).isObsolete;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* A container class for the return value to allow
|
||||
* proper type-checking.
|
||||
*/
|
||||
class ReturnContainer implements ValueContainer {
|
||||
ReturnContainer() {
|
||||
}
|
||||
public Type type() throws ClassNotLoadedException {
|
||||
return returnType();
|
||||
}
|
||||
public String typeName(){
|
||||
return returnTypeName();
|
||||
}
|
||||
public String signature() {
|
||||
return returnSignature(); //type().signature();
|
||||
}
|
||||
public Type findType(String signature) throws ClassNotLoadedException {
|
||||
return MethodImpl.this.findType(signature);
|
||||
}
|
||||
}
|
||||
ReturnContainer retValContainer = null;
|
||||
ReturnContainer getReturnValueContainer() {
|
||||
if (retValContainer == null) {
|
||||
retValContainer = new ReturnContainer();
|
||||
}
|
||||
return retValContainer;
|
||||
}
|
||||
|
||||
/*
|
||||
* A container class for the argument to allow
|
||||
* proper type-checking.
|
||||
*/
|
||||
class ArgumentContainer implements ValueContainer {
|
||||
int index;
|
||||
|
||||
ArgumentContainer(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
public Type type() throws ClassNotLoadedException {
|
||||
return argumentType(index);
|
||||
}
|
||||
public String typeName(){
|
||||
return argumentTypeNames().get(index);
|
||||
}
|
||||
public String signature() {
|
||||
return argumentSignatures().get(index);
|
||||
}
|
||||
public Type findType(String signature) throws ClassNotLoadedException {
|
||||
return MethodImpl.this.findType(signature);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a var args method. Thus, its last param is an
|
||||
* array. If the method has n params, then:
|
||||
* 1. If there are n args and the last is the same type as the type of
|
||||
* the last param, do nothing. IE, a String[]
|
||||
* can be passed to a String...
|
||||
* 2. If there are >= n arguments and for each arg whose number is >= n,
|
||||
* the arg type is 'compatible' with the component type of
|
||||
* the last param, then do
|
||||
* - create an array of the type of the last param
|
||||
* - put the n, ... args into this array.
|
||||
* We might have to do conversions here.
|
||||
* - put this array into arguments(n)
|
||||
* - delete arguments(n+1), ...
|
||||
* NOTE that this might modify the input list.
|
||||
*/
|
||||
void handleVarArgs(List<Value> arguments)
|
||||
throws ClassNotLoadedException, InvalidTypeException {
|
||||
List<Type> paramTypes = this.argumentTypes();
|
||||
ArrayType lastParamType = (ArrayType)paramTypes.get(paramTypes.size() - 1);
|
||||
Type componentType = lastParamType.componentType();
|
||||
int argCount = arguments.size();
|
||||
int paramCount = paramTypes.size();
|
||||
if (argCount < paramCount - 1) {
|
||||
// Error; will be caught later.
|
||||
return;
|
||||
}
|
||||
if (argCount == paramCount - 1) {
|
||||
// It is ok to pass 0 args to the var arg.
|
||||
// We have to gen a 0 length array.
|
||||
ArrayReference argArray = lastParamType.newInstance(0);
|
||||
arguments.add(argArray);
|
||||
return;
|
||||
}
|
||||
Value nthArgValue = arguments.get(paramCount - 1);
|
||||
if (nthArgValue == null && argCount == paramCount) {
|
||||
// We have one varargs parameter and it is null
|
||||
// so we don't have to do anything.
|
||||
return;
|
||||
}
|
||||
// If the first varargs parameter is null, then don't
|
||||
// access its type since it can't be an array.
|
||||
Type nthArgType = (nthArgValue == null) ? null : nthArgValue.type();
|
||||
if (nthArgType instanceof ArrayTypeImpl) {
|
||||
if (argCount == paramCount &&
|
||||
((ArrayTypeImpl)nthArgType).isAssignableTo(lastParamType)) {
|
||||
/*
|
||||
* This is case 1. A compatible array is being passed to the
|
||||
* var args array param. We don't have to do anything.
|
||||
*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Case 2. We have to verify that the n, n+1, ... args are compatible
|
||||
* with componentType, and do conversions if necessary and create
|
||||
* an array of componentType to hold these possibly converted values.
|
||||
*/
|
||||
int count = argCount - paramCount + 1;
|
||||
ArrayReference argArray = lastParamType.newInstance(count);
|
||||
|
||||
/*
|
||||
* This will copy arguments(paramCount - 1) ... to argArray(0) ...
|
||||
* doing whatever conversions are needed! It will throw an
|
||||
* exception if an incompatible arg is encountered
|
||||
*/
|
||||
argArray.setValues(0, arguments, paramCount - 1, count);
|
||||
arguments.set(paramCount - 1, argArray);
|
||||
|
||||
/*
|
||||
* Remove the excess args
|
||||
*/
|
||||
for (int ii = paramCount; ii < argCount; ii++) {
|
||||
arguments.remove(paramCount);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* The output list will be different than the input list.
|
||||
*/
|
||||
List<Value> validateAndPrepareArgumentsForInvoke(List<? extends Value> origArguments)
|
||||
throws ClassNotLoadedException, InvalidTypeException {
|
||||
|
||||
List<Value> arguments = new ArrayList<Value>(origArguments);
|
||||
if (isVarArgs()) {
|
||||
handleVarArgs(arguments);
|
||||
}
|
||||
|
||||
int argSize = arguments.size();
|
||||
|
||||
JNITypeParser parser = new JNITypeParser(signature());
|
||||
List<String> signatures = parser.argumentSignatures();
|
||||
|
||||
if (signatures.size() != argSize) {
|
||||
throw new IllegalArgumentException("Invalid argument count: expected " +
|
||||
signatures.size() + ", received " +
|
||||
arguments.size());
|
||||
}
|
||||
|
||||
for (int i = 0; i < argSize; i++) {
|
||||
Value value = arguments.get(i);
|
||||
value = ValueImpl.prepareForAssignment(value,
|
||||
new ArgumentContainer(i));
|
||||
arguments.set(i, value);
|
||||
}
|
||||
return arguments;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
sb.append(declaringType().name());
|
||||
sb.append(".");
|
||||
sb.append(name());
|
||||
sb.append("(");
|
||||
boolean first = true;
|
||||
for (String name : argumentTypeNames()) {
|
||||
if (!first) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append(name);
|
||||
first = false;
|
||||
}
|
||||
sb.append(")");
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
108
jdkSrc/jdk8/com/sun/tools/jdi/MirrorImpl.java
Normal file
108
jdkSrc/jdk8/com/sun/tools/jdi/MirrorImpl.java
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
abstract class MirrorImpl extends Object implements Mirror {
|
||||
|
||||
protected VirtualMachineImpl vm;
|
||||
|
||||
MirrorImpl(VirtualMachine aVm) {
|
||||
super();
|
||||
|
||||
// Yes, its a bit of a hack. But by doing it this
|
||||
// way, this is the only place we have to change
|
||||
// typing to substitute a new impl.
|
||||
vm = (VirtualMachineImpl)aVm;
|
||||
}
|
||||
|
||||
public VirtualMachine virtualMachine() {
|
||||
return vm;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof Mirror)) {
|
||||
Mirror other = (Mirror)obj;
|
||||
return vm.equals(other.virtualMachine());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return vm.hashCode();
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw NullPointerException on null mirror.
|
||||
* Throw VMMismatchException on wrong VM.
|
||||
*/
|
||||
void validateMirror(Mirror mirror) {
|
||||
if (!vm.equals(mirror.virtualMachine())) {
|
||||
throw new VMMismatchException(mirror.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow null mirror.
|
||||
* Throw VMMismatchException on wrong VM.
|
||||
*/
|
||||
void validateMirrorOrNull(Mirror mirror) {
|
||||
if ((mirror != null) && !vm.equals(mirror.virtualMachine())) {
|
||||
throw new VMMismatchException(mirror.toString());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Throw NullPointerException on null mirrors.
|
||||
* Throw VMMismatchException on wrong VM.
|
||||
*/
|
||||
void validateMirrors(Collection<? extends Mirror> mirrors) {
|
||||
Iterator<? extends Mirror> iter = mirrors.iterator();
|
||||
while (iter.hasNext()) {
|
||||
MirrorImpl mirror = (MirrorImpl)iter.next();
|
||||
if (!vm.equals(mirror.vm)) {
|
||||
throw new VMMismatchException(mirror.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Allow null mirrors.
|
||||
* Throw VMMismatchException on wrong VM.
|
||||
*/
|
||||
void validateMirrorsOrNulls(Collection<? extends Mirror> mirrors) {
|
||||
Iterator<? extends Mirror> iter = mirrors.iterator();
|
||||
while (iter.hasNext()) {
|
||||
MirrorImpl mirror = (MirrorImpl)iter.next();
|
||||
if ((mirror != null) && !vm.equals(mirror.vm)) {
|
||||
throw new VMMismatchException(mirror.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
jdkSrc/jdk8/com/sun/tools/jdi/MonitorInfoImpl.java
Normal file
89
jdkSrc/jdk8/com/sun/tools/jdi/MonitorInfoImpl.java
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2008, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class MonitorInfoImpl extends MirrorImpl
|
||||
implements MonitorInfo, ThreadListener {
|
||||
|
||||
/* Once false, monitorInfo should not be used.
|
||||
* access synchronized on (vm.state())
|
||||
*/
|
||||
private boolean isValid = true;
|
||||
|
||||
ObjectReference monitor;
|
||||
ThreadReference thread;
|
||||
int stack_depth;
|
||||
|
||||
MonitorInfoImpl(VirtualMachine vm, ObjectReference mon,
|
||||
ThreadReferenceImpl thread, int dpth) {
|
||||
super(vm);
|
||||
this.monitor = mon;
|
||||
this.thread = thread;
|
||||
this.stack_depth = dpth;
|
||||
thread.addListener(this);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ThreadListener implementation
|
||||
* Must be synchronized since we must protect against
|
||||
* sending defunct (isValid == false) stack ids to the back-end.
|
||||
*/
|
||||
public boolean threadResumable(ThreadAction action) {
|
||||
synchronized (vm.state()) {
|
||||
if (isValid) {
|
||||
isValid = false;
|
||||
return false; /* remove this stack frame as a listener */
|
||||
} else {
|
||||
throw new InternalException(
|
||||
"Invalid stack frame thread listener");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateMonitorInfo() {
|
||||
if (!isValid) {
|
||||
throw new InvalidStackFrameException("Thread has been resumed");
|
||||
}
|
||||
}
|
||||
|
||||
public ObjectReference monitor() {
|
||||
validateMonitorInfo();
|
||||
return monitor;
|
||||
}
|
||||
|
||||
public int stackDepth() {
|
||||
validateMonitorInfo();
|
||||
return stack_depth;
|
||||
}
|
||||
|
||||
public ThreadReference thread() {
|
||||
validateMonitorInfo();
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
112
jdkSrc/jdk8/com/sun/tools/jdi/NonConcreteMethodImpl.java
Normal file
112
jdkSrc/jdk8/com/sun/tools/jdi/NonConcreteMethodImpl.java
Normal file
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Iterator;
|
||||
import java.util.ListIterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Represents non-concrete (that is, native or abstract) methods.
|
||||
* Private to MethodImpl.
|
||||
*/
|
||||
public class NonConcreteMethodImpl extends MethodImpl {
|
||||
|
||||
private Location location = null;
|
||||
|
||||
NonConcreteMethodImpl(VirtualMachine vm,
|
||||
ReferenceTypeImpl declaringType,
|
||||
long ref,
|
||||
String name, String signature,
|
||||
String genericSignature, int modifiers) {
|
||||
|
||||
// The generic signature is set when this is created
|
||||
super(vm, declaringType, ref, name, signature,
|
||||
genericSignature, modifiers);
|
||||
}
|
||||
|
||||
public Location location() {
|
||||
if (isAbstract()) {
|
||||
return null;
|
||||
}
|
||||
if (location == null) {
|
||||
location = new LocationImpl(vm, this, -1);
|
||||
}
|
||||
return location;
|
||||
}
|
||||
|
||||
public List<Location> allLineLocations(String stratumID,
|
||||
String sourceName) {
|
||||
return new ArrayList<Location>(0);
|
||||
}
|
||||
|
||||
public List<Location> allLineLocations(SDE.Stratum stratum,
|
||||
String sourceName) {
|
||||
return new ArrayList<Location>(0);
|
||||
}
|
||||
|
||||
public List<Location> locationsOfLine(String stratumID,
|
||||
String sourceName,
|
||||
int lineNumber) {
|
||||
return new ArrayList<Location>(0);
|
||||
}
|
||||
|
||||
public List<Location> locationsOfLine(SDE.Stratum stratum,
|
||||
String sourceName,
|
||||
int lineNumber) {
|
||||
return new ArrayList<Location>(0);
|
||||
}
|
||||
|
||||
public Location locationOfCodeIndex(long codeIndex) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<LocalVariable> variables() throws AbsentInformationException {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
|
||||
public List<LocalVariable> variablesByName(String name) throws AbsentInformationException {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
|
||||
public List<LocalVariable> arguments() throws AbsentInformationException {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
|
||||
public byte[] bytecodes() {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
int argSlotCount() throws AbsentInformationException {
|
||||
throw new InternalException("should not get here");
|
||||
}
|
||||
}
|
||||
631
jdkSrc/jdk8/com/sun/tools/jdi/ObjectReferenceImpl.java
Normal file
631
jdkSrc/jdk8/com/sun/tools/jdi/ObjectReferenceImpl.java
Normal file
@@ -0,0 +1,631 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2015, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ObjectReferenceImpl extends ValueImpl
|
||||
implements ObjectReference, VMListener {
|
||||
|
||||
protected long ref;
|
||||
private ReferenceType type = null;
|
||||
private int gcDisableCount = 0;
|
||||
boolean addedListener = false;
|
||||
|
||||
// This is cached only while the VM is suspended
|
||||
protected static class Cache {
|
||||
JDWP.ObjectReference.MonitorInfo monitorInfo = null;
|
||||
}
|
||||
|
||||
private static final Cache noInitCache = new Cache();
|
||||
private static final Cache markerCache = new Cache();
|
||||
private Cache cache = noInitCache;
|
||||
|
||||
private void disableCache() {
|
||||
synchronized (vm.state()) {
|
||||
cache = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void enableCache() {
|
||||
synchronized (vm.state()) {
|
||||
cache = markerCache;
|
||||
}
|
||||
}
|
||||
|
||||
// Override in subclasses
|
||||
protected Cache newCache() {
|
||||
return new Cache();
|
||||
}
|
||||
|
||||
protected Cache getCache() {
|
||||
synchronized (vm.state()) {
|
||||
if (cache == noInitCache) {
|
||||
if (vm.state().isSuspended()) {
|
||||
// Set cache now, otherwise newly created objects are
|
||||
// not cached until resuspend
|
||||
enableCache();
|
||||
} else {
|
||||
disableCache();
|
||||
}
|
||||
}
|
||||
if (cache == markerCache) {
|
||||
cache = newCache();
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
// Return the ClassTypeImpl upon which to invoke a method.
|
||||
// By default it is our very own referenceType() but subclasses
|
||||
// can override.
|
||||
protected ClassTypeImpl invokableReferenceType(Method method) {
|
||||
return (ClassTypeImpl)referenceType();
|
||||
}
|
||||
|
||||
ObjectReferenceImpl(VirtualMachine aVm,long aRef) {
|
||||
super(aVm);
|
||||
|
||||
ref = aRef;
|
||||
}
|
||||
|
||||
protected String description() {
|
||||
return "ObjectReference " + uniqueID();
|
||||
}
|
||||
|
||||
/*
|
||||
* VMListener implementation
|
||||
*/
|
||||
public boolean vmSuspended(VMAction action) {
|
||||
enableCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean vmNotSuspended(VMAction action) {
|
||||
// make sure that cache and listener management are synchronized
|
||||
synchronized (vm.state()) {
|
||||
if (cache != null && (vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace("Clearing temporary cache for " + description());
|
||||
}
|
||||
disableCache();
|
||||
if (addedListener) {
|
||||
/*
|
||||
* If a listener was added (i.e. this is not a
|
||||
* ObjectReference that adds a listener on startup),
|
||||
* remove it here.
|
||||
*/
|
||||
addedListener = false;
|
||||
return false; // false says remove
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof ObjectReferenceImpl)) {
|
||||
ObjectReferenceImpl other = (ObjectReferenceImpl)obj;
|
||||
return (ref() == other.ref()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return(int)ref();
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return referenceType();
|
||||
}
|
||||
|
||||
public ReferenceType referenceType() {
|
||||
if (type == null) {
|
||||
try {
|
||||
JDWP.ObjectReference.ReferenceType rtinfo =
|
||||
JDWP.ObjectReference.ReferenceType.process(vm, this);
|
||||
type = vm.referenceType(rtinfo.typeID,
|
||||
rtinfo.refTypeTag);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public Value getValue(Field sig) {
|
||||
List<Field> list = new ArrayList<Field>(1);
|
||||
list.add(sig);
|
||||
Map<Field, Value> map = getValues(list);
|
||||
return map.get(sig);
|
||||
}
|
||||
|
||||
public Map<Field,Value> getValues(List<? extends Field> theFields) {
|
||||
validateMirrors(theFields);
|
||||
|
||||
List<Field> staticFields = new ArrayList<Field>(0);
|
||||
int size = theFields.size();
|
||||
List<Field> instanceFields = new ArrayList<Field>(size);
|
||||
|
||||
for (int i=0; i<size; i++) {
|
||||
Field field = (Field)theFields.get(i);
|
||||
|
||||
// Make sure the field is valid
|
||||
((ReferenceTypeImpl)referenceType()).validateFieldAccess(field);
|
||||
|
||||
// FIX ME! We need to do some sanity checking
|
||||
// here; make sure the field belongs to this
|
||||
// object.
|
||||
if (field.isStatic())
|
||||
staticFields.add(field);
|
||||
else {
|
||||
instanceFields.add(field);
|
||||
}
|
||||
}
|
||||
|
||||
Map<Field, Value> map;
|
||||
if (staticFields.size() > 0) {
|
||||
map = referenceType().getValues(staticFields);
|
||||
} else {
|
||||
map = new HashMap<Field, Value>(size);
|
||||
}
|
||||
|
||||
size = instanceFields.size();
|
||||
|
||||
JDWP.ObjectReference.GetValues.Field[] queryFields =
|
||||
new JDWP.ObjectReference.GetValues.Field[size];
|
||||
for (int i=0; i<size; i++) {
|
||||
FieldImpl field = (FieldImpl)instanceFields.get(i);/* thanks OTI */
|
||||
queryFields[i] = new JDWP.ObjectReference.GetValues.Field(
|
||||
field.ref());
|
||||
}
|
||||
ValueImpl[] values;
|
||||
try {
|
||||
values = JDWP.ObjectReference.GetValues.
|
||||
process(vm, this, queryFields).values;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
|
||||
if (size != values.length) {
|
||||
throw new InternalException(
|
||||
"Wrong number of values returned from target VM");
|
||||
}
|
||||
for (int i=0; i<size; i++) {
|
||||
FieldImpl field = (FieldImpl)instanceFields.get(i);
|
||||
map.put(field, values[i]);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setValue(Field field, Value value)
|
||||
throws InvalidTypeException, ClassNotLoadedException {
|
||||
|
||||
validateMirror(field);
|
||||
validateMirrorOrNull(value);
|
||||
|
||||
// Make sure the field is valid
|
||||
((ReferenceTypeImpl)referenceType()).validateFieldSet(field);
|
||||
|
||||
if (field.isStatic()) {
|
||||
ReferenceType type = referenceType();
|
||||
if (type instanceof ClassType) {
|
||||
((ClassType)type).setValue(field, value);
|
||||
return;
|
||||
} else {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid type for static field set");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
JDWP.ObjectReference.SetValues.FieldValue[] fvals =
|
||||
new JDWP.ObjectReference.SetValues.FieldValue[1];
|
||||
fvals[0] = new JDWP.ObjectReference.SetValues.FieldValue(
|
||||
((FieldImpl)field).ref(),
|
||||
// Validate and convert if necessary
|
||||
ValueImpl.prepareForAssignment(value,
|
||||
(FieldImpl)field));
|
||||
try {
|
||||
JDWP.ObjectReference.SetValues.process(vm, this, fvals);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
} catch (ClassNotLoadedException e) {
|
||||
/*
|
||||
* Since we got this exception,
|
||||
* the field type must be a reference type. The value
|
||||
* we're trying to set is null, but if the field's
|
||||
* class has not yet been loaded through the enclosing
|
||||
* class loader, then setting to null is essentially a
|
||||
* no-op, and we should allow it without an exception.
|
||||
*/
|
||||
if (value != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void validateMethodInvocation(Method method, int options)
|
||||
throws InvalidTypeException,
|
||||
InvocationException {
|
||||
/*
|
||||
* Method must be in this object's class, a superclass, or
|
||||
* implemented interface
|
||||
*/
|
||||
ReferenceTypeImpl declType = (ReferenceTypeImpl)method.declaringType();
|
||||
if (!declType.isAssignableFrom(this)) {
|
||||
throw new IllegalArgumentException("Invalid method");
|
||||
}
|
||||
|
||||
if (declType instanceof ClassTypeImpl) {
|
||||
validateClassMethodInvocation(method, options);
|
||||
} else if (declType instanceof InterfaceTypeImpl) {
|
||||
validateIfaceMethodInvocation(method, options);
|
||||
} else {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
}
|
||||
|
||||
void validateClassMethodInvocation(Method method, int options)
|
||||
throws InvalidTypeException,
|
||||
InvocationException {
|
||||
|
||||
ClassTypeImpl clazz = invokableReferenceType(method);
|
||||
|
||||
/*
|
||||
* Method must be a non-constructor
|
||||
*/
|
||||
if (method.isConstructor()) {
|
||||
throw new IllegalArgumentException("Cannot invoke constructor");
|
||||
}
|
||||
|
||||
/*
|
||||
* For nonvirtual invokes, method must have a body
|
||||
*/
|
||||
if (isNonVirtual(options)) {
|
||||
if (method.isAbstract()) {
|
||||
throw new IllegalArgumentException("Abstract method");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the class containing the method that will be invoked.
|
||||
* This class is needed only for proper validation of the
|
||||
* method argument types.
|
||||
*/
|
||||
ClassTypeImpl invokedClass;
|
||||
if (isNonVirtual(options)) {
|
||||
// No overrides in non-virtual invokes
|
||||
invokedClass = clazz;
|
||||
} else {
|
||||
/*
|
||||
* For virtual invokes, find any override of the method.
|
||||
* Since we are looking for a method with a real body, we
|
||||
* don't need to bother with interfaces/abstract methods.
|
||||
*/
|
||||
Method invoker = clazz.concreteMethodByName(method.name(),
|
||||
method.signature());
|
||||
// invoker is supposed to be non-null under normal circumstances
|
||||
invokedClass = (ClassTypeImpl)invoker.declaringType();
|
||||
}
|
||||
/* The above code is left over from previous versions.
|
||||
* We haven't had time to divine the intent. jjh, 7/31/2003
|
||||
*/
|
||||
}
|
||||
|
||||
void validateIfaceMethodInvocation(Method method, int options)
|
||||
throws InvalidTypeException,
|
||||
InvocationException {
|
||||
/*
|
||||
* Only default methods allowed for nonvirtual invokes
|
||||
*/
|
||||
if (isNonVirtual(options) && !method.isDefault()) {
|
||||
throw new IllegalArgumentException("Not a default method");
|
||||
}
|
||||
}
|
||||
|
||||
PacketStream sendInvokeCommand(final ThreadReferenceImpl thread,
|
||||
final ClassTypeImpl refType,
|
||||
final MethodImpl method,
|
||||
final ValueImpl[] args,
|
||||
final int options) {
|
||||
CommandSender sender =
|
||||
new CommandSender() {
|
||||
public PacketStream send() {
|
||||
return JDWP.ObjectReference.InvokeMethod.enqueueCommand(
|
||||
vm, ObjectReferenceImpl.this,
|
||||
thread, refType,
|
||||
method.ref(), args, options);
|
||||
}
|
||||
};
|
||||
|
||||
PacketStream stream;
|
||||
if ((options & INVOKE_SINGLE_THREADED) != 0) {
|
||||
stream = thread.sendResumingCommand(sender);
|
||||
} else {
|
||||
stream = vm.sendResumingCommand(sender);
|
||||
}
|
||||
return stream;
|
||||
}
|
||||
|
||||
public Value invokeMethod(ThreadReference threadIntf, Method methodIntf,
|
||||
List<? extends Value> origArguments, int options)
|
||||
throws InvalidTypeException,
|
||||
IncompatibleThreadStateException,
|
||||
InvocationException,
|
||||
ClassNotLoadedException {
|
||||
validateMirror(threadIntf);
|
||||
validateMirror(methodIntf);
|
||||
validateMirrorsOrNulls(origArguments);
|
||||
|
||||
MethodImpl method = (MethodImpl)methodIntf;
|
||||
ThreadReferenceImpl thread = (ThreadReferenceImpl)threadIntf;
|
||||
|
||||
if (method.isStatic()) {
|
||||
if (referenceType() instanceof InterfaceType) {
|
||||
InterfaceType type = (InterfaceType)referenceType();
|
||||
return type.invokeMethod(thread, method, origArguments, options);
|
||||
} else if (referenceType() instanceof ClassType) {
|
||||
ClassType type = (ClassType)referenceType();
|
||||
return type.invokeMethod(thread, method, origArguments, options);
|
||||
} else {
|
||||
throw new IllegalArgumentException("Invalid type for static method invocation");
|
||||
}
|
||||
}
|
||||
|
||||
validateMethodInvocation(method, options);
|
||||
|
||||
List<Value> arguments = method.validateAndPrepareArgumentsForInvoke(
|
||||
origArguments);
|
||||
|
||||
ValueImpl[] args = arguments.toArray(new ValueImpl[0]);
|
||||
JDWP.ObjectReference.InvokeMethod ret;
|
||||
try {
|
||||
PacketStream stream =
|
||||
sendInvokeCommand(thread, invokableReferenceType(method),
|
||||
method, args, options);
|
||||
ret = JDWP.ObjectReference.InvokeMethod.waitForReply(vm, stream);
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.INVALID_THREAD) {
|
||||
throw new IncompatibleThreadStateException();
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* There is an implict VM-wide suspend at the conclusion
|
||||
* of a normal (non-single-threaded) method invoke
|
||||
*/
|
||||
if ((options & INVOKE_SINGLE_THREADED) == 0) {
|
||||
vm.notifySuspend();
|
||||
}
|
||||
|
||||
if (ret.exception != null) {
|
||||
throw new InvocationException(ret.exception);
|
||||
} else {
|
||||
return ret.returnValue;
|
||||
}
|
||||
}
|
||||
|
||||
/* leave synchronized to keep count accurate */
|
||||
public synchronized void disableCollection() {
|
||||
if (gcDisableCount == 0) {
|
||||
try {
|
||||
JDWP.ObjectReference.DisableCollection.process(vm, this);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
gcDisableCount++;
|
||||
}
|
||||
|
||||
/* leave synchronized to keep count accurate */
|
||||
public synchronized void enableCollection() {
|
||||
gcDisableCount--;
|
||||
|
||||
if (gcDisableCount == 0) {
|
||||
try {
|
||||
JDWP.ObjectReference.EnableCollection.process(vm, this);
|
||||
} catch (JDWPException exc) {
|
||||
// If already collected, no harm done, no exception
|
||||
if (exc.errorCode() != JDWP.Error.INVALID_OBJECT) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isCollected() {
|
||||
try {
|
||||
return JDWP.ObjectReference.IsCollected.process(vm, this).
|
||||
isCollected;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
public long uniqueID() {
|
||||
return ref();
|
||||
}
|
||||
|
||||
JDWP.ObjectReference.MonitorInfo jdwpMonitorInfo()
|
||||
throws IncompatibleThreadStateException {
|
||||
JDWP.ObjectReference.MonitorInfo info = null;
|
||||
try {
|
||||
Cache local;
|
||||
|
||||
// getCache() and addlistener() must be synchronized
|
||||
// so that no events are lost.
|
||||
synchronized (vm.state()) {
|
||||
local = getCache();
|
||||
|
||||
if (local != null) {
|
||||
info = local.monitorInfo;
|
||||
|
||||
// Check if there will be something to cache
|
||||
// and there is not already a listener
|
||||
if (info == null && !vm.state().hasListener(this)) {
|
||||
/* For other, less numerous objects, this is done
|
||||
* in the constructor. Since there can be many
|
||||
* ObjectReferences, the VM listener is installed
|
||||
* and removed as needed.
|
||||
* Listener must be installed before process()
|
||||
*/
|
||||
vm.state().addListener(this);
|
||||
addedListener = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (info == null) {
|
||||
info = JDWP.ObjectReference.MonitorInfo.process(vm, this);
|
||||
if (local != null) {
|
||||
local.monitorInfo = info;
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace("ObjectReference " + uniqueID() +
|
||||
" temporarily caching monitor info");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
if (exc.errorCode() == JDWP.Error.THREAD_NOT_SUSPENDED) {
|
||||
throw new IncompatibleThreadStateException();
|
||||
} else {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
public List<ThreadReference> waitingThreads() throws IncompatibleThreadStateException {
|
||||
return Arrays.asList((ThreadReference[])jdwpMonitorInfo().waiters);
|
||||
}
|
||||
|
||||
public ThreadReference owningThread() throws IncompatibleThreadStateException {
|
||||
return jdwpMonitorInfo().owner;
|
||||
}
|
||||
|
||||
public int entryCount() throws IncompatibleThreadStateException {
|
||||
return jdwpMonitorInfo().entryCount;
|
||||
}
|
||||
|
||||
|
||||
public List<ObjectReference> referringObjects(long maxReferrers) {
|
||||
if (!vm.canGetInstanceInfo()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target does not support getting referring objects");
|
||||
}
|
||||
|
||||
if (maxReferrers < 0) {
|
||||
throw new IllegalArgumentException("maxReferrers is less than zero: "
|
||||
+ maxReferrers);
|
||||
}
|
||||
|
||||
int intMax = (maxReferrers > Integer.MAX_VALUE)?
|
||||
Integer.MAX_VALUE: (int)maxReferrers;
|
||||
// JDWP can't currently handle more than this (in mustang)
|
||||
|
||||
try {
|
||||
return Arrays.asList((ObjectReference[])JDWP.ObjectReference.ReferringObjects.
|
||||
process(vm, this, intMax).referringObjects);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
long ref() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
boolean isClassObject() {
|
||||
/*
|
||||
* Don't need to worry about subclasses since java.lang.Class is final.
|
||||
*/
|
||||
return referenceType().name().equals("java.lang.Class");
|
||||
}
|
||||
|
||||
ValueImpl prepareForAssignmentTo(ValueContainer destination)
|
||||
throws InvalidTypeException,
|
||||
ClassNotLoadedException {
|
||||
|
||||
validateAssignment(destination);
|
||||
return this; // conversion never necessary
|
||||
}
|
||||
|
||||
void validateAssignment(ValueContainer destination)
|
||||
throws InvalidTypeException, ClassNotLoadedException {
|
||||
|
||||
/*
|
||||
* Do these simpler checks before attempting a query of the destination's
|
||||
* type which might cause a confusing ClassNotLoadedException if
|
||||
* the destination is primitive or an array.
|
||||
*/
|
||||
/*
|
||||
* TO DO: Centralize JNI signature knowledge
|
||||
*/
|
||||
if (destination.signature().length() == 1) {
|
||||
throw new InvalidTypeException("Can't assign object value to primitive");
|
||||
}
|
||||
if ((destination.signature().charAt(0) == '[') &&
|
||||
(type().signature().charAt(0) != '[')) {
|
||||
throw new InvalidTypeException("Can't assign non-array value to an array");
|
||||
}
|
||||
if ("void".equals(destination.typeName())) {
|
||||
throw new InvalidTypeException("Can't assign object value to a void");
|
||||
}
|
||||
|
||||
// Validate assignment
|
||||
ReferenceType destType = (ReferenceTypeImpl)destination.type();
|
||||
ReferenceTypeImpl myType = (ReferenceTypeImpl)referenceType();
|
||||
if (!myType.isAssignableTo(destType)) {
|
||||
JNITypeParser parser = new JNITypeParser(destType.signature());
|
||||
String destTypeName = parser.typeName();
|
||||
throw new InvalidTypeException("Can't assign " +
|
||||
type().name() +
|
||||
" to " + destTypeName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String toString() {
|
||||
return "instance of " + referenceType().name() + "(id=" + uniqueID() + ")";
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.OBJECT;
|
||||
}
|
||||
|
||||
private static boolean isNonVirtual(int options) {
|
||||
return (options & INVOKE_NONVIRTUAL) != 0;
|
||||
}
|
||||
}
|
||||
73
jdkSrc/jdk8/com/sun/tools/jdi/ObsoleteMethodImpl.java
Normal file
73
jdkSrc/jdk8/com/sun/tools/jdi/ObsoleteMethodImpl.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents methods which have changed when the class was redefined.
|
||||
*/
|
||||
public class ObsoleteMethodImpl extends NonConcreteMethodImpl {
|
||||
|
||||
private Location location = null;
|
||||
|
||||
ObsoleteMethodImpl(VirtualMachine vm,
|
||||
ReferenceTypeImpl declaringType) {
|
||||
super(vm, declaringType, 0, "<obsolete>", "", null, 0);
|
||||
}
|
||||
|
||||
public boolean isObsolete() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public String returnTypeName() {
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
public Type returnType() throws ClassNotLoadedException {
|
||||
throw new ClassNotLoadedException("type unknown");
|
||||
}
|
||||
|
||||
public List<String> argumentTypeNames() {
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
|
||||
public List<String> argumentSignatures() {
|
||||
return new ArrayList<String>();
|
||||
}
|
||||
|
||||
Type argumentType(int index) throws ClassNotLoadedException {
|
||||
throw new ClassNotLoadedException("type unknown");
|
||||
}
|
||||
|
||||
public List<Type> argumentTypes() throws ClassNotLoadedException {
|
||||
return new ArrayList<Type>();
|
||||
}
|
||||
|
||||
}
|
||||
135
jdkSrc/jdk8/com/sun/tools/jdi/Packet.java
Normal file
135
jdkSrc/jdk8/com/sun/tools/jdi/Packet.java
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class Packet extends Object {
|
||||
public final static short NoFlags = 0x0;
|
||||
public final static short Reply = 0x80;
|
||||
public final static short ReplyNoError = 0x0;
|
||||
|
||||
static int uID = 1;
|
||||
final static byte[] nullData = new byte[0];
|
||||
|
||||
// Note! flags, cmdSet, and cmd are all byte values.
|
||||
// We represent them as shorts to make them easier
|
||||
// to work with.
|
||||
int id;
|
||||
short flags;
|
||||
short cmdSet;
|
||||
short cmd;
|
||||
short errorCode;
|
||||
byte[] data;
|
||||
volatile boolean replied = false;
|
||||
|
||||
/**
|
||||
* Return byte representation of the packet
|
||||
*/
|
||||
public byte[] toByteArray() {
|
||||
int len = data.length + 11;
|
||||
byte b[] = new byte[len];
|
||||
b[0] = (byte)((len >>> 24) & 0xff);
|
||||
b[1] = (byte)((len >>> 16) & 0xff);
|
||||
b[2] = (byte)((len >>> 8) & 0xff);
|
||||
b[3] = (byte)((len >>> 0) & 0xff);
|
||||
b[4] = (byte)((id >>> 24) & 0xff);
|
||||
b[5] = (byte)((id >>> 16) & 0xff);
|
||||
b[6] = (byte)((id >>> 8) & 0xff);
|
||||
b[7] = (byte)((id >>> 0) & 0xff);
|
||||
b[8] = (byte)flags;
|
||||
if ((flags & Packet.Reply) == 0) {
|
||||
b[9] = (byte)cmdSet;
|
||||
b[10] = (byte)cmd;
|
||||
} else {
|
||||
b[9] = (byte)((errorCode >>> 8) & 0xff);
|
||||
b[10] = (byte)((errorCode >>> 0) & 0xff);
|
||||
}
|
||||
if (data.length > 0) {
|
||||
System.arraycopy(data, 0, b, 11, data.length);
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a packet from its byte array representation
|
||||
*/
|
||||
public static Packet fromByteArray(byte b[]) throws IOException {
|
||||
if (b.length < 11) {
|
||||
throw new IOException("packet is insufficient size");
|
||||
}
|
||||
|
||||
int b0 = b[0] & 0xff;
|
||||
int b1 = b[1] & 0xff;
|
||||
int b2 = b[2] & 0xff;
|
||||
int b3 = b[3] & 0xff;
|
||||
int len = ((b0 << 24) | (b1 << 16) | (b2 << 8) | (b3 << 0));
|
||||
if (len != b.length) {
|
||||
throw new IOException("length size mis-match");
|
||||
}
|
||||
|
||||
int b4 = b[4] & 0xff;
|
||||
int b5 = b[5] & 0xff;
|
||||
int b6 = b[6] & 0xff;
|
||||
int b7 = b[7] & 0xff;
|
||||
|
||||
Packet p = new Packet();
|
||||
p.id = ((b4 << 24) | (b5 << 16) | (b6 << 8) | (b7 << 0));
|
||||
|
||||
p.flags = (short)(b[8] & 0xff);
|
||||
|
||||
if ((p.flags & Packet.Reply) == 0) {
|
||||
p.cmdSet = (short)(b[9] & 0xff);
|
||||
p.cmd = (short)(b[10] & 0xff);
|
||||
} else {
|
||||
short b9 = (short)(b[9] & 0xff);
|
||||
short b10 = (short)(b[10] & 0xff);
|
||||
p.errorCode = (short)((b9 << 8) + (b10 << 0));
|
||||
}
|
||||
|
||||
p.data = new byte[b.length - 11];
|
||||
System.arraycopy(b, 11, p.data, 0, p.data.length);
|
||||
return p;
|
||||
}
|
||||
|
||||
Packet()
|
||||
{
|
||||
id = uniqID();
|
||||
flags = NoFlags;
|
||||
data = nullData;
|
||||
}
|
||||
|
||||
static synchronized private int uniqID()
|
||||
{
|
||||
/*
|
||||
* JDWP spec does not require this id to be sequential and
|
||||
* increasing, but our implementation does. See
|
||||
* VirtualMachine.notifySuspend, for example.
|
||||
*/
|
||||
return uID++;
|
||||
}
|
||||
}
|
||||
628
jdkSrc/jdk8/com/sun/tools/jdi/PacketStream.java
Normal file
628
jdkSrc/jdk8/com/sun/tools/jdi/PacketStream.java
Normal file
@@ -0,0 +1,628 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
class PacketStream {
|
||||
final VirtualMachineImpl vm;
|
||||
private int inCursor = 0;
|
||||
final Packet pkt;
|
||||
private ByteArrayOutputStream dataStream = new ByteArrayOutputStream();
|
||||
private boolean isCommitted = false;
|
||||
|
||||
PacketStream(VirtualMachineImpl vm, int cmdSet, int cmd) {
|
||||
this.vm = vm;
|
||||
this.pkt = new Packet();
|
||||
pkt.cmdSet = (short)cmdSet;
|
||||
pkt.cmd = (short)cmd;
|
||||
}
|
||||
|
||||
PacketStream(VirtualMachineImpl vm, Packet pkt) {
|
||||
this.vm = vm;
|
||||
this.pkt = pkt;
|
||||
this.isCommitted = true; /* read only stream */
|
||||
}
|
||||
|
||||
int id() {
|
||||
return pkt.id;
|
||||
}
|
||||
|
||||
void send() {
|
||||
if (!isCommitted) {
|
||||
pkt.data = dataStream.toByteArray();
|
||||
vm.sendToTarget(pkt);
|
||||
isCommitted = true;
|
||||
}
|
||||
}
|
||||
|
||||
void waitForReply() throws JDWPException {
|
||||
if (!isCommitted) {
|
||||
throw new InternalException("waitForReply without send");
|
||||
}
|
||||
|
||||
vm.waitForTargetReply(pkt);
|
||||
|
||||
if (pkt.errorCode != Packet.ReplyNoError) {
|
||||
throw new JDWPException(pkt.errorCode);
|
||||
}
|
||||
}
|
||||
|
||||
void writeBoolean(boolean data) {
|
||||
if(data) {
|
||||
dataStream.write( 1 );
|
||||
} else {
|
||||
dataStream.write( 0 );
|
||||
}
|
||||
}
|
||||
|
||||
void writeByte(byte data) {
|
||||
dataStream.write( data );
|
||||
}
|
||||
|
||||
void writeChar(char data) {
|
||||
dataStream.write( (byte)((data >>> 8) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 0) & 0xFF) );
|
||||
}
|
||||
|
||||
void writeShort(short data) {
|
||||
dataStream.write( (byte)((data >>> 8) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 0) & 0xFF) );
|
||||
}
|
||||
|
||||
void writeInt(int data) {
|
||||
dataStream.write( (byte)((data >>> 24) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 16) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 8) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 0) & 0xFF) );
|
||||
}
|
||||
|
||||
void writeLong(long data) {
|
||||
dataStream.write( (byte)((data >>> 56) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 48) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 40) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 32) & 0xFF) );
|
||||
|
||||
dataStream.write( (byte)((data >>> 24) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 16) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 8) & 0xFF) );
|
||||
dataStream.write( (byte)((data >>> 0) & 0xFF) );
|
||||
}
|
||||
|
||||
void writeFloat(float data) {
|
||||
writeInt(Float.floatToIntBits(data));
|
||||
}
|
||||
|
||||
void writeDouble(double data) {
|
||||
writeLong(Double.doubleToLongBits(data));
|
||||
}
|
||||
|
||||
void writeID(int size, long data) {
|
||||
switch (size) {
|
||||
case 8:
|
||||
writeLong(data);
|
||||
break;
|
||||
case 4:
|
||||
writeInt((int)data);
|
||||
break;
|
||||
case 2:
|
||||
writeShort((short)data);
|
||||
break;
|
||||
default:
|
||||
throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);
|
||||
}
|
||||
}
|
||||
|
||||
void writeNullObjectRef() {
|
||||
writeObjectRef(0);
|
||||
}
|
||||
|
||||
void writeObjectRef(long data) {
|
||||
writeID(vm.sizeofObjectRef, data);
|
||||
}
|
||||
|
||||
void writeClassRef(long data) {
|
||||
writeID(vm.sizeofClassRef, data);
|
||||
}
|
||||
|
||||
void writeMethodRef(long data) {
|
||||
writeID(vm.sizeofMethodRef, data);
|
||||
}
|
||||
|
||||
void writeFieldRef(long data) {
|
||||
writeID(vm.sizeofFieldRef, data);
|
||||
}
|
||||
|
||||
void writeFrameRef(long data) {
|
||||
writeID(vm.sizeofFrameRef, data);
|
||||
}
|
||||
|
||||
void writeByteArray(byte[] data) {
|
||||
dataStream.write(data, 0, data.length);
|
||||
}
|
||||
|
||||
void writeString(String string) {
|
||||
try {
|
||||
byte[] stringBytes = string.getBytes("UTF8");
|
||||
writeInt(stringBytes.length);
|
||||
writeByteArray(stringBytes);
|
||||
} catch (java.io.UnsupportedEncodingException e) {
|
||||
throw new InternalException("Cannot convert string to UTF8 bytes");
|
||||
}
|
||||
}
|
||||
|
||||
void writeLocation(Location location) {
|
||||
ReferenceTypeImpl refType = (ReferenceTypeImpl)location.declaringType();
|
||||
byte tag;
|
||||
if (refType instanceof ClassType) {
|
||||
tag = JDWP.TypeTag.CLASS;
|
||||
} else if (refType instanceof InterfaceType) {
|
||||
// It's possible to have executable code in an interface
|
||||
tag = JDWP.TypeTag.INTERFACE;
|
||||
} else {
|
||||
throw new InternalException("Invalid Location");
|
||||
}
|
||||
writeByte(tag);
|
||||
writeClassRef(refType.ref());
|
||||
writeMethodRef(((MethodImpl)location.method()).ref());
|
||||
writeLong(location.codeIndex());
|
||||
}
|
||||
|
||||
void writeValue(Value val) {
|
||||
try {
|
||||
writeValueChecked(val);
|
||||
} catch (InvalidTypeException exc) { // should never happen
|
||||
throw new RuntimeException(
|
||||
"Internal error: Invalid Tag/Type pair");
|
||||
}
|
||||
}
|
||||
|
||||
void writeValueChecked(Value val) throws InvalidTypeException {
|
||||
writeByte(ValueImpl.typeValueKey(val));
|
||||
writeUntaggedValue(val);
|
||||
}
|
||||
|
||||
void writeUntaggedValue(Value val) {
|
||||
try {
|
||||
writeUntaggedValueChecked(val);
|
||||
} catch (InvalidTypeException exc) { // should never happen
|
||||
throw new RuntimeException(
|
||||
"Internal error: Invalid Tag/Type pair");
|
||||
}
|
||||
}
|
||||
|
||||
void writeUntaggedValueChecked(Value val) throws InvalidTypeException {
|
||||
byte tag = ValueImpl.typeValueKey(val);
|
||||
if (isObjectTag(tag)) {
|
||||
if (val == null) {
|
||||
writeObjectRef(0);
|
||||
} else {
|
||||
if (!(val instanceof ObjectReference)) {
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
writeObjectRef(((ObjectReferenceImpl)val).ref());
|
||||
}
|
||||
} else {
|
||||
switch (tag) {
|
||||
case JDWP.Tag.BYTE:
|
||||
if(!(val instanceof ByteValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeByte(((PrimitiveValue)val).byteValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.CHAR:
|
||||
if(!(val instanceof CharValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeChar(((PrimitiveValue)val).charValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.FLOAT:
|
||||
if(!(val instanceof FloatValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeFloat(((PrimitiveValue)val).floatValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.DOUBLE:
|
||||
if(!(val instanceof DoubleValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeDouble(((PrimitiveValue)val).doubleValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.INT:
|
||||
if(!(val instanceof IntegerValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeInt(((PrimitiveValue)val).intValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.LONG:
|
||||
if(!(val instanceof LongValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeLong(((PrimitiveValue)val).longValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.SHORT:
|
||||
if(!(val instanceof ShortValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeShort(((PrimitiveValue)val).shortValue());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.BOOLEAN:
|
||||
if(!(val instanceof BooleanValue))
|
||||
throw new InvalidTypeException();
|
||||
|
||||
writeBoolean(((PrimitiveValue)val).booleanValue());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Read byte represented as one bytes.
|
||||
*/
|
||||
byte readByte() {
|
||||
byte ret = pkt.data[inCursor];
|
||||
inCursor += 1;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read boolean represented as one byte.
|
||||
*/
|
||||
boolean readBoolean() {
|
||||
byte ret = readByte();
|
||||
return (ret != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read char represented as two bytes.
|
||||
*/
|
||||
char readChar() {
|
||||
int b1, b2;
|
||||
|
||||
b1 = pkt.data[inCursor++] & 0xff;
|
||||
b2 = pkt.data[inCursor++] & 0xff;
|
||||
|
||||
return (char)((b1 << 8) + b2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read short represented as two bytes.
|
||||
*/
|
||||
short readShort() {
|
||||
int b1, b2;
|
||||
|
||||
b1 = pkt.data[inCursor++] & 0xff;
|
||||
b2 = pkt.data[inCursor++] & 0xff;
|
||||
|
||||
return (short)((b1 << 8) + b2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read int represented as four bytes.
|
||||
*/
|
||||
int readInt() {
|
||||
int b1,b2,b3,b4;
|
||||
|
||||
b1 = pkt.data[inCursor++] & 0xff;
|
||||
b2 = pkt.data[inCursor++] & 0xff;
|
||||
b3 = pkt.data[inCursor++] & 0xff;
|
||||
b4 = pkt.data[inCursor++] & 0xff;
|
||||
|
||||
return ((b1 << 24) + (b2 << 16) + (b3 << 8) + b4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read long represented as eight bytes.
|
||||
*/
|
||||
long readLong() {
|
||||
long b1,b2,b3,b4;
|
||||
long b5,b6,b7,b8;
|
||||
|
||||
b1 = pkt.data[inCursor++] & 0xff;
|
||||
b2 = pkt.data[inCursor++] & 0xff;
|
||||
b3 = pkt.data[inCursor++] & 0xff;
|
||||
b4 = pkt.data[inCursor++] & 0xff;
|
||||
|
||||
b5 = pkt.data[inCursor++] & 0xff;
|
||||
b6 = pkt.data[inCursor++] & 0xff;
|
||||
b7 = pkt.data[inCursor++] & 0xff;
|
||||
b8 = pkt.data[inCursor++] & 0xff;
|
||||
|
||||
return ((b1 << 56) + (b2 << 48) + (b3 << 40) + (b4 << 32)
|
||||
+ (b5 << 24) + (b6 << 16) + (b7 << 8) + b8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read float represented as four bytes.
|
||||
*/
|
||||
float readFloat() {
|
||||
return Float.intBitsToFloat(readInt());
|
||||
}
|
||||
|
||||
/**
|
||||
* Read double represented as eight bytes.
|
||||
*/
|
||||
double readDouble() {
|
||||
return Double.longBitsToDouble(readLong());
|
||||
}
|
||||
|
||||
/**
|
||||
* Read string represented as four byte length followed by
|
||||
* characters of the string.
|
||||
*/
|
||||
String readString() {
|
||||
String ret;
|
||||
int len = readInt();
|
||||
|
||||
try {
|
||||
ret = new String(pkt.data, inCursor, len, "UTF8");
|
||||
} catch(java.io.UnsupportedEncodingException e) {
|
||||
System.err.println(e);
|
||||
ret = "Conversion error!";
|
||||
}
|
||||
inCursor += len;
|
||||
return ret;
|
||||
}
|
||||
|
||||
private long readID(int size) {
|
||||
switch (size) {
|
||||
case 8:
|
||||
return readLong();
|
||||
case 4:
|
||||
return (long)readInt();
|
||||
case 2:
|
||||
return (long)readShort();
|
||||
default:
|
||||
throw new UnsupportedOperationException("JDWP: ID size not supported: " + size);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read object represented as vm specific byte sequence.
|
||||
*/
|
||||
long readObjectRef() {
|
||||
return readID(vm.sizeofObjectRef);
|
||||
}
|
||||
|
||||
long readClassRef() {
|
||||
return readID(vm.sizeofClassRef);
|
||||
}
|
||||
|
||||
ObjectReferenceImpl readTaggedObjectReference() {
|
||||
byte typeKey = readByte();
|
||||
return vm.objectMirror(readObjectRef(), typeKey);
|
||||
}
|
||||
|
||||
ObjectReferenceImpl readObjectReference() {
|
||||
return vm.objectMirror(readObjectRef());
|
||||
}
|
||||
|
||||
StringReferenceImpl readStringReference() {
|
||||
long ref = readObjectRef();
|
||||
return vm.stringMirror(ref);
|
||||
}
|
||||
|
||||
ArrayReferenceImpl readArrayReference() {
|
||||
long ref = readObjectRef();
|
||||
return vm.arrayMirror(ref);
|
||||
}
|
||||
|
||||
ThreadReferenceImpl readThreadReference() {
|
||||
long ref = readObjectRef();
|
||||
return vm.threadMirror(ref);
|
||||
}
|
||||
|
||||
ThreadGroupReferenceImpl readThreadGroupReference() {
|
||||
long ref = readObjectRef();
|
||||
return vm.threadGroupMirror(ref);
|
||||
}
|
||||
|
||||
ClassLoaderReferenceImpl readClassLoaderReference() {
|
||||
long ref = readObjectRef();
|
||||
return vm.classLoaderMirror(ref);
|
||||
}
|
||||
|
||||
ClassObjectReferenceImpl readClassObjectReference() {
|
||||
long ref = readObjectRef();
|
||||
return vm.classObjectMirror(ref);
|
||||
}
|
||||
|
||||
ReferenceTypeImpl readReferenceType() {
|
||||
byte tag = readByte();
|
||||
long ref = readObjectRef();
|
||||
return vm.referenceType(ref, tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read method reference represented as vm specific byte sequence.
|
||||
*/
|
||||
long readMethodRef() {
|
||||
return readID(vm.sizeofMethodRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read field reference represented as vm specific byte sequence.
|
||||
*/
|
||||
long readFieldRef() {
|
||||
return readID(vm.sizeofFieldRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read field represented as vm specific byte sequence.
|
||||
*/
|
||||
Field readField() {
|
||||
ReferenceTypeImpl refType = readReferenceType();
|
||||
long fieldRef = readFieldRef();
|
||||
return refType.getFieldMirror(fieldRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read frame represented as vm specific byte sequence.
|
||||
*/
|
||||
long readFrameRef() {
|
||||
return readID(vm.sizeofFrameRef);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a value, first byte describes type of value to read.
|
||||
*/
|
||||
ValueImpl readValue() {
|
||||
byte typeKey = readByte();
|
||||
return readUntaggedValue(typeKey);
|
||||
}
|
||||
|
||||
ValueImpl readUntaggedValue(byte typeKey) {
|
||||
ValueImpl val = null;
|
||||
|
||||
if (isObjectTag(typeKey)) {
|
||||
val = vm.objectMirror(readObjectRef(), typeKey);
|
||||
} else {
|
||||
switch(typeKey) {
|
||||
case JDWP.Tag.BYTE:
|
||||
val = new ByteValueImpl(vm, readByte());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.CHAR:
|
||||
val = new CharValueImpl(vm, readChar());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.FLOAT:
|
||||
val = new FloatValueImpl(vm, readFloat());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.DOUBLE:
|
||||
val = new DoubleValueImpl(vm, readDouble());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.INT:
|
||||
val = new IntegerValueImpl(vm, readInt());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.LONG:
|
||||
val = new LongValueImpl(vm, readLong());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.SHORT:
|
||||
val = new ShortValueImpl(vm, readShort());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.BOOLEAN:
|
||||
val = new BooleanValueImpl(vm, readBoolean());
|
||||
break;
|
||||
|
||||
case JDWP.Tag.VOID:
|
||||
val = new VoidValueImpl(vm);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read location represented as vm specific byte sequence.
|
||||
*/
|
||||
Location readLocation() {
|
||||
byte tag = readByte();
|
||||
long classRef = readObjectRef();
|
||||
long methodRef = readMethodRef();
|
||||
long codeIndex = readLong();
|
||||
if (classRef != 0) {
|
||||
/* Valid location */
|
||||
ReferenceTypeImpl refType = vm.referenceType(classRef, tag);
|
||||
return new LocationImpl(vm, refType, methodRef, codeIndex);
|
||||
} else {
|
||||
/* Null location (example: uncaught exception) */
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
byte[] readByteArray(int length) {
|
||||
byte[] array = new byte[length];
|
||||
System.arraycopy(pkt.data, inCursor, array, 0, length);
|
||||
inCursor += length;
|
||||
return array;
|
||||
}
|
||||
|
||||
List<Value> readArrayRegion() {
|
||||
byte typeKey = readByte();
|
||||
int length = readInt();
|
||||
List<Value> list = new ArrayList<Value>(length);
|
||||
boolean gettingObjects = isObjectTag(typeKey);
|
||||
for (int i = 0; i < length; i++) {
|
||||
/*
|
||||
* Each object comes back with a type key which might
|
||||
* identify a more specific type than the type key we
|
||||
* passed in, so we use it in the decodeValue call.
|
||||
* (For primitives, we just use the original one)
|
||||
*/
|
||||
if (gettingObjects) {
|
||||
typeKey = readByte();
|
||||
}
|
||||
Value value = readUntaggedValue(typeKey);
|
||||
list.add(value);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
void writeArrayRegion(List<Value> srcValues) {
|
||||
writeInt(srcValues.size());
|
||||
for (int i = 0; i < srcValues.size(); i++) {
|
||||
Value value = srcValues.get(i);
|
||||
writeUntaggedValue(value);
|
||||
}
|
||||
}
|
||||
|
||||
int skipBytes(int n) {
|
||||
inCursor += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
byte command() {
|
||||
return (byte)pkt.cmd;
|
||||
}
|
||||
|
||||
static boolean isObjectTag(byte tag) {
|
||||
return (tag == JDWP.Tag.OBJECT) ||
|
||||
(tag == JDWP.Tag.ARRAY) ||
|
||||
(tag == JDWP.Tag.STRING) ||
|
||||
(tag == JDWP.Tag.THREAD) ||
|
||||
(tag == JDWP.Tag.THREAD_GROUP) ||
|
||||
(tag == JDWP.Tag.CLASS_LOADER) ||
|
||||
(tag == JDWP.Tag.CLASS_OBJECT);
|
||||
}
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/PrimitiveTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/PrimitiveTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
abstract class PrimitiveTypeImpl extends TypeImpl implements PrimitiveType {
|
||||
|
||||
PrimitiveTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts the given primitive value to a value of this type.
|
||||
*/
|
||||
abstract PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException;
|
||||
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
132
jdkSrc/jdk8/com/sun/tools/jdi/PrimitiveValueImpl.java
Normal file
132
jdkSrc/jdk8/com/sun/tools/jdi/PrimitiveValueImpl.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public abstract class PrimitiveValueImpl extends ValueImpl
|
||||
implements PrimitiveValue {
|
||||
|
||||
PrimitiveValueImpl(VirtualMachine aVm) {
|
||||
super(aVm);
|
||||
}
|
||||
|
||||
abstract public boolean booleanValue();
|
||||
abstract public byte byteValue();
|
||||
abstract public char charValue();
|
||||
abstract public short shortValue();
|
||||
abstract public int intValue();
|
||||
abstract public long longValue();
|
||||
abstract public float floatValue();
|
||||
abstract public double doubleValue();
|
||||
|
||||
/*
|
||||
* The checked versions of the value accessors throw
|
||||
* InvalidTypeException if the required conversion is
|
||||
* narrowing and would result in the loss of information
|
||||
* (either magnitude or precision).
|
||||
*
|
||||
* Default implementations here do no checking; subclasses
|
||||
* override as necessary to do the proper checking.
|
||||
*/
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
return byteValue();
|
||||
}
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
return charValue();
|
||||
}
|
||||
short checkedShortValue() throws InvalidTypeException {
|
||||
return shortValue();
|
||||
}
|
||||
int checkedIntValue() throws InvalidTypeException {
|
||||
return intValue();
|
||||
}
|
||||
long checkedLongValue() throws InvalidTypeException {
|
||||
return longValue();
|
||||
}
|
||||
float checkedFloatValue() throws InvalidTypeException {
|
||||
return floatValue();
|
||||
}
|
||||
|
||||
final boolean checkedBooleanValue() throws InvalidTypeException {
|
||||
/*
|
||||
* Always disallow a conversion to boolean from any other
|
||||
* primitive
|
||||
*/
|
||||
if (this instanceof BooleanValue) {
|
||||
return booleanValue();
|
||||
} else {
|
||||
throw new InvalidTypeException("Can't convert non-boolean value to boolean");
|
||||
}
|
||||
}
|
||||
|
||||
final double checkedDoubleValue() throws InvalidTypeException {
|
||||
/*
|
||||
* Can't overflow by converting to double, so this method
|
||||
* is never overridden
|
||||
*/
|
||||
return doubleValue();
|
||||
}
|
||||
|
||||
ValueImpl prepareForAssignmentTo(ValueContainer destination)
|
||||
throws InvalidTypeException {
|
||||
|
||||
return convertForAssignmentTo(destination);
|
||||
}
|
||||
|
||||
ValueImpl convertForAssignmentTo(ValueContainer destination)
|
||||
throws InvalidTypeException {
|
||||
|
||||
/*
|
||||
* TO DO: Centralize JNI signature knowledge
|
||||
*/
|
||||
if (destination.signature().length() > 1) {
|
||||
throw new InvalidTypeException("Can't assign primitive value to object");
|
||||
}
|
||||
|
||||
if ((destination.signature().charAt(0) == 'Z') &&
|
||||
(type().signature().charAt(0) != 'Z')) {
|
||||
throw new InvalidTypeException("Can't assign non-boolean value to a boolean");
|
||||
}
|
||||
|
||||
if ((destination.signature().charAt(0) != 'Z') &&
|
||||
(type().signature().charAt(0) == 'Z')) {
|
||||
throw new InvalidTypeException("Can't assign boolean value to an non-boolean");
|
||||
}
|
||||
|
||||
if ("void".equals(destination.typeName())) {
|
||||
throw new InvalidTypeException("Can't assign primitive value to a void");
|
||||
}
|
||||
|
||||
try {
|
||||
PrimitiveTypeImpl primitiveType = (PrimitiveTypeImpl)destination.type();
|
||||
return (ValueImpl)(primitiveType.convert(this));
|
||||
} catch (ClassNotLoadedException e) {
|
||||
throw new InternalException("Signature and type inconsistent for: " +
|
||||
destination.typeName());
|
||||
}
|
||||
}
|
||||
}
|
||||
164
jdkSrc/jdk8/com/sun/tools/jdi/ProcessAttachingConnector.java
Normal file
164
jdkSrc/jdk8/com/sun/tools/jdi/ProcessAttachingConnector.java
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright (c) 2005, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.sun.jdi.Bootstrap;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
|
||||
/*
|
||||
* An AttachingConnector that connects to a debuggee by specifying the process
|
||||
* id (pid) as the connector argument. If the process is a debuggee listening
|
||||
* on a transport address then this connector reads the transport address
|
||||
* and attempts to attach to it using the appropriate transport.
|
||||
*/
|
||||
|
||||
public class ProcessAttachingConnector
|
||||
extends ConnectorImpl implements AttachingConnector
|
||||
{
|
||||
/*
|
||||
* The arguments that this connector supports
|
||||
*/
|
||||
static final String ARG_PID = "pid";
|
||||
static final String ARG_TIMEOUT = "timeout";
|
||||
|
||||
com.sun.tools.attach.VirtualMachine vm;
|
||||
Transport transport;
|
||||
|
||||
public ProcessAttachingConnector() {
|
||||
addStringArgument(
|
||||
ARG_PID,
|
||||
getString("process_attaching.pid.label"),
|
||||
getString("process_attaching.pid"),
|
||||
"",
|
||||
true);
|
||||
|
||||
addIntegerArgument(
|
||||
ARG_TIMEOUT,
|
||||
getString("generic_attaching.timeout.label"), // use generic keys to keep
|
||||
getString("generic_attaching.timeout"), // resource bundle small
|
||||
"",
|
||||
false,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "local";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach to a target VM using the specified address and Connector arguments.
|
||||
*/
|
||||
public VirtualMachine attach(Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String pid = argument(ARG_PID, args).value();
|
||||
String t = argument(ARG_TIMEOUT, args).value();
|
||||
int timeout = 0;
|
||||
if (t.length() > 0) {
|
||||
timeout = Integer.decode(t).intValue();
|
||||
}
|
||||
|
||||
// Use Attach API to attach to target VM and read value of
|
||||
// sun.jdwp.listenAddress property.
|
||||
|
||||
String address = null;
|
||||
com.sun.tools.attach.VirtualMachine vm = null;
|
||||
try {
|
||||
vm = com.sun.tools.attach.VirtualMachine.attach(pid);
|
||||
Properties props = vm.getAgentProperties();
|
||||
address = props.getProperty("sun.jdwp.listenerAddress");
|
||||
} catch (Exception x) {
|
||||
throw new IOException(x.getMessage());
|
||||
} finally {
|
||||
if (vm != null) vm.detach();
|
||||
}
|
||||
|
||||
// check that the property value is formatted correctly
|
||||
|
||||
if (address == null) {
|
||||
throw new IOException("Not a debuggee, or not listening for debugger to attach");
|
||||
}
|
||||
int pos = address.indexOf(':');
|
||||
if (pos < 1) {
|
||||
throw new IOException("Unable to determine transport endpoint");
|
||||
}
|
||||
|
||||
// parse into transport library name and address
|
||||
|
||||
final String lib = address.substring(0, pos);
|
||||
address = address.substring(pos+1, address.length());
|
||||
|
||||
TransportService ts = null;
|
||||
if (lib.equals("dt_socket")) {
|
||||
ts = new SocketTransportService();
|
||||
} else {
|
||||
if (lib.equals("dt_shmem")) {
|
||||
try {
|
||||
Class<?> c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService");
|
||||
ts = (TransportService)c.newInstance();
|
||||
} catch (Exception x) { }
|
||||
}
|
||||
}
|
||||
if (ts == null) {
|
||||
throw new IOException("Transport " + lib + " not recognized");
|
||||
}
|
||||
|
||||
// connect to the debuggee
|
||||
|
||||
Connection connection = ts.attach(address, timeout, 0);
|
||||
return Bootstrap.virtualMachineManager().createVirtualMachine(connection);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.ProcessAttach";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("process_attaching.description");
|
||||
}
|
||||
|
||||
public Transport transport() {
|
||||
if (transport == null) {
|
||||
return new Transport() {
|
||||
public String name() {
|
||||
return "local";
|
||||
}
|
||||
};
|
||||
}
|
||||
return transport;
|
||||
}
|
||||
|
||||
}
|
||||
132
jdkSrc/jdk8/com/sun/tools/jdi/RawCommandLineLauncher.java
Normal file
132
jdkSrc/jdk8/com/sun/tools/jdi/RawCommandLineLauncher.java
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.tools.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import java.util.Map;
|
||||
import java.io.IOException;
|
||||
|
||||
public class RawCommandLineLauncher extends AbstractLauncher implements LaunchingConnector {
|
||||
|
||||
static private final String ARG_COMMAND = "command";
|
||||
static private final String ARG_ADDRESS = "address";
|
||||
static private final String ARG_QUOTE = "quote";
|
||||
|
||||
TransportService transportService;
|
||||
Transport transport;
|
||||
|
||||
public TransportService transportService() {
|
||||
return transportService;
|
||||
}
|
||||
|
||||
public Transport transport() {
|
||||
return transport;
|
||||
}
|
||||
|
||||
public RawCommandLineLauncher() {
|
||||
super();
|
||||
|
||||
try {
|
||||
Class<?> c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService");
|
||||
transportService = (TransportService)c.newInstance();
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_shmem";
|
||||
}
|
||||
};
|
||||
} catch (ClassNotFoundException x) {
|
||||
} catch (UnsatisfiedLinkError x) {
|
||||
} catch (InstantiationException x) {
|
||||
} catch (IllegalAccessException x) {
|
||||
};
|
||||
|
||||
if (transportService == null) {
|
||||
transportService = new SocketTransportService();
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_socket";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addStringArgument(
|
||||
ARG_COMMAND,
|
||||
getString("raw.command.label"),
|
||||
getString("raw.command"),
|
||||
"",
|
||||
true);
|
||||
addStringArgument(
|
||||
ARG_QUOTE,
|
||||
getString("raw.quote.label"),
|
||||
getString("raw.quote"),
|
||||
"\"",
|
||||
true);
|
||||
|
||||
addStringArgument(
|
||||
ARG_ADDRESS,
|
||||
getString("raw.address.label"),
|
||||
getString("raw.address"),
|
||||
"",
|
||||
true);
|
||||
}
|
||||
|
||||
|
||||
public VirtualMachine
|
||||
launch(Map<String,? extends Connector.Argument> arguments)
|
||||
throws IOException, IllegalConnectorArgumentsException,
|
||||
VMStartException
|
||||
{
|
||||
String command = argument(ARG_COMMAND, arguments).value();
|
||||
String address = argument(ARG_ADDRESS, arguments).value();
|
||||
|
||||
String quote = argument(ARG_QUOTE, arguments).value();
|
||||
|
||||
if (quote.length() > 1) {
|
||||
throw new IllegalConnectorArgumentsException("Invalid length",
|
||||
ARG_QUOTE);
|
||||
}
|
||||
|
||||
TransportService.ListenKey listener = transportService.startListening(address);
|
||||
|
||||
try {
|
||||
return launch(tokenizeCommand(command, quote.charAt(0)),
|
||||
address, listener, transportService);
|
||||
} finally {
|
||||
transportService.stopListening(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.RawCommandLineLaunch";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("raw.description");
|
||||
}
|
||||
}
|
||||
1167
jdkSrc/jdk8/com/sun/tools/jdi/ReferenceTypeImpl.java
Normal file
1167
jdkSrc/jdk8/com/sun/tools/jdi/ReferenceTypeImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
691
jdkSrc/jdk8/com/sun/tools/jdi/SDE.java
Normal file
691
jdkSrc/jdk8/com/sun/tools/jdi/SDE.java
Normal file
@@ -0,0 +1,691 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.File;
|
||||
|
||||
class SDE {
|
||||
private static final int INIT_SIZE_FILE = 3;
|
||||
private static final int INIT_SIZE_LINE = 100;
|
||||
private static final int INIT_SIZE_STRATUM = 3;
|
||||
|
||||
static final String BASE_STRATUM_NAME = "Java";
|
||||
|
||||
/* for C capatibility */
|
||||
static final String NullString = null;
|
||||
|
||||
private class FileTableRecord {
|
||||
int fileId;
|
||||
String sourceName;
|
||||
String sourcePath; // do not read - use accessor
|
||||
boolean isConverted = false;
|
||||
|
||||
/**
|
||||
* Return the sourcePath, computing it if not set.
|
||||
* If set, convert '/' in the sourcePath to the
|
||||
* local file separator.
|
||||
*/
|
||||
String getSourcePath(ReferenceTypeImpl refType) {
|
||||
if (!isConverted) {
|
||||
if (sourcePath == null) {
|
||||
sourcePath = refType.baseSourceDir() + sourceName;
|
||||
} else {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; i < sourcePath.length(); ++i) {
|
||||
char ch = sourcePath.charAt(i);
|
||||
if (ch == '/') {
|
||||
buf.append(File.separatorChar);
|
||||
} else {
|
||||
buf.append(ch);
|
||||
}
|
||||
}
|
||||
sourcePath = buf.toString();
|
||||
}
|
||||
isConverted = true;
|
||||
}
|
||||
return sourcePath;
|
||||
}
|
||||
}
|
||||
|
||||
private class LineTableRecord {
|
||||
int jplsStart;
|
||||
int jplsEnd;
|
||||
int jplsLineInc;
|
||||
int njplsStart;
|
||||
int njplsEnd;
|
||||
int fileId;
|
||||
}
|
||||
|
||||
private class StratumTableRecord {
|
||||
String id;
|
||||
int fileIndex;
|
||||
int lineIndex;
|
||||
}
|
||||
|
||||
class Stratum {
|
||||
private final int sti; /* stratum index */
|
||||
|
||||
private Stratum(int sti) {
|
||||
this.sti = sti;
|
||||
}
|
||||
|
||||
String id() {
|
||||
return stratumTable[sti].id;
|
||||
}
|
||||
|
||||
boolean isJava() {
|
||||
return sti == baseStratumIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the sourceNames for this stratum.
|
||||
* Look from our starting fileIndex upto the starting
|
||||
* fileIndex of next stratum - can do this since there
|
||||
* is always a terminator stratum.
|
||||
* Default sourceName (the first one) must be first.
|
||||
*/
|
||||
List<String> sourceNames(ReferenceTypeImpl refType) {
|
||||
int i;
|
||||
int fileIndexStart = stratumTable[sti].fileIndex;
|
||||
/* one past end */
|
||||
int fileIndexEnd = stratumTable[sti+1].fileIndex;
|
||||
List<String> result = new ArrayList<String>(fileIndexEnd - fileIndexStart);
|
||||
for (i = fileIndexStart; i < fileIndexEnd; ++i) {
|
||||
result.add(fileTable[i].sourceName);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the sourcePaths for this stratum.
|
||||
* Look from our starting fileIndex upto the starting
|
||||
* fileIndex of next stratum - can do this since there
|
||||
* is always a terminator stratum.
|
||||
* Default sourcePath (the first one) must be first.
|
||||
*/
|
||||
List<String> sourcePaths(ReferenceTypeImpl refType) {
|
||||
int i;
|
||||
int fileIndexStart = stratumTable[sti].fileIndex;
|
||||
/* one past end */
|
||||
int fileIndexEnd = stratumTable[sti+1].fileIndex;
|
||||
List<String> result = new ArrayList<String>(fileIndexEnd - fileIndexStart);
|
||||
for (i = fileIndexStart; i < fileIndexEnd; ++i) {
|
||||
result.add(fileTable[i].getSourcePath(refType));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
LineStratum lineStratum(ReferenceTypeImpl refType,
|
||||
int jplsLine) {
|
||||
int lti = stiLineTableIndex(sti, jplsLine);
|
||||
if (lti < 0) {
|
||||
return null;
|
||||
} else {
|
||||
return new LineStratum(sti, lti, refType,
|
||||
jplsLine);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LineStratum {
|
||||
private final int sti; /* stratum index */
|
||||
private final int lti; /* line table index */
|
||||
private final ReferenceTypeImpl refType;
|
||||
private final int jplsLine;
|
||||
private String sourceName = null;
|
||||
private String sourcePath = null;
|
||||
|
||||
private LineStratum(int sti, int lti,
|
||||
ReferenceTypeImpl refType,
|
||||
int jplsLine) {
|
||||
this.sti = sti;
|
||||
this.lti = lti;
|
||||
this.refType = refType;
|
||||
this.jplsLine = jplsLine;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if (obj instanceof LineStratum) {
|
||||
LineStratum other = (LineStratum)obj;
|
||||
return (lti == other.lti) &&
|
||||
(sti == other.sti) &&
|
||||
(lineNumber() == other.lineNumber()) &&
|
||||
(refType.equals(other.refType));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return (lineNumber() * 17) ^ refType.hashCode();
|
||||
}
|
||||
|
||||
int lineNumber() {
|
||||
return stiLineNumber(sti, lti, jplsLine);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch the source name and source path for
|
||||
* this line, converting or constructing
|
||||
* the source path if needed.
|
||||
*/
|
||||
void getSourceInfo() {
|
||||
if (sourceName != null) {
|
||||
// already done
|
||||
return;
|
||||
}
|
||||
int fti = stiFileTableIndex(sti, lti);
|
||||
if (fti == -1) {
|
||||
throw new InternalError(
|
||||
"Bad SourceDebugExtension, no matching source id " +
|
||||
lineTable[lti].fileId + " jplsLine: " + jplsLine);
|
||||
}
|
||||
FileTableRecord ftr = fileTable[fti];
|
||||
sourceName = ftr.sourceName;
|
||||
sourcePath = ftr.getSourcePath(refType);
|
||||
}
|
||||
|
||||
String sourceName() {
|
||||
getSourceInfo();
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
String sourcePath() {
|
||||
getSourceInfo();
|
||||
return sourcePath;
|
||||
}
|
||||
}
|
||||
|
||||
private FileTableRecord[] fileTable = null;
|
||||
private LineTableRecord[] lineTable = null;
|
||||
private StratumTableRecord[] stratumTable = null;
|
||||
|
||||
private int fileIndex = 0;
|
||||
private int lineIndex = 0;
|
||||
private int stratumIndex = 0;
|
||||
private int currentFileId = 0;
|
||||
|
||||
private int defaultStratumIndex = -1;
|
||||
private int baseStratumIndex = -2; /* so as not to match -1 above */
|
||||
private int sdePos = 0;
|
||||
|
||||
final String sourceDebugExtension;
|
||||
String jplsFilename = null;
|
||||
String defaultStratumId = null;
|
||||
boolean isValid = false;
|
||||
|
||||
SDE(String sourceDebugExtension) {
|
||||
this.sourceDebugExtension = sourceDebugExtension;
|
||||
decode();
|
||||
}
|
||||
|
||||
SDE() {
|
||||
this.sourceDebugExtension = null;
|
||||
createProxyForAbsentSDE();
|
||||
}
|
||||
|
||||
char sdePeek() {
|
||||
if (sdePos >= sourceDebugExtension.length()) {
|
||||
syntax();
|
||||
}
|
||||
return sourceDebugExtension.charAt(sdePos);
|
||||
}
|
||||
|
||||
char sdeRead() {
|
||||
if (sdePos >= sourceDebugExtension.length()) {
|
||||
syntax();
|
||||
}
|
||||
return sourceDebugExtension.charAt(sdePos++);
|
||||
}
|
||||
|
||||
void sdeAdvance() {
|
||||
sdePos++;
|
||||
}
|
||||
|
||||
void syntax() {
|
||||
throw new InternalError("bad SourceDebugExtension syntax - position " +
|
||||
sdePos);
|
||||
}
|
||||
|
||||
void syntax(String msg) {
|
||||
throw new InternalError("bad SourceDebugExtension syntax: " + msg);
|
||||
}
|
||||
|
||||
void assureLineTableSize() {
|
||||
int len = lineTable == null? 0 : lineTable.length;
|
||||
if (lineIndex >= len) {
|
||||
int i;
|
||||
int newLen = len == 0? INIT_SIZE_LINE : len * 2;
|
||||
LineTableRecord[] newTable = new LineTableRecord[newLen];
|
||||
for (i = 0; i < len; ++i) {
|
||||
newTable[i] = lineTable[i];
|
||||
}
|
||||
for (; i < newLen; ++i) {
|
||||
newTable[i] = new LineTableRecord();
|
||||
}
|
||||
lineTable = newTable;
|
||||
}
|
||||
}
|
||||
|
||||
void assureFileTableSize() {
|
||||
int len = fileTable == null? 0 : fileTable.length;
|
||||
if (fileIndex >= len) {
|
||||
int i;
|
||||
int newLen = len == 0? INIT_SIZE_FILE : len * 2;
|
||||
FileTableRecord[] newTable = new FileTableRecord[newLen];
|
||||
for (i = 0; i < len; ++i) {
|
||||
newTable[i] = fileTable[i];
|
||||
}
|
||||
for (; i < newLen; ++i) {
|
||||
newTable[i] = new FileTableRecord();
|
||||
}
|
||||
fileTable = newTable;
|
||||
}
|
||||
}
|
||||
|
||||
void assureStratumTableSize() {
|
||||
int len = stratumTable == null? 0 : stratumTable.length;
|
||||
if (stratumIndex >= len) {
|
||||
int i;
|
||||
int newLen = len == 0? INIT_SIZE_STRATUM : len * 2;
|
||||
StratumTableRecord[] newTable = new StratumTableRecord[newLen];
|
||||
for (i = 0; i < len; ++i) {
|
||||
newTable[i] = stratumTable[i];
|
||||
}
|
||||
for (; i < newLen; ++i) {
|
||||
newTable[i] = new StratumTableRecord();
|
||||
}
|
||||
stratumTable = newTable;
|
||||
}
|
||||
}
|
||||
|
||||
String readLine() {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
char ch;
|
||||
|
||||
ignoreWhite();
|
||||
while (((ch = sdeRead()) != '\n') && (ch != '\r')) {
|
||||
sb.append(ch);
|
||||
}
|
||||
// check for CR LF
|
||||
if ((ch == '\r') && (sdePeek() == '\n')) {
|
||||
sdeRead();
|
||||
}
|
||||
ignoreWhite(); // leading white
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private int defaultStratumTableIndex() {
|
||||
if ((defaultStratumIndex == -1) && (defaultStratumId != null)) {
|
||||
defaultStratumIndex =
|
||||
stratumTableIndex(defaultStratumId);
|
||||
}
|
||||
return defaultStratumIndex;
|
||||
}
|
||||
|
||||
int stratumTableIndex(String stratumId) {
|
||||
int i;
|
||||
|
||||
if (stratumId == null) {
|
||||
return defaultStratumTableIndex();
|
||||
}
|
||||
for (i = 0; i < (stratumIndex-1); ++i) {
|
||||
if (stratumTable[i].id.equals(stratumId)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return defaultStratumTableIndex();
|
||||
}
|
||||
|
||||
Stratum stratum(String stratumID) {
|
||||
int sti = stratumTableIndex(stratumID);
|
||||
return new Stratum(sti);
|
||||
}
|
||||
|
||||
List<String> availableStrata() {
|
||||
List<String> strata = new ArrayList<String>();
|
||||
|
||||
for (int i = 0; i < (stratumIndex-1); ++i) {
|
||||
StratumTableRecord rec = stratumTable[i];
|
||||
strata.add(rec.id);
|
||||
}
|
||||
return strata;
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* below functions/methods are written to compile under either Java or C
|
||||
*
|
||||
* Needed support functions:
|
||||
* sdePeek()
|
||||
* sdeRead()
|
||||
* sdeAdvance()
|
||||
* readLine()
|
||||
* assureLineTableSize()
|
||||
* assureFileTableSize()
|
||||
* assureStratumTableSize()
|
||||
* syntax()
|
||||
*
|
||||
* stratumTableIndex(String)
|
||||
*
|
||||
* Needed support variables:
|
||||
* lineTable
|
||||
* lineIndex
|
||||
* fileTable
|
||||
* fileIndex
|
||||
* currentFileId
|
||||
*
|
||||
* Needed types:
|
||||
* String
|
||||
*
|
||||
* Needed constants:
|
||||
* NullString
|
||||
*/
|
||||
|
||||
void ignoreWhite() {
|
||||
char ch;
|
||||
|
||||
while (((ch = sdePeek()) == ' ') || (ch == '\t')) {
|
||||
sdeAdvance();
|
||||
}
|
||||
}
|
||||
|
||||
void ignoreLine() {
|
||||
char ch;
|
||||
|
||||
while (((ch = sdeRead()) != '\n') && (ch != '\r')) {
|
||||
}
|
||||
/* check for CR LF */
|
||||
if ((ch == '\r') && (sdePeek() == '\n')) {
|
||||
sdeAdvance();
|
||||
}
|
||||
ignoreWhite(); /* leading white */
|
||||
}
|
||||
|
||||
int readNumber() {
|
||||
int value = 0;
|
||||
char ch;
|
||||
|
||||
ignoreWhite();
|
||||
while (((ch = sdePeek()) >= '0') && (ch <= '9')) {
|
||||
sdeAdvance();
|
||||
value = (value * 10) + ch - '0';
|
||||
}
|
||||
ignoreWhite();
|
||||
return value;
|
||||
}
|
||||
|
||||
void storeFile(int fileId, String sourceName, String sourcePath) {
|
||||
assureFileTableSize();
|
||||
fileTable[fileIndex].fileId = fileId;
|
||||
fileTable[fileIndex].sourceName = sourceName;
|
||||
fileTable[fileIndex].sourcePath = sourcePath;
|
||||
++fileIndex;
|
||||
}
|
||||
|
||||
void fileLine() {
|
||||
int hasAbsolute = 0; /* acts as boolean */
|
||||
int fileId;
|
||||
String sourceName;
|
||||
String sourcePath = null;
|
||||
|
||||
/* is there an absolute filename? */
|
||||
if (sdePeek() == '+') {
|
||||
sdeAdvance();
|
||||
hasAbsolute = 1;
|
||||
}
|
||||
fileId = readNumber();
|
||||
sourceName = readLine();
|
||||
if (hasAbsolute == 1) {
|
||||
sourcePath = readLine();
|
||||
}
|
||||
|
||||
storeFile(fileId, sourceName, sourcePath);
|
||||
}
|
||||
|
||||
void storeLine(int jplsStart, int jplsEnd, int jplsLineInc,
|
||||
int njplsStart, int njplsEnd, int fileId) {
|
||||
assureLineTableSize();
|
||||
lineTable[lineIndex].jplsStart = jplsStart;
|
||||
lineTable[lineIndex].jplsEnd = jplsEnd;
|
||||
lineTable[lineIndex].jplsLineInc = jplsLineInc;
|
||||
lineTable[lineIndex].njplsStart = njplsStart;
|
||||
lineTable[lineIndex].njplsEnd = njplsEnd;
|
||||
lineTable[lineIndex].fileId = fileId;
|
||||
++lineIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse line translation info. Syntax is
|
||||
* <NJ-start-line> [ # <file-id> ] [ , <line-count> ] :
|
||||
* <J-start-line> [ , <line-increment> ] CR
|
||||
*/
|
||||
void lineLine() {
|
||||
int lineCount = 1;
|
||||
int lineIncrement = 1;
|
||||
int njplsStart;
|
||||
int jplsStart;
|
||||
|
||||
njplsStart = readNumber();
|
||||
|
||||
/* is there a fileID? */
|
||||
if (sdePeek() == '#') {
|
||||
sdeAdvance();
|
||||
currentFileId = readNumber();
|
||||
}
|
||||
|
||||
/* is there a line count? */
|
||||
if (sdePeek() == ',') {
|
||||
sdeAdvance();
|
||||
lineCount = readNumber();
|
||||
}
|
||||
|
||||
if (sdeRead() != ':') {
|
||||
syntax();
|
||||
}
|
||||
jplsStart = readNumber();
|
||||
if (sdePeek() == ',') {
|
||||
sdeAdvance();
|
||||
lineIncrement = readNumber();
|
||||
}
|
||||
ignoreLine(); /* flush the rest */
|
||||
|
||||
storeLine(jplsStart,
|
||||
jplsStart + (lineCount * lineIncrement) -1,
|
||||
lineIncrement,
|
||||
njplsStart,
|
||||
njplsStart + lineCount -1,
|
||||
currentFileId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Until the next stratum section, everything after this
|
||||
* is in stratumId - so, store the current indicies.
|
||||
*/
|
||||
void storeStratum(String stratumId) {
|
||||
/* remove redundant strata */
|
||||
if (stratumIndex > 0) {
|
||||
if ((stratumTable[stratumIndex-1].fileIndex
|
||||
== fileIndex) &&
|
||||
(stratumTable[stratumIndex-1].lineIndex
|
||||
== lineIndex)) {
|
||||
/* nothing changed overwrite it */
|
||||
--stratumIndex;
|
||||
}
|
||||
}
|
||||
/* store the results */
|
||||
assureStratumTableSize();
|
||||
stratumTable[stratumIndex].id = stratumId;
|
||||
stratumTable[stratumIndex].fileIndex = fileIndex;
|
||||
stratumTable[stratumIndex].lineIndex = lineIndex;
|
||||
++stratumIndex;
|
||||
currentFileId = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* The beginning of a stratum's info
|
||||
*/
|
||||
void stratumSection() {
|
||||
storeStratum(readLine());
|
||||
}
|
||||
|
||||
void fileSection() {
|
||||
ignoreLine();
|
||||
while (sdePeek() != '*') {
|
||||
fileLine();
|
||||
}
|
||||
}
|
||||
|
||||
void lineSection() {
|
||||
ignoreLine();
|
||||
while (sdePeek() != '*') {
|
||||
lineLine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore a section we don't know about.
|
||||
*/
|
||||
void ignoreSection() {
|
||||
ignoreLine();
|
||||
while (sdePeek() != '*') {
|
||||
ignoreLine();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A base "Java" stratum is always available, though
|
||||
* it is not in the SourceDebugExtension.
|
||||
* Create the base stratum.
|
||||
*/
|
||||
void createJavaStratum() {
|
||||
baseStratumIndex = stratumIndex;
|
||||
storeStratum(BASE_STRATUM_NAME);
|
||||
storeFile(1, jplsFilename, NullString);
|
||||
/* JPL line numbers cannot exceed 65535 */
|
||||
storeLine(1, 65536, 1, 1, 65536, 1);
|
||||
storeStratum("Aux"); /* in case they don't declare */
|
||||
}
|
||||
|
||||
/**
|
||||
* Decode a SourceDebugExtension which is in SourceMap format.
|
||||
* This is the entry point into the recursive descent parser.
|
||||
*/
|
||||
void decode() {
|
||||
/* check for "SMAP" - allow EOF if not ours */
|
||||
if ((sourceDebugExtension.length() < 4) ||
|
||||
(sdeRead() != 'S') ||
|
||||
(sdeRead() != 'M') ||
|
||||
(sdeRead() != 'A') ||
|
||||
(sdeRead() != 'P')) {
|
||||
return; /* not our info */
|
||||
}
|
||||
ignoreLine(); /* flush the rest */
|
||||
jplsFilename = readLine();
|
||||
defaultStratumId = readLine();
|
||||
createJavaStratum();
|
||||
while (true) {
|
||||
if (sdeRead() != '*') {
|
||||
syntax();
|
||||
}
|
||||
switch (sdeRead()) {
|
||||
case 'S':
|
||||
stratumSection();
|
||||
break;
|
||||
case 'F':
|
||||
fileSection();
|
||||
break;
|
||||
case 'L':
|
||||
lineSection();
|
||||
break;
|
||||
case 'E':
|
||||
/* set end points */
|
||||
storeStratum("*terminator*");
|
||||
isValid = true;
|
||||
return;
|
||||
default:
|
||||
ignoreSection();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void createProxyForAbsentSDE() {
|
||||
jplsFilename = null;
|
||||
defaultStratumId = BASE_STRATUM_NAME;
|
||||
defaultStratumIndex = stratumIndex;
|
||||
createJavaStratum();
|
||||
storeStratum("*terminator*");
|
||||
}
|
||||
|
||||
/***************** query functions ***********************/
|
||||
|
||||
private int stiLineTableIndex(int sti, int jplsLine) {
|
||||
int i;
|
||||
int lineIndexStart;
|
||||
int lineIndexEnd;
|
||||
|
||||
lineIndexStart = stratumTable[sti].lineIndex;
|
||||
/* one past end */
|
||||
lineIndexEnd = stratumTable[sti+1].lineIndex;
|
||||
for (i = lineIndexStart; i < lineIndexEnd; ++i) {
|
||||
if ((jplsLine >= lineTable[i].jplsStart) &&
|
||||
(jplsLine <= lineTable[i].jplsEnd)) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int stiLineNumber(int sti, int lti, int jplsLine) {
|
||||
return lineTable[lti].njplsStart +
|
||||
(((jplsLine - lineTable[lti].jplsStart) /
|
||||
lineTable[lti].jplsLineInc));
|
||||
}
|
||||
|
||||
private int fileTableIndex(int sti, int fileId) {
|
||||
int i;
|
||||
int fileIndexStart = stratumTable[sti].fileIndex;
|
||||
/* one past end */
|
||||
int fileIndexEnd = stratumTable[sti+1].fileIndex;
|
||||
for (i = fileIndexStart; i < fileIndexEnd; ++i) {
|
||||
if (fileTable[i].fileId == fileId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private int stiFileTableIndex(int sti, int lti) {
|
||||
return fileTableIndex(sti, lineTable[lti].fileId);
|
||||
}
|
||||
|
||||
boolean isValid() {
|
||||
return isValid;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
|
||||
/*
|
||||
* An AttachingConnector that uses the SharedMemoryTransportService
|
||||
*/
|
||||
public class SharedMemoryAttachingConnector extends GenericAttachingConnector {
|
||||
|
||||
static final String ARG_NAME = "name";
|
||||
|
||||
public SharedMemoryAttachingConnector() {
|
||||
super(new SharedMemoryTransportService());
|
||||
|
||||
addStringArgument(
|
||||
ARG_NAME,
|
||||
getString("memory_attaching.name.label"),
|
||||
getString("memory_attaching.name"),
|
||||
"",
|
||||
true);
|
||||
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_shmem"; // for compatibility reasons
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public VirtualMachine
|
||||
attach(Map<String, ? extends Connector.Argument> arguments)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String name = argument(ARG_NAME, arguments).value();
|
||||
return super.attach(name, arguments);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.SharedMemoryAttach";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("memory_attaching.description");
|
||||
}
|
||||
}
|
||||
143
jdkSrc/jdk8/com/sun/tools/jdi/SharedMemoryConnection.java
Normal file
143
jdkSrc/jdk8/com/sun/tools/jdi/SharedMemoryConnection.java
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
class SharedMemoryConnection extends Connection {
|
||||
private long id;
|
||||
private Object receiveLock = new Object();
|
||||
private Object sendLock = new Object();
|
||||
private Object closeLock = new Object();
|
||||
private boolean closed = false;
|
||||
|
||||
private native byte receiveByte0(long id) throws IOException;
|
||||
private native void sendByte0(long id, byte b) throws IOException;
|
||||
private native void close0(long id);
|
||||
private native byte[] receivePacket0(long id)throws IOException;
|
||||
private native void sendPacket0(long id, byte b[]) throws IOException;
|
||||
|
||||
// handshake with the target VM
|
||||
void handshake(long handshakeTimeout) throws IOException {
|
||||
byte[] hello = "JDWP-Handshake".getBytes("UTF-8");
|
||||
|
||||
for (int i=0; i<hello.length; i++) {
|
||||
sendByte0(id, hello[i]);
|
||||
}
|
||||
for (int i=0; i<hello.length; i++) {
|
||||
byte b = receiveByte0(id);
|
||||
if (b != hello[i]) {
|
||||
throw new IOException("handshake failed - unrecognized message from target VM");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SharedMemoryConnection(long id) throws IOException {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
synchronized (closeLock) {
|
||||
if (!closed) {
|
||||
close0(id);
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
synchronized (closeLock) {
|
||||
return !closed;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] readPacket() throws IOException {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("Connection closed");
|
||||
}
|
||||
byte b[];
|
||||
try {
|
||||
// only one thread may be reading at a time
|
||||
synchronized (receiveLock) {
|
||||
b = receivePacket0(id);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("Connection closed");
|
||||
} else {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
|
||||
public void writePacket(byte b[]) throws IOException {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("Connection closed");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the packet size
|
||||
*/
|
||||
if (b.length < 11) {
|
||||
throw new IllegalArgumentException("packet is insufficient size");
|
||||
}
|
||||
int b0 = b[0] & 0xff;
|
||||
int b1 = b[1] & 0xff;
|
||||
int b2 = b[2] & 0xff;
|
||||
int b3 = b[3] & 0xff;
|
||||
int len = ((b0 << 24) | (b1 << 16) | (b2 << 8) | (b3 << 0));
|
||||
if (len < 11) {
|
||||
throw new IllegalArgumentException("packet is insufficient size");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the byte array contains the complete packet
|
||||
*/
|
||||
if (len > b.length) {
|
||||
throw new IllegalArgumentException("length mis-match");
|
||||
}
|
||||
|
||||
try {
|
||||
// only one thread may be writing at a time
|
||||
synchronized(sendLock) {
|
||||
sendPacket0(id, b);
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("Connection closed");
|
||||
} else {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
|
||||
/*
|
||||
* A ListeningConnector based on the SharedMemoryTransportService
|
||||
*/
|
||||
public class SharedMemoryListeningConnector extends GenericListeningConnector {
|
||||
|
||||
static final String ARG_NAME = "name";
|
||||
|
||||
public SharedMemoryListeningConnector() {
|
||||
super(new SharedMemoryTransportService());
|
||||
|
||||
addStringArgument(
|
||||
ARG_NAME,
|
||||
getString("memory_listening.name.label"),
|
||||
getString("memory_listening.name"),
|
||||
"",
|
||||
false);
|
||||
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_shmem"; // compatibility
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// override startListening so that "name" argument can be
|
||||
// converted into "address" argument
|
||||
|
||||
public String
|
||||
startListening(Map<String, ? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String name = argument(ARG_NAME, args).value();
|
||||
|
||||
// if the name argument isn't specified then we use the default
|
||||
// address for the transport service.
|
||||
if (name.length() == 0) {
|
||||
assert transportService instanceof SharedMemoryTransportService;
|
||||
SharedMemoryTransportService ts = (SharedMemoryTransportService)transportService;
|
||||
name = ts.defaultAddress();
|
||||
}
|
||||
|
||||
return super.startListening(name, args);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.SharedMemoryListen";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("memory_listening.description");
|
||||
}
|
||||
}
|
||||
190
jdkSrc/jdk8/com/sun/tools/jdi/SharedMemoryTransportService.java
Normal file
190
jdkSrc/jdk8/com/sun/tools/jdi/SharedMemoryTransportService.java
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2012, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
class SharedMemoryTransportService extends TransportService {
|
||||
private ResourceBundle messages = null;
|
||||
|
||||
/**
|
||||
* The listener returned by startListening
|
||||
*/
|
||||
static class SharedMemoryListenKey extends ListenKey {
|
||||
long id;
|
||||
String name;
|
||||
|
||||
SharedMemoryListenKey(long id, String name) {
|
||||
this.id = id;
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
long id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
void setId(long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String address() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return address();
|
||||
}
|
||||
}
|
||||
|
||||
SharedMemoryTransportService() {
|
||||
System.loadLibrary("dt_shmem");
|
||||
initialize();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "SharedMemory";
|
||||
}
|
||||
|
||||
public String defaultAddress() {
|
||||
return "javadebug";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return localized description of this transport service
|
||||
*/
|
||||
public String description() {
|
||||
synchronized (this) {
|
||||
if (messages == null) {
|
||||
messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi");
|
||||
}
|
||||
}
|
||||
return messages.getString("memory_transportservice.description");
|
||||
}
|
||||
|
||||
public Capabilities capabilities() {
|
||||
return new SharedMemoryTransportServiceCapabilities();
|
||||
}
|
||||
|
||||
private native void initialize();
|
||||
private native long startListening0(String address) throws IOException;
|
||||
private native long attach0(String address, long attachTimeout) throws IOException;
|
||||
private native void stopListening0(long id) throws IOException;
|
||||
private native long accept0(long id, long acceptTimeout) throws IOException;
|
||||
private native String name(long id) throws IOException;
|
||||
|
||||
public Connection attach(String address, long attachTimeout, long handshakeTimeout) throws IOException {
|
||||
if (address == null) {
|
||||
throw new NullPointerException("address is null");
|
||||
}
|
||||
long id = attach0(address, attachTimeout);
|
||||
SharedMemoryConnection conn = new SharedMemoryConnection(id);
|
||||
conn.handshake(handshakeTimeout);
|
||||
return conn;
|
||||
}
|
||||
|
||||
public TransportService.ListenKey startListening(String address) throws IOException {
|
||||
if (address == null || address.length() == 0) {
|
||||
address = defaultAddress();
|
||||
}
|
||||
long id = startListening0(address);
|
||||
return new SharedMemoryListenKey(id, name(id));
|
||||
}
|
||||
|
||||
public ListenKey startListening() throws IOException {
|
||||
return startListening(null);
|
||||
}
|
||||
|
||||
public void stopListening(ListenKey listener) throws IOException {
|
||||
if (!(listener instanceof SharedMemoryListenKey)) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
|
||||
long id;
|
||||
SharedMemoryListenKey key = (SharedMemoryListenKey)listener;
|
||||
synchronized (key) {
|
||||
id = key.id();
|
||||
if (id == 0) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
|
||||
// invalidate the id
|
||||
key.setId(0);
|
||||
}
|
||||
stopListening0(id);
|
||||
}
|
||||
|
||||
public Connection accept(ListenKey listener, long acceptTimeout, long handshakeTimeout) throws IOException {
|
||||
if (!(listener instanceof SharedMemoryListenKey)) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
|
||||
long transportId;
|
||||
SharedMemoryListenKey key = (SharedMemoryListenKey)listener;
|
||||
synchronized (key) {
|
||||
transportId = key.id();
|
||||
if (transportId == 0) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
}
|
||||
|
||||
// in theory another thread could call stopListening before
|
||||
// accept0 is called. In that case accept0 will try to accept
|
||||
// with an invalid "transport id" - this should result in an
|
||||
// IOException.
|
||||
|
||||
long connectId = accept0(transportId, acceptTimeout);
|
||||
SharedMemoryConnection conn = new SharedMemoryConnection(connectId);
|
||||
conn.handshake(handshakeTimeout);
|
||||
return conn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
class SharedMemoryTransportServiceCapabilities extends TransportService.Capabilities {
|
||||
|
||||
public boolean supportsMultipleConnections() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean supportsAttachTimeout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsAcceptTimeout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsHandshakeTimeout() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
44
jdkSrc/jdk8/com/sun/tools/jdi/ShortTypeImpl.java
Normal file
44
jdkSrc/jdk8/com/sun/tools/jdi/ShortTypeImpl.java
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class ShortTypeImpl extends PrimitiveTypeImpl implements ShortType {
|
||||
ShortTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.SHORT);
|
||||
}
|
||||
|
||||
PrimitiveValue convert(PrimitiveValue value) throws InvalidTypeException {
|
||||
return vm.mirrorOf(((PrimitiveValueImpl)value).checkedShortValue());
|
||||
}
|
||||
|
||||
}
|
||||
124
jdkSrc/jdk8/com/sun/tools/jdi/ShortValueImpl.java
Normal file
124
jdkSrc/jdk8/com/sun/tools/jdi/ShortValueImpl.java
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class ShortValueImpl extends PrimitiveValueImpl
|
||||
implements ShortValue {
|
||||
private short value;
|
||||
|
||||
ShortValueImpl(VirtualMachine aVm,short aValue) {
|
||||
super(aVm);
|
||||
|
||||
value = aValue;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof ShortValue)) {
|
||||
return (value == ((ShortValue)obj).value()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return intValue();
|
||||
}
|
||||
|
||||
public int compareTo(ShortValue obj) {
|
||||
short other = obj.value();
|
||||
return value() - other;
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theShortType();
|
||||
}
|
||||
|
||||
public short value() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public boolean booleanValue() {
|
||||
return(value == 0)?false:true;
|
||||
}
|
||||
|
||||
public byte byteValue() {
|
||||
return(byte)value;
|
||||
}
|
||||
|
||||
public char charValue() {
|
||||
return(char)value;
|
||||
}
|
||||
|
||||
public short shortValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public int intValue() {
|
||||
return(int)value;
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return(long)value;
|
||||
}
|
||||
|
||||
public float floatValue() {
|
||||
return(float)value;
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return(double)value;
|
||||
}
|
||||
|
||||
byte checkedByteValue() throws InvalidTypeException {
|
||||
if ((value > Byte.MAX_VALUE) || (value < Byte.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to byte");
|
||||
} else {
|
||||
return super.checkedByteValue();
|
||||
}
|
||||
}
|
||||
|
||||
char checkedCharValue() throws InvalidTypeException {
|
||||
if ((value > Character.MAX_VALUE) || (value < Character.MIN_VALUE)) {
|
||||
throw new InvalidTypeException("Can't convert " + value + " to char");
|
||||
} else {
|
||||
return super.checkedCharValue();
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "" + value;
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.SHORT;
|
||||
}
|
||||
}
|
||||
100
jdkSrc/jdk8/com/sun/tools/jdi/SocketAttachingConnector.java
Normal file
100
jdkSrc/jdk8/com/sun/tools/jdi/SocketAttachingConnector.java
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.UnknownHostException;
|
||||
|
||||
/*
|
||||
* An AttachingConnector that uses the SocketTransportService
|
||||
*/
|
||||
public class SocketAttachingConnector extends GenericAttachingConnector {
|
||||
|
||||
static final String ARG_PORT = "port";
|
||||
static final String ARG_HOST = "hostname";
|
||||
|
||||
public SocketAttachingConnector() {
|
||||
super(new SocketTransportService());
|
||||
|
||||
String defaultHostName;
|
||||
try {
|
||||
defaultHostName = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
defaultHostName = "";
|
||||
}
|
||||
|
||||
addStringArgument(
|
||||
ARG_HOST,
|
||||
getString("socket_attaching.host.label"),
|
||||
getString("socket_attaching.host"),
|
||||
defaultHostName,
|
||||
false);
|
||||
|
||||
addIntegerArgument(
|
||||
ARG_PORT,
|
||||
getString("socket_attaching.port.label"),
|
||||
getString("socket_attaching.port"),
|
||||
"",
|
||||
true,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_socket"; // for compatibility reasons
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Create an "address" from the hostname and port connector
|
||||
* arguments and attach to the target VM.
|
||||
*/
|
||||
public VirtualMachine
|
||||
attach(Map<String,? extends Connector.Argument> arguments)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String host = argument(ARG_HOST, arguments).value();
|
||||
if (host.length() > 0) {
|
||||
host = host + ":";
|
||||
}
|
||||
String address = host + argument(ARG_PORT, arguments).value();
|
||||
return super.attach(address, arguments);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.SocketAttach";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("socket_attaching.description");
|
||||
}
|
||||
}
|
||||
113
jdkSrc/jdk8/com/sun/tools/jdi/SocketListeningConnector.java
Normal file
113
jdkSrc/jdk8/com/sun/tools/jdi/SocketListeningConnector.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2018, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.io.IOException;
|
||||
import com.sun.jdi.connect.spi.TransportService;
|
||||
|
||||
/*
|
||||
* An ListeningConnector that uses the SocketTransportService
|
||||
*/
|
||||
public class SocketListeningConnector extends GenericListeningConnector {
|
||||
|
||||
static final String ARG_PORT = "port";
|
||||
static final String ARG_LOCALADDR = "localAddress";
|
||||
|
||||
public SocketListeningConnector() {
|
||||
super(new SocketTransportService());
|
||||
|
||||
addIntegerArgument(
|
||||
ARG_PORT,
|
||||
getString("socket_listening.port.label"),
|
||||
getString("socket_listening.port"),
|
||||
"",
|
||||
false,
|
||||
0, Integer.MAX_VALUE);
|
||||
|
||||
addStringArgument(
|
||||
ARG_LOCALADDR,
|
||||
getString("socket_listening.localaddr.label"),
|
||||
getString("socket_listening.localaddr"),
|
||||
"", // default is wildcard
|
||||
false);
|
||||
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_socket"; // for compatibility reasons
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
public String
|
||||
startListening(Map<String,? extends Connector.Argument> args)
|
||||
throws IOException, IllegalConnectorArgumentsException
|
||||
{
|
||||
String port = argument(ARG_PORT, args).value();
|
||||
String localaddr = argument(ARG_LOCALADDR, args).value();
|
||||
|
||||
// default to system chosen port
|
||||
if (port.length() == 0) {
|
||||
port = "0";
|
||||
}
|
||||
|
||||
if (localaddr.length() > 0) {
|
||||
localaddr = localaddr + ":" + port;
|
||||
} else {
|
||||
localaddr = port;
|
||||
}
|
||||
|
||||
return super.startListening(localaddr, args);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.SocketListen";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("socket_listening.description");
|
||||
}
|
||||
|
||||
// If the port is auto detected update the argument map with the bound port number.
|
||||
@Override
|
||||
protected void updateArgumentMapIfRequired(
|
||||
Map<String, ? extends Connector.Argument> args, TransportService.ListenKey listener) {
|
||||
if (isWildcardPort(args)) {
|
||||
String[] address = listener.address().split(":");
|
||||
if (address.length > 1) {
|
||||
args.get(ARG_PORT).setValue(address[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isWildcardPort(Map<String, ? extends Connector.Argument> args) {
|
||||
String port = args.get(ARG_PORT).value();
|
||||
return port.isEmpty() || Integer.valueOf(port) == 0;
|
||||
}
|
||||
}
|
||||
536
jdkSrc/jdk8/com/sun/tools/jdi/SocketTransportService.java
Normal file
536
jdkSrc/jdk8/com/sun/tools/jdi/SocketTransportService.java
Normal file
@@ -0,0 +1,536 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.util.Map;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
/*
|
||||
* A transport service based on a TCP connection between the
|
||||
* debugger and debugee.
|
||||
*/
|
||||
|
||||
public class SocketTransportService extends TransportService {
|
||||
private ResourceBundle messages = null;
|
||||
|
||||
/**
|
||||
* The listener returned by startListening encapsulates
|
||||
* the ServerSocket.
|
||||
*/
|
||||
static class SocketListenKey extends ListenKey {
|
||||
ServerSocket ss;
|
||||
|
||||
SocketListenKey(ServerSocket ss) {
|
||||
this.ss = ss;
|
||||
}
|
||||
|
||||
ServerSocket socket() {
|
||||
return ss;
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the string representation of the address that this
|
||||
* listen key represents.
|
||||
*/
|
||||
public String address() {
|
||||
InetAddress address = ss.getInetAddress();
|
||||
|
||||
/*
|
||||
* If bound to the wildcard address then use current local
|
||||
* hostname. In the event that we don't know our own hostname
|
||||
* then assume that host supports IPv4 and return something to
|
||||
* represent the loopback address.
|
||||
*/
|
||||
if (address.isAnyLocalAddress()) {
|
||||
try {
|
||||
address = InetAddress.getLocalHost();
|
||||
} catch (UnknownHostException uhe) {
|
||||
byte[] loopback = {0x7f,0x00,0x00,0x01};
|
||||
try {
|
||||
address = InetAddress.getByAddress("127.0.0.1", loopback);
|
||||
} catch (UnknownHostException x) {
|
||||
throw new InternalError("unable to get local hostname");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now decide if we return a hostname or IP address. Where possible
|
||||
* return a hostname but in the case that we are bound to an
|
||||
* address that isn't registered in the name service then we
|
||||
* return an address.
|
||||
*/
|
||||
String result;
|
||||
String hostname = address.getHostName();
|
||||
String hostaddr = address.getHostAddress();
|
||||
if (hostname.equals(hostaddr)) {
|
||||
if (address instanceof Inet6Address) {
|
||||
result = "[" + hostaddr + "]";
|
||||
} else {
|
||||
result = hostaddr;
|
||||
}
|
||||
} else {
|
||||
result = hostname;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finally return "hostname:port", "ipv4-address:port" or
|
||||
* "[ipv6-address]:port".
|
||||
*/
|
||||
return result + ":" + ss.getLocalPort();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return address();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handshake with the debuggee
|
||||
*/
|
||||
void handshake(Socket s, long timeout) throws IOException {
|
||||
s.setSoTimeout((int)timeout);
|
||||
|
||||
byte[] hello = "JDWP-Handshake".getBytes("UTF-8");
|
||||
s.getOutputStream().write(hello);
|
||||
|
||||
byte[] b = new byte[hello.length];
|
||||
int received = 0;
|
||||
while (received < hello.length) {
|
||||
int n;
|
||||
try {
|
||||
n = s.getInputStream().read(b, received, hello.length-received);
|
||||
} catch (SocketTimeoutException x) {
|
||||
throw new IOException("handshake timeout");
|
||||
}
|
||||
if (n < 0) {
|
||||
s.close();
|
||||
throw new IOException("handshake failed - connection prematurally closed");
|
||||
}
|
||||
received += n;
|
||||
}
|
||||
for (int i=0; i<hello.length; i++) {
|
||||
if (b[i] != hello[i]) {
|
||||
throw new IOException("handshake failed - unrecognized message from target VM");
|
||||
}
|
||||
}
|
||||
|
||||
// disable read timeout
|
||||
s.setSoTimeout(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* No-arg constructor
|
||||
*/
|
||||
public SocketTransportService() {
|
||||
}
|
||||
|
||||
/**
|
||||
* The name of this transport service
|
||||
*/
|
||||
public String name() {
|
||||
return "Socket";
|
||||
}
|
||||
|
||||
/**
|
||||
* Return localized description of this transport service
|
||||
*/
|
||||
public String description() {
|
||||
synchronized (this) {
|
||||
if (messages == null) {
|
||||
messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi");
|
||||
}
|
||||
}
|
||||
return messages.getString("socket_transportservice.description");
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the capabilities of this transport service
|
||||
*/
|
||||
public Capabilities capabilities() {
|
||||
return new SocketTransportServiceCapabilities();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Attach to the specified address with optional attach and handshake
|
||||
* timeout.
|
||||
*/
|
||||
public Connection attach(String address, long attachTimeout, long handshakeTimeout)
|
||||
throws IOException {
|
||||
|
||||
if (address == null) {
|
||||
throw new NullPointerException("address is null");
|
||||
}
|
||||
if (attachTimeout < 0 || handshakeTimeout < 0) {
|
||||
throw new IllegalArgumentException("timeout is negative");
|
||||
}
|
||||
|
||||
int splitIndex = address.indexOf(':');
|
||||
String host;
|
||||
String portStr;
|
||||
if (splitIndex < 0) {
|
||||
host = InetAddress.getLocalHost().getHostName();
|
||||
portStr = address;
|
||||
} else {
|
||||
host = address.substring(0, splitIndex);
|
||||
portStr = address.substring(splitIndex+1);
|
||||
}
|
||||
|
||||
int port;
|
||||
try {
|
||||
port = Integer.decode(portStr).intValue();
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"unable to parse port number in address");
|
||||
}
|
||||
|
||||
|
||||
// open TCP connection to VM
|
||||
|
||||
InetSocketAddress sa = new InetSocketAddress(host, port);
|
||||
Socket s = new Socket();
|
||||
try {
|
||||
s.connect(sa, (int)attachTimeout);
|
||||
} catch (SocketTimeoutException exc) {
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException x) { }
|
||||
throw new TransportTimeoutException("timed out trying to establish connection");
|
||||
}
|
||||
|
||||
// handshake with the target VM
|
||||
try {
|
||||
handshake(s, handshakeTimeout);
|
||||
} catch (IOException exc) {
|
||||
try {
|
||||
s.close();
|
||||
} catch (IOException x) { }
|
||||
throw exc;
|
||||
}
|
||||
|
||||
return new SocketConnection(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Listen on the specified address and port. Return a listener
|
||||
* that encapsulates the ServerSocket.
|
||||
*/
|
||||
ListenKey startListening(String localaddress, int port) throws IOException {
|
||||
InetSocketAddress sa;
|
||||
if (localaddress == null) {
|
||||
sa = new InetSocketAddress(port);
|
||||
} else {
|
||||
sa = new InetSocketAddress(localaddress, port);
|
||||
}
|
||||
ServerSocket ss = new ServerSocket();
|
||||
ss.bind(sa);
|
||||
return new SocketListenKey(ss);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on the specified address
|
||||
*/
|
||||
public ListenKey startListening(String address) throws IOException {
|
||||
// use ephemeral port if address isn't specified.
|
||||
if (address == null || address.length() == 0) {
|
||||
address = "0";
|
||||
}
|
||||
|
||||
int splitIndex = address.indexOf(':');
|
||||
String localaddr = null;
|
||||
if (splitIndex >= 0) {
|
||||
localaddr = address.substring(0, splitIndex);
|
||||
address = address.substring(splitIndex+1);
|
||||
}
|
||||
|
||||
int port;
|
||||
try {
|
||||
port = Integer.decode(address).intValue();
|
||||
} catch (NumberFormatException e) {
|
||||
throw new IllegalArgumentException(
|
||||
"unable to parse port number in address");
|
||||
}
|
||||
|
||||
return startListening(localaddr, port);
|
||||
}
|
||||
|
||||
/**
|
||||
* Listen on the default address
|
||||
*/
|
||||
public ListenKey startListening() throws IOException {
|
||||
return startListening(null, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the listener
|
||||
*/
|
||||
public void stopListening(ListenKey listener) throws IOException {
|
||||
if (!(listener instanceof SocketListenKey)) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
|
||||
synchronized (listener) {
|
||||
ServerSocket ss = ((SocketListenKey)listener).socket();
|
||||
|
||||
// if the ServerSocket has been closed it means
|
||||
// the listener is invalid
|
||||
if (ss.isClosed()) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
ss.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept a connection from a debuggee and handshake with it.
|
||||
*/
|
||||
public Connection accept(ListenKey listener, long acceptTimeout, long handshakeTimeout) throws IOException {
|
||||
if (acceptTimeout < 0 || handshakeTimeout < 0) {
|
||||
throw new IllegalArgumentException("timeout is negative");
|
||||
}
|
||||
if (!(listener instanceof SocketListenKey)) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
ServerSocket ss;
|
||||
|
||||
// obtain the ServerSocket from the listener - if the
|
||||
// socket is closed it means the listener is invalid
|
||||
synchronized (listener) {
|
||||
ss = ((SocketListenKey)listener).socket();
|
||||
if (ss.isClosed()) {
|
||||
throw new IllegalArgumentException("Invalid listener");
|
||||
}
|
||||
}
|
||||
|
||||
// from here onwards it's possible that the ServerSocket
|
||||
// may be closed by a call to stopListening - that's okay
|
||||
// because the ServerSocket methods will throw an
|
||||
// IOException indicating the socket is closed.
|
||||
//
|
||||
// Additionally, it's possible that another thread calls accept
|
||||
// with a different accept timeout - that creates a same race
|
||||
// condition between setting the timeout and calling accept.
|
||||
// As it is such an unlikely scenario (requires both threads
|
||||
// to be using the same listener we've chosen to ignore the issue).
|
||||
|
||||
ss.setSoTimeout((int)acceptTimeout);
|
||||
Socket s;
|
||||
try {
|
||||
s = ss.accept();
|
||||
} catch (SocketTimeoutException x) {
|
||||
throw new TransportTimeoutException("timeout waiting for connection");
|
||||
}
|
||||
|
||||
// handshake here
|
||||
handshake(s, handshakeTimeout);
|
||||
|
||||
return new SocketConnection(s);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The Connection returned by attach and accept is one of these
|
||||
*/
|
||||
class SocketConnection extends Connection {
|
||||
private Socket socket;
|
||||
private boolean closed = false;
|
||||
private OutputStream socketOutput;
|
||||
private InputStream socketInput;
|
||||
private Object receiveLock = new Object();
|
||||
private Object sendLock = new Object();
|
||||
private Object closeLock = new Object();
|
||||
|
||||
SocketConnection(Socket socket) throws IOException {
|
||||
this.socket = socket;
|
||||
socket.setTcpNoDelay(true);
|
||||
socketInput = socket.getInputStream();
|
||||
socketOutput = socket.getOutputStream();
|
||||
}
|
||||
|
||||
public void close() throws IOException {
|
||||
synchronized (closeLock) {
|
||||
if (closed) {
|
||||
return;
|
||||
}
|
||||
socketOutput.close();
|
||||
socketInput.close();
|
||||
socket.close();
|
||||
closed = true;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isOpen() {
|
||||
synchronized (closeLock) {
|
||||
return !closed;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] readPacket() throws IOException {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("connection is closed");
|
||||
}
|
||||
synchronized (receiveLock) {
|
||||
int b1,b2,b3,b4;
|
||||
|
||||
// length
|
||||
try {
|
||||
b1 = socketInput.read();
|
||||
b2 = socketInput.read();
|
||||
b3 = socketInput.read();
|
||||
b4 = socketInput.read();
|
||||
} catch (IOException ioe) {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("connection is closed");
|
||||
} else {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
|
||||
// EOF
|
||||
if (b1<0) {
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
if (b2<0 || b3<0 || b4<0) {
|
||||
throw new IOException("protocol error - premature EOF");
|
||||
}
|
||||
|
||||
int len = ((b1 << 24) | (b2 << 16) | (b3 << 8) | (b4 << 0));
|
||||
|
||||
if (len < 0) {
|
||||
throw new IOException("protocol error - invalid length");
|
||||
}
|
||||
|
||||
byte b[] = new byte[len];
|
||||
b[0] = (byte)b1;
|
||||
b[1] = (byte)b2;
|
||||
b[2] = (byte)b3;
|
||||
b[3] = (byte)b4;
|
||||
|
||||
int off = 4;
|
||||
len -= off;
|
||||
|
||||
while (len > 0) {
|
||||
int count;
|
||||
try {
|
||||
count = socketInput.read(b, off, len);
|
||||
} catch (IOException ioe) {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("connection is closed");
|
||||
} else {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
if (count < 0) {
|
||||
throw new IOException("protocol error - premature EOF");
|
||||
}
|
||||
len -= count;
|
||||
off += count;
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
}
|
||||
|
||||
public void writePacket(byte b[]) throws IOException {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("connection is closed");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the packet size
|
||||
*/
|
||||
if (b.length < 11) {
|
||||
throw new IllegalArgumentException("packet is insufficient size");
|
||||
}
|
||||
int b0 = b[0] & 0xff;
|
||||
int b1 = b[1] & 0xff;
|
||||
int b2 = b[2] & 0xff;
|
||||
int b3 = b[3] & 0xff;
|
||||
int len = ((b0 << 24) | (b1 << 16) | (b2 << 8) | (b3 << 0));
|
||||
if (len < 11) {
|
||||
throw new IllegalArgumentException("packet is insufficient size");
|
||||
}
|
||||
|
||||
/*
|
||||
* Check that the byte array contains the complete packet
|
||||
*/
|
||||
if (len > b.length) {
|
||||
throw new IllegalArgumentException("length mis-match");
|
||||
}
|
||||
|
||||
synchronized (sendLock) {
|
||||
try {
|
||||
/*
|
||||
* Send the packet (ignoring any bytes that follow
|
||||
* the packet in the byte array).
|
||||
*/
|
||||
socketOutput.write(b, 0, len);
|
||||
} catch (IOException ioe) {
|
||||
if (!isOpen()) {
|
||||
throw new ClosedConnectionException("connection is closed");
|
||||
} else {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The capabilities of the socket transport service
|
||||
*/
|
||||
class SocketTransportServiceCapabilities extends TransportService.Capabilities {
|
||||
|
||||
public boolean supportsMultipleConnections() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsAttachTimeout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsAcceptTimeout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean supportsHandshakeTimeout() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
404
jdkSrc/jdk8/com/sun/tools/jdi/StackFrameImpl.java
Normal file
404
jdkSrc/jdk8/com/sun/tools/jdi/StackFrameImpl.java
Normal file
@@ -0,0 +1,404 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
|
||||
public class StackFrameImpl extends MirrorImpl
|
||||
implements StackFrame, ThreadListener
|
||||
{
|
||||
/* Once false, frame should not be used.
|
||||
* access synchronized on (vm.state())
|
||||
*/
|
||||
private boolean isValid = true;
|
||||
|
||||
private final ThreadReferenceImpl thread;
|
||||
private final long id;
|
||||
private final Location location;
|
||||
private Map<String, LocalVariable> visibleVariables = null;
|
||||
private ObjectReference thisObject = null;
|
||||
|
||||
StackFrameImpl(VirtualMachine vm, ThreadReferenceImpl thread,
|
||||
long id, Location location) {
|
||||
super(vm);
|
||||
this.thread = thread;
|
||||
this.id = id;
|
||||
this.location = location;
|
||||
thread.addListener(this);
|
||||
}
|
||||
|
||||
/*
|
||||
* ThreadListener implementation
|
||||
* Must be synchronized since we must protect against
|
||||
* sending defunct (isValid == false) stack ids to the back-end.
|
||||
*/
|
||||
public boolean threadResumable(ThreadAction action) {
|
||||
synchronized (vm.state()) {
|
||||
if (isValid) {
|
||||
isValid = false;
|
||||
return false; /* remove this stack frame as a listener */
|
||||
} else {
|
||||
throw new InternalException(
|
||||
"Invalid stack frame thread listener");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void validateStackFrame() {
|
||||
if (!isValid) {
|
||||
throw new InvalidStackFrameException("Thread has been resumed");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the frame location.
|
||||
* Need not be synchronized since it cannot be provably stale.
|
||||
*/
|
||||
public Location location() {
|
||||
validateStackFrame();
|
||||
return location;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the thread holding the frame.
|
||||
* Need not be synchronized since it cannot be provably stale.
|
||||
*/
|
||||
public ThreadReference thread() {
|
||||
validateStackFrame();
|
||||
return thread;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof StackFrameImpl)) {
|
||||
StackFrameImpl other = (StackFrameImpl)obj;
|
||||
return (id == other.id) &&
|
||||
(thread().equals(other.thread())) &&
|
||||
(location().equals(other.location())) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return (thread().hashCode() << 4) + ((int)id);
|
||||
}
|
||||
|
||||
public ObjectReference thisObject() {
|
||||
validateStackFrame();
|
||||
MethodImpl currentMethod = (MethodImpl)location.method();
|
||||
if (currentMethod.isStatic() || currentMethod.isNative()) {
|
||||
return null;
|
||||
} else {
|
||||
if (thisObject == null) {
|
||||
PacketStream ps;
|
||||
|
||||
/* protect against defunct frame id */
|
||||
synchronized (vm.state()) {
|
||||
validateStackFrame();
|
||||
ps = JDWP.StackFrame.ThisObject.
|
||||
enqueueCommand(vm, thread, id);
|
||||
}
|
||||
|
||||
/* actually get it, now that order is guaranteed */
|
||||
try {
|
||||
thisObject = JDWP.StackFrame.ThisObject.
|
||||
waitForReply(vm, ps).objectThis;
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.INVALID_FRAMEID:
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD:
|
||||
throw new InvalidStackFrameException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return thisObject;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the visible variable map.
|
||||
* Need not be synchronized since it cannot be provably stale.
|
||||
*/
|
||||
private void createVisibleVariables() throws AbsentInformationException {
|
||||
if (visibleVariables == null) {
|
||||
List<LocalVariable> allVariables = location.method().variables();
|
||||
Map<String, LocalVariable> map = new HashMap<String, LocalVariable>(allVariables.size());
|
||||
|
||||
for (LocalVariable variable : allVariables) {
|
||||
String name = variable.name();
|
||||
if (variable.isVisible(this)) {
|
||||
LocalVariable existing = map.get(name);
|
||||
if ((existing == null) ||
|
||||
((LocalVariableImpl)variable).hides(existing)) {
|
||||
map.put(name, variable);
|
||||
}
|
||||
}
|
||||
}
|
||||
visibleVariables = map;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the list of visible variable in the frame.
|
||||
* Need not be synchronized since it cannot be provably stale.
|
||||
*/
|
||||
public List<LocalVariable> visibleVariables() throws AbsentInformationException {
|
||||
validateStackFrame();
|
||||
createVisibleVariables();
|
||||
List<LocalVariable> mapAsList = new ArrayList<LocalVariable>(visibleVariables.values());
|
||||
Collections.sort(mapAsList);
|
||||
return mapAsList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a particular variable in the frame.
|
||||
* Need not be synchronized since it cannot be provably stale.
|
||||
*/
|
||||
public LocalVariable visibleVariableByName(String name) throws AbsentInformationException {
|
||||
validateStackFrame();
|
||||
createVisibleVariables();
|
||||
return visibleVariables.get(name);
|
||||
}
|
||||
|
||||
public Value getValue(LocalVariable variable) {
|
||||
List<LocalVariable> list = new ArrayList<LocalVariable>(1);
|
||||
list.add(variable);
|
||||
return getValues(list).get(variable);
|
||||
}
|
||||
|
||||
public Map<LocalVariable, Value> getValues(List<? extends LocalVariable> variables) {
|
||||
validateStackFrame();
|
||||
validateMirrors(variables);
|
||||
|
||||
int count = variables.size();
|
||||
JDWP.StackFrame.GetValues.SlotInfo[] slots =
|
||||
new JDWP.StackFrame.GetValues.SlotInfo[count];
|
||||
|
||||
for (int i=0; i<count; ++i) {
|
||||
LocalVariableImpl variable = (LocalVariableImpl)variables.get(i);
|
||||
if (!variable.isVisible(this)) {
|
||||
throw new IllegalArgumentException(variable.name() +
|
||||
" is not valid at this frame location");
|
||||
}
|
||||
slots[i] = new JDWP.StackFrame.GetValues.SlotInfo(variable.slot(),
|
||||
(byte)variable.signature().charAt(0));
|
||||
}
|
||||
|
||||
PacketStream ps;
|
||||
|
||||
/* protect against defunct frame id */
|
||||
synchronized (vm.state()) {
|
||||
validateStackFrame();
|
||||
ps = JDWP.StackFrame.GetValues.enqueueCommand(vm, thread, id, slots);
|
||||
}
|
||||
|
||||
/* actually get it, now that order is guaranteed */
|
||||
ValueImpl[] values;
|
||||
try {
|
||||
values = JDWP.StackFrame.GetValues.waitForReply(vm, ps).values;
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.INVALID_FRAMEID:
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD:
|
||||
throw new InvalidStackFrameException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
if (count != values.length) {
|
||||
throw new InternalException(
|
||||
"Wrong number of values returned from target VM");
|
||||
}
|
||||
Map<LocalVariable, Value> map = new HashMap<LocalVariable, Value>(count);
|
||||
for (int i=0; i<count; ++i) {
|
||||
LocalVariableImpl variable = (LocalVariableImpl)variables.get(i);
|
||||
map.put(variable, values[i]);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
public void setValue(LocalVariable variableIntf, Value valueIntf)
|
||||
throws InvalidTypeException, ClassNotLoadedException {
|
||||
|
||||
validateStackFrame();
|
||||
validateMirror(variableIntf);
|
||||
validateMirrorOrNull(valueIntf);
|
||||
|
||||
LocalVariableImpl variable = (LocalVariableImpl)variableIntf;
|
||||
ValueImpl value = (ValueImpl)valueIntf;
|
||||
|
||||
if (!variable.isVisible(this)) {
|
||||
throw new IllegalArgumentException(variable.name() +
|
||||
" is not valid at this frame location");
|
||||
}
|
||||
|
||||
try {
|
||||
// Validate and convert value if necessary
|
||||
value = ValueImpl.prepareForAssignment(value, variable);
|
||||
|
||||
JDWP.StackFrame.SetValues.SlotInfo[] slotVals =
|
||||
new JDWP.StackFrame.SetValues.SlotInfo[1];
|
||||
slotVals[0] = new JDWP.StackFrame.SetValues.
|
||||
SlotInfo(variable.slot(), value);
|
||||
|
||||
PacketStream ps;
|
||||
|
||||
/* protect against defunct frame id */
|
||||
synchronized (vm.state()) {
|
||||
validateStackFrame();
|
||||
ps = JDWP.StackFrame.SetValues.
|
||||
enqueueCommand(vm, thread, id, slotVals);
|
||||
}
|
||||
|
||||
/* actually set it, now that order is guaranteed */
|
||||
try {
|
||||
JDWP.StackFrame.SetValues.waitForReply(vm, ps);
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.INVALID_FRAMEID:
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD:
|
||||
throw new InvalidStackFrameException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
} catch (ClassNotLoadedException e) {
|
||||
/*
|
||||
* Since we got this exception,
|
||||
* the variable type must be a reference type. The value
|
||||
* we're trying to set is null, but if the variable's
|
||||
* class has not yet been loaded through the enclosing
|
||||
* class loader, then setting to null is essentially a
|
||||
* no-op, and we should allow it without an exception.
|
||||
*/
|
||||
if (value != null) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<Value> getArgumentValues() {
|
||||
validateStackFrame();
|
||||
MethodImpl mmm = (MethodImpl)location.method();
|
||||
List<String> argSigs = mmm.argumentSignatures();
|
||||
int count = argSigs.size();
|
||||
JDWP.StackFrame.GetValues.SlotInfo[] slots =
|
||||
new JDWP.StackFrame.GetValues.SlotInfo[count];
|
||||
|
||||
int slot;
|
||||
if (mmm.isStatic()) {
|
||||
slot = 0;
|
||||
} else {
|
||||
slot = 1;
|
||||
}
|
||||
for (int ii = 0; ii < count; ++ii) {
|
||||
char sigChar = argSigs.get(ii).charAt(0);
|
||||
slots[ii] = new JDWP.StackFrame.GetValues.SlotInfo(slot++,(byte)sigChar);
|
||||
if (sigChar == 'J' || sigChar == 'D') {
|
||||
slot++;
|
||||
}
|
||||
}
|
||||
|
||||
PacketStream ps;
|
||||
|
||||
/* protect against defunct frame id */
|
||||
synchronized (vm.state()) {
|
||||
validateStackFrame();
|
||||
ps = JDWP.StackFrame.GetValues.enqueueCommand(vm, thread, id, slots);
|
||||
}
|
||||
|
||||
ValueImpl[] values;
|
||||
try {
|
||||
values = JDWP.StackFrame.GetValues.waitForReply(vm, ps).values;
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.INVALID_FRAMEID:
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD:
|
||||
throw new InvalidStackFrameException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
if (count != values.length) {
|
||||
throw new InternalException(
|
||||
"Wrong number of values returned from target VM");
|
||||
}
|
||||
return Arrays.asList((Value[])values);
|
||||
}
|
||||
|
||||
void pop() throws IncompatibleThreadStateException {
|
||||
validateStackFrame();
|
||||
// flush caches and disable caching until command completion
|
||||
CommandSender sender =
|
||||
new CommandSender() {
|
||||
public PacketStream send() {
|
||||
return JDWP.StackFrame.PopFrames.enqueueCommand(vm,
|
||||
thread, id);
|
||||
}
|
||||
};
|
||||
try {
|
||||
PacketStream stream = thread.sendResumingCommand(sender);
|
||||
JDWP.StackFrame.PopFrames.waitForReply(vm, stream);
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
throw new IncompatibleThreadStateException(
|
||||
"Thread not current or suspended");
|
||||
case JDWP.Error.INVALID_THREAD: /* zombie */
|
||||
throw new IncompatibleThreadStateException("zombie");
|
||||
case JDWP.Error.NO_MORE_FRAMES:
|
||||
throw new InvalidStackFrameException(
|
||||
"No more frames on the stack");
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
// enable caching - suspended again
|
||||
vm.state().freeze();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return location.toString() + " in thread " + thread.toString();
|
||||
}
|
||||
}
|
||||
67
jdkSrc/jdk8/com/sun/tools/jdi/StratumLineInfo.java
Normal file
67
jdkSrc/jdk8/com/sun/tools/jdi/StratumLineInfo.java
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
class StratumLineInfo implements LineInfo {
|
||||
private final String stratumID;
|
||||
private final int lineNumber;
|
||||
private final String sourceName;
|
||||
private final String sourcePath;
|
||||
|
||||
StratumLineInfo(String stratumID, int lineNumber,
|
||||
String sourceName, String sourcePath) {
|
||||
this.stratumID = stratumID;
|
||||
this.lineNumber = lineNumber;
|
||||
this.sourceName = sourceName;
|
||||
this.sourcePath = sourcePath;
|
||||
}
|
||||
|
||||
public String liStratum() {
|
||||
return stratumID;
|
||||
}
|
||||
|
||||
public int liLineNumber() {
|
||||
return lineNumber;
|
||||
}
|
||||
|
||||
public String liSourceName()
|
||||
throws AbsentInformationException {
|
||||
if (sourceName == null) {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
return sourceName;
|
||||
}
|
||||
|
||||
public String liSourcePath()
|
||||
throws AbsentInformationException {
|
||||
if (sourcePath == null) {
|
||||
throw new AbsentInformationException();
|
||||
}
|
||||
return sourcePath;
|
||||
}
|
||||
}
|
||||
60
jdkSrc/jdk8/com/sun/tools/jdi/StringReferenceImpl.java
Normal file
60
jdkSrc/jdk8/com/sun/tools/jdi/StringReferenceImpl.java
Normal file
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class StringReferenceImpl extends ObjectReferenceImpl
|
||||
implements StringReference
|
||||
{
|
||||
private String value;
|
||||
|
||||
StringReferenceImpl(VirtualMachine aVm,long aRef) {
|
||||
super(aVm,aRef);
|
||||
}
|
||||
|
||||
public String value() {
|
||||
if(value == null) {
|
||||
// Does not need synchronization, since worst-case
|
||||
// static info is fetched twice
|
||||
try {
|
||||
value = JDWP.StringReference.Value.
|
||||
process(vm, this).stringValue;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "\"" + value() + "\"";
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.STRING;
|
||||
}
|
||||
}
|
||||
240
jdkSrc/jdk8/com/sun/tools/jdi/SunCommandLineLauncher.java
Normal file
240
jdkSrc/jdk8/com/sun/tools/jdi/SunCommandLineLauncher.java
Normal file
@@ -0,0 +1,240 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.tools.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.Random;
|
||||
import java.io.IOException;
|
||||
import java.io.File;
|
||||
|
||||
public class SunCommandLineLauncher extends AbstractLauncher implements LaunchingConnector {
|
||||
|
||||
static private final String ARG_HOME = "home";
|
||||
static private final String ARG_OPTIONS = "options";
|
||||
static private final String ARG_MAIN = "main";
|
||||
static private final String ARG_INIT_SUSPEND = "suspend";
|
||||
static private final String ARG_QUOTE = "quote";
|
||||
static private final String ARG_VM_EXEC = "vmexec";
|
||||
|
||||
TransportService transportService;
|
||||
Transport transport;
|
||||
boolean usingSharedMemory = false;
|
||||
|
||||
TransportService transportService() {
|
||||
return transportService;
|
||||
}
|
||||
|
||||
public Transport transport() {
|
||||
return transport;
|
||||
}
|
||||
|
||||
public SunCommandLineLauncher() {
|
||||
super();
|
||||
|
||||
/**
|
||||
* By default this connector uses either the shared memory
|
||||
* transport or the socket transport
|
||||
*/
|
||||
try {
|
||||
Class<?> c = Class.forName("com.sun.tools.jdi.SharedMemoryTransportService");
|
||||
transportService = (TransportService)c.newInstance();
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_shmem";
|
||||
}
|
||||
};
|
||||
usingSharedMemory = true;
|
||||
} catch (ClassNotFoundException x) {
|
||||
} catch (UnsatisfiedLinkError x) {
|
||||
} catch (InstantiationException x) {
|
||||
} catch (IllegalAccessException x) {
|
||||
};
|
||||
if (transportService == null) {
|
||||
transportService = new SocketTransportService();
|
||||
transport = new Transport() {
|
||||
public String name() {
|
||||
return "dt_socket";
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
addStringArgument(
|
||||
ARG_HOME,
|
||||
getString("sun.home.label"),
|
||||
getString("sun.home"),
|
||||
System.getProperty("java.home"),
|
||||
false);
|
||||
addStringArgument(
|
||||
ARG_OPTIONS,
|
||||
getString("sun.options.label"),
|
||||
getString("sun.options"),
|
||||
"",
|
||||
false);
|
||||
addStringArgument(
|
||||
ARG_MAIN,
|
||||
getString("sun.main.label"),
|
||||
getString("sun.main"),
|
||||
"",
|
||||
true);
|
||||
|
||||
addBooleanArgument(
|
||||
ARG_INIT_SUSPEND,
|
||||
getString("sun.init_suspend.label"),
|
||||
getString("sun.init_suspend"),
|
||||
true,
|
||||
false);
|
||||
|
||||
addStringArgument(
|
||||
ARG_QUOTE,
|
||||
getString("sun.quote.label"),
|
||||
getString("sun.quote"),
|
||||
"\"",
|
||||
true);
|
||||
addStringArgument(
|
||||
ARG_VM_EXEC,
|
||||
getString("sun.vm_exec.label"),
|
||||
getString("sun.vm_exec"),
|
||||
"java",
|
||||
true);
|
||||
}
|
||||
|
||||
static boolean hasWhitespace(String string) {
|
||||
int length = string.length();
|
||||
for (int i = 0; i < length; i++) {
|
||||
if (Character.isWhitespace(string.charAt(i))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public VirtualMachine
|
||||
launch(Map<String,? extends Connector.Argument> arguments)
|
||||
throws IOException, IllegalConnectorArgumentsException,
|
||||
VMStartException
|
||||
{
|
||||
VirtualMachine vm;
|
||||
|
||||
String home = argument(ARG_HOME, arguments).value();
|
||||
String options = argument(ARG_OPTIONS, arguments).value();
|
||||
String mainClassAndArgs = argument(ARG_MAIN, arguments).value();
|
||||
boolean wait = ((BooleanArgumentImpl)argument(ARG_INIT_SUSPEND,
|
||||
arguments)).booleanValue();
|
||||
String quote = argument(ARG_QUOTE, arguments).value();
|
||||
String exe = argument(ARG_VM_EXEC, arguments).value();
|
||||
String exePath = null;
|
||||
|
||||
if (quote.length() > 1) {
|
||||
throw new IllegalConnectorArgumentsException("Invalid length",
|
||||
ARG_QUOTE);
|
||||
}
|
||||
|
||||
if ((options.indexOf("-Djava.compiler=") != -1) &&
|
||||
(options.toLowerCase().indexOf("-djava.compiler=none") == -1)) {
|
||||
throw new IllegalConnectorArgumentsException("Cannot debug with a JIT compiler",
|
||||
ARG_OPTIONS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Start listening.
|
||||
* If we're using the shared memory transport then we pick a
|
||||
* random address rather than using the (fixed) default.
|
||||
* Random() uses System.currentTimeMillis() as the seed
|
||||
* which can be a problem on windows (many calls to
|
||||
* currentTimeMillis can return the same value), so
|
||||
* we do a few retries if we get an IOException (we
|
||||
* assume the IOException is the filename is already in use.)
|
||||
*/
|
||||
TransportService.ListenKey listenKey;
|
||||
if (usingSharedMemory) {
|
||||
Random rr = new Random();
|
||||
int failCount = 0;
|
||||
while(true) {
|
||||
try {
|
||||
String address = "javadebug" +
|
||||
String.valueOf(rr.nextInt(100000));
|
||||
listenKey = transportService().startListening(address);
|
||||
break;
|
||||
} catch (IOException ioe) {
|
||||
if (++failCount > 5) {
|
||||
throw ioe;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
listenKey = transportService().startListening();
|
||||
}
|
||||
String address = listenKey.address();
|
||||
|
||||
try {
|
||||
if (home.length() > 0) {
|
||||
exePath = home + File.separator + "bin" + File.separator + exe;
|
||||
} else {
|
||||
exePath = exe;
|
||||
}
|
||||
// Quote only if necessary in case the quote arg value is bogus
|
||||
if (hasWhitespace(exePath)) {
|
||||
exePath = quote + exePath + quote;
|
||||
}
|
||||
|
||||
String xrun = "transport=" + transport().name() +
|
||||
",address=" + address +
|
||||
",suspend=" + (wait? 'y' : 'n');
|
||||
// Quote only if necessary in case the quote arg value is bogus
|
||||
if (hasWhitespace(xrun)) {
|
||||
xrun = quote + xrun + quote;
|
||||
}
|
||||
|
||||
String command = exePath + ' ' +
|
||||
options + ' ' +
|
||||
"-Xdebug " +
|
||||
"-Xrunjdwp:" + xrun + ' ' +
|
||||
mainClassAndArgs;
|
||||
|
||||
// System.err.println("Command: \"" + command + '"');
|
||||
vm = launch(tokenizeCommand(command, quote.charAt(0)), address, listenKey,
|
||||
transportService());
|
||||
} finally {
|
||||
transportService().stopListening(listenKey);
|
||||
}
|
||||
|
||||
return vm;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "com.sun.jdi.CommandLineLaunch";
|
||||
}
|
||||
|
||||
public String description() {
|
||||
return getString("sun.description");
|
||||
|
||||
}
|
||||
}
|
||||
48
jdkSrc/jdk8/com/sun/tools/jdi/SunSDK.java
Normal file
48
jdkSrc/jdk8/com/sun/tools/jdi/SunSDK.java
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* This class encapsulates platform-specific details of the
|
||||
* structure of an SDK which has a JRE embedded in it.
|
||||
*/
|
||||
class SunSDK {
|
||||
/**
|
||||
* Returns the home directory of a Java 2 SDK if the current
|
||||
* JRE is embedded in one.
|
||||
*/
|
||||
static String home() {
|
||||
File jreHome = new File(System.getProperty("java.home"));
|
||||
File jreParent = new File(jreHome.getParent());
|
||||
|
||||
String jdwpLibName = "bin" + File.separator +
|
||||
System.mapLibraryName("jdwp");
|
||||
File jdwpLib = new File(jreParent, jdwpLibName);
|
||||
return jdwpLib.exists() ? jreParent.getAbsolutePath() : null;
|
||||
}
|
||||
}
|
||||
379
jdkSrc/jdk8/com/sun/tools/jdi/TargetVM.java
Normal file
379
jdkSrc/jdk8/com/sun/tools/jdi/TargetVM.java
Normal file
@@ -0,0 +1,379 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.event.*;
|
||||
import com.sun.jdi.connect.spi.Connection;
|
||||
import com.sun.jdi.event.EventSet;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.IOException;
|
||||
|
||||
public class TargetVM implements Runnable {
|
||||
private Map<String, Packet> waitingQueue = new HashMap<String, Packet>(32,0.75f);
|
||||
private volatile boolean shouldListen = true;
|
||||
private List<EventQueue> eventQueues = Collections.synchronizedList(new ArrayList<EventQueue>(2));
|
||||
private VirtualMachineImpl vm;
|
||||
private Connection connection;
|
||||
private Thread readerThread;
|
||||
private EventController eventController = null;
|
||||
private boolean eventsHeld = false;
|
||||
|
||||
/*
|
||||
* TO DO: The limit numbers below are somewhat arbitrary and should
|
||||
* be configurable in the future.
|
||||
*/
|
||||
static private final int OVERLOADED_QUEUE = 2000;
|
||||
static private final int UNDERLOADED_QUEUE = 100;
|
||||
|
||||
TargetVM(VirtualMachineImpl vm, Connection connection) {
|
||||
this.vm = vm;
|
||||
this.connection = connection;
|
||||
this.readerThread = new Thread(vm.threadGroupForJDI(),
|
||||
this, "JDI Target VM Interface");
|
||||
this.readerThread.setDaemon(true);
|
||||
}
|
||||
|
||||
void start() {
|
||||
readerThread.start();
|
||||
}
|
||||
|
||||
private void dumpPacket(Packet packet, boolean sending) {
|
||||
String direction = sending ? "Sending" : "Receiving";
|
||||
if (sending) {
|
||||
vm.printTrace(direction + " Command. id=" + packet.id +
|
||||
", length=" + packet.data.length +
|
||||
", commandSet=" + packet.cmdSet +
|
||||
", command=" + packet.cmd +
|
||||
", flags=" + packet.flags);
|
||||
} else {
|
||||
String type = (packet.flags & Packet.Reply) != 0 ?
|
||||
"Reply" : "Event";
|
||||
vm.printTrace(direction + " " + type + ". id=" + packet.id +
|
||||
", length=" + packet.data.length +
|
||||
", errorCode=" + packet.errorCode +
|
||||
", flags=" + packet.flags);
|
||||
}
|
||||
StringBuffer line = new StringBuffer(80);
|
||||
line.append("0000: ");
|
||||
for (int i = 0; i < packet.data.length; i++) {
|
||||
if ((i > 0) && (i % 16 == 0)) {
|
||||
vm.printTrace(line.toString());
|
||||
line.setLength(0);
|
||||
line.append(String.valueOf(i));
|
||||
line.append(": ");
|
||||
int len = line.length();
|
||||
for (int j = 0; j < 6 - len; j++) {
|
||||
line.insert(0, '0');
|
||||
}
|
||||
}
|
||||
int val = 0xff & packet.data[i];
|
||||
String str = Integer.toHexString(val);
|
||||
if (str.length() == 1) {
|
||||
line.append('0');
|
||||
}
|
||||
line.append(str);
|
||||
line.append(' ');
|
||||
}
|
||||
if (line.length() > 6) {
|
||||
vm.printTrace(line.toString());
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_SENDS) != 0) {
|
||||
vm.printTrace("Target VM interface thread running");
|
||||
}
|
||||
Packet p=null,p2;
|
||||
String idString;
|
||||
|
||||
while(shouldListen) {
|
||||
|
||||
boolean done = false;
|
||||
try {
|
||||
byte b[] = connection.readPacket();
|
||||
if (b.length == 0) {
|
||||
done = true;
|
||||
}
|
||||
p = Packet.fromByteArray(b);
|
||||
} catch (IOException e) {
|
||||
done = true;
|
||||
}
|
||||
|
||||
if (done) {
|
||||
shouldListen = false;
|
||||
try {
|
||||
connection.close();
|
||||
} catch (IOException ioe) { }
|
||||
break;
|
||||
}
|
||||
|
||||
if ((vm.traceFlags & VirtualMachineImpl.TRACE_RAW_RECEIVES) != 0) {
|
||||
dumpPacket(p, false);
|
||||
}
|
||||
|
||||
if((p.flags & Packet.Reply) == 0) {
|
||||
// It's a command
|
||||
handleVMCommand(p);
|
||||
} else {
|
||||
/*if(p.errorCode != Packet.ReplyNoError) {
|
||||
System.err.println("Packet " + p.id + " returned failure = " + p.errorCode);
|
||||
}*/
|
||||
|
||||
vm.state().notifyCommandComplete(p.id);
|
||||
idString = String.valueOf(p.id);
|
||||
|
||||
synchronized(waitingQueue) {
|
||||
p2 = waitingQueue.get(idString);
|
||||
|
||||
if (p2 != null)
|
||||
waitingQueue.remove(idString);
|
||||
}
|
||||
|
||||
if(p2 == null) {
|
||||
// Whoa! a reply without a sender. Problem.
|
||||
// FIX ME! Need to post an error.
|
||||
|
||||
System.err.println("Recieved reply with no sender!");
|
||||
continue;
|
||||
}
|
||||
p2.errorCode = p.errorCode;
|
||||
p2.data = p.data;
|
||||
p2.replied = true;
|
||||
|
||||
synchronized(p2) {
|
||||
p2.notify();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// inform the VM mamager that this VM is history
|
||||
vm.vmManager.disposeVirtualMachine(vm);
|
||||
if (eventController != null) {
|
||||
eventController.release();
|
||||
}
|
||||
|
||||
// close down all the event queues
|
||||
// Closing a queue causes a VMDisconnectEvent to
|
||||
// be put onto the queue.
|
||||
synchronized(eventQueues) {
|
||||
Iterator<EventQueue> iter = eventQueues.iterator();
|
||||
while (iter.hasNext()) {
|
||||
((EventQueueImpl)iter.next()).close();
|
||||
}
|
||||
}
|
||||
|
||||
// indirectly throw VMDisconnectedException to
|
||||
// command requesters.
|
||||
synchronized(waitingQueue) {
|
||||
Iterator<Packet> iter = waitingQueue.values().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Packet packet = iter.next();
|
||||
synchronized(packet) {
|
||||
packet.notify();
|
||||
}
|
||||
}
|
||||
waitingQueue.clear();
|
||||
}
|
||||
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_SENDS) != 0) {
|
||||
vm.printTrace("Target VM interface thread exiting");
|
||||
}
|
||||
}
|
||||
|
||||
protected void handleVMCommand(Packet p) {
|
||||
switch (p.cmdSet) {
|
||||
case JDWP.Event.COMMAND_SET:
|
||||
handleEventCmdSet(p);
|
||||
break;
|
||||
|
||||
default:
|
||||
System.err.println("Ignoring cmd " + p.id + "/" +
|
||||
p.cmdSet + "/" + p.cmd + " from the VM");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Events should not be constructed on this thread (the thread
|
||||
* which reads all data from the transport). This means that the
|
||||
* packet cannot be converted to real JDI objects as that may
|
||||
* involve further communications with the back end which would
|
||||
* deadlock.
|
||||
*
|
||||
* Instead the whole packet is passed for lazy eval by a queue
|
||||
* reading thread.
|
||||
*/
|
||||
protected void handleEventCmdSet(Packet p) {
|
||||
EventSet eventSet = new EventSetImpl(vm, p);
|
||||
|
||||
if (eventSet != null) {
|
||||
queueEventSet(eventSet);
|
||||
}
|
||||
}
|
||||
|
||||
private EventController eventController() {
|
||||
if (eventController == null) {
|
||||
eventController = new EventController();
|
||||
}
|
||||
return eventController;
|
||||
}
|
||||
|
||||
private synchronized void controlEventFlow(int maxQueueSize) {
|
||||
if (!eventsHeld && (maxQueueSize > OVERLOADED_QUEUE)) {
|
||||
eventController().hold();
|
||||
eventsHeld = true;
|
||||
} else if (eventsHeld && (maxQueueSize < UNDERLOADED_QUEUE)) {
|
||||
eventController().release();
|
||||
eventsHeld = false;
|
||||
}
|
||||
}
|
||||
|
||||
void notifyDequeueEventSet() {
|
||||
int maxQueueSize = 0;
|
||||
synchronized(eventQueues) {
|
||||
Iterator<EventQueue> iter = eventQueues.iterator();
|
||||
while (iter.hasNext()) {
|
||||
EventQueueImpl queue = (EventQueueImpl)iter.next();
|
||||
maxQueueSize = Math.max(maxQueueSize, queue.size());
|
||||
}
|
||||
}
|
||||
controlEventFlow(maxQueueSize);
|
||||
}
|
||||
|
||||
private void queueEventSet(EventSet eventSet) {
|
||||
int maxQueueSize = 0;
|
||||
|
||||
synchronized(eventQueues) {
|
||||
Iterator<EventQueue> iter = eventQueues.iterator();
|
||||
while (iter.hasNext()) {
|
||||
EventQueueImpl queue = (EventQueueImpl)iter.next();
|
||||
queue.enqueue(eventSet);
|
||||
maxQueueSize = Math.max(maxQueueSize, queue.size());
|
||||
}
|
||||
}
|
||||
|
||||
controlEventFlow(maxQueueSize);
|
||||
}
|
||||
|
||||
void send(Packet packet) {
|
||||
String id = String.valueOf(packet.id);
|
||||
|
||||
synchronized(waitingQueue) {
|
||||
waitingQueue.put(id, packet);
|
||||
}
|
||||
|
||||
if ((vm.traceFlags & VirtualMachineImpl.TRACE_RAW_SENDS) != 0) {
|
||||
dumpPacket(packet, true);
|
||||
}
|
||||
|
||||
try {
|
||||
connection.writePacket(packet.toByteArray());
|
||||
} catch (IOException e) {
|
||||
throw new VMDisconnectedException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
void waitForReply(Packet packet) {
|
||||
synchronized(packet) {
|
||||
while ((!packet.replied) && shouldListen) {
|
||||
try { packet.wait(); } catch (InterruptedException e) {;}
|
||||
}
|
||||
|
||||
if (!packet.replied) {
|
||||
throw new VMDisconnectedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void addEventQueue(EventQueueImpl queue) {
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
vm.printTrace("New event queue added");
|
||||
}
|
||||
eventQueues.add(queue);
|
||||
}
|
||||
|
||||
void stopListening() {
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_EVENTS) != 0) {
|
||||
vm.printTrace("Target VM i/f closing event queues");
|
||||
}
|
||||
shouldListen = false;
|
||||
try {
|
||||
connection.close();
|
||||
} catch (IOException ioe) { }
|
||||
}
|
||||
|
||||
private class EventController extends Thread {
|
||||
int controlRequest = 0;
|
||||
|
||||
EventController() {
|
||||
super(vm.threadGroupForJDI(), "JDI Event Control Thread");
|
||||
setDaemon(true);
|
||||
setPriority((MAX_PRIORITY + NORM_PRIORITY)/2);
|
||||
super.start();
|
||||
}
|
||||
|
||||
synchronized void hold() {
|
||||
controlRequest++;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
synchronized void release() {
|
||||
controlRequest--;
|
||||
notifyAll();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while(true) {
|
||||
int currentRequest;
|
||||
synchronized(this) {
|
||||
while (controlRequest == 0) {
|
||||
try {wait();} catch (InterruptedException e) {}
|
||||
if (!shouldListen) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
currentRequest = controlRequest;
|
||||
controlRequest = 0;
|
||||
}
|
||||
try {
|
||||
if (currentRequest > 0) {
|
||||
JDWP.VirtualMachine.HoldEvents.process(vm);
|
||||
} else {
|
||||
JDWP.VirtualMachine.ReleaseEvents.process(vm);
|
||||
}
|
||||
} catch (JDWPException e) {
|
||||
/*
|
||||
* Don't want to terminate the thread, so the
|
||||
* stack trace is printed and we continue.
|
||||
*/
|
||||
e.toJDIException().printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
53
jdkSrc/jdk8/com/sun/tools/jdi/ThreadAction.java
Normal file
53
jdkSrc/jdk8/com/sun/tools/jdi/ThreadAction.java
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.EventObject;
|
||||
|
||||
/*
|
||||
* The name "action" is used to avoid confusion
|
||||
* with JDI events.
|
||||
*/
|
||||
class ThreadAction extends EventObject {
|
||||
private static final long serialVersionUID = 5690763191100515283L;
|
||||
// Event ids
|
||||
/*static final int THREAD_SUSPENDED = 1;*/
|
||||
static final int THREAD_RESUMABLE = 2;
|
||||
|
||||
int id;
|
||||
|
||||
ThreadAction(ThreadReference thread, int id) {
|
||||
super(thread);
|
||||
this.id = id;
|
||||
}
|
||||
ThreadReference thread() {
|
||||
return (ThreadReference)getSource();
|
||||
}
|
||||
int id() {
|
||||
return id;
|
||||
}
|
||||
}
|
||||
149
jdkSrc/jdk8/com/sun/tools/jdi/ThreadGroupReferenceImpl.java
Normal file
149
jdkSrc/jdk8/com/sun/tools/jdi/ThreadGroupReferenceImpl.java
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.*;
|
||||
|
||||
public class ThreadGroupReferenceImpl extends ObjectReferenceImpl
|
||||
implements ThreadGroupReference, VMListener
|
||||
{
|
||||
// Cached components that cannot change
|
||||
String name;
|
||||
ThreadGroupReference parent;
|
||||
boolean triedParent;
|
||||
|
||||
// This is cached only while the VM is suspended
|
||||
private static class Cache extends ObjectReferenceImpl.Cache {
|
||||
JDWP.ThreadGroupReference.Children kids = null;
|
||||
}
|
||||
|
||||
protected ObjectReferenceImpl.Cache newCache() {
|
||||
return new Cache();
|
||||
}
|
||||
|
||||
ThreadGroupReferenceImpl(VirtualMachine aVm,long aRef) {
|
||||
super(aVm,aRef);
|
||||
vm.state().addListener(this);
|
||||
}
|
||||
|
||||
protected String description() {
|
||||
return "ThreadGroupReference " + uniqueID();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
if (name == null) {
|
||||
// Does not need synchronization, since worst-case
|
||||
// static info is fetched twice (Thread group name
|
||||
// cannot change)
|
||||
try {
|
||||
name = JDWP.ThreadGroupReference.Name.
|
||||
process(vm, this).groupName;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
public ThreadGroupReference parent() {
|
||||
if (!triedParent) {
|
||||
// Does not need synchronization, since worst-case
|
||||
// static info is fetched twice (Thread group parent cannot
|
||||
// change)
|
||||
try {
|
||||
parent = JDWP.ThreadGroupReference.Parent.
|
||||
process(vm, this).parentGroup;
|
||||
triedParent = true;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
for (ThreadReference thread : threads()) {
|
||||
thread.suspend();
|
||||
}
|
||||
|
||||
for (ThreadGroupReference threadGroup : threadGroups()) {
|
||||
threadGroup.suspend();
|
||||
}
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
for (ThreadReference thread : threads()) {
|
||||
thread.resume();
|
||||
}
|
||||
|
||||
for (ThreadGroupReference threadGroup : threadGroups()) {
|
||||
threadGroup.resume();
|
||||
}
|
||||
}
|
||||
|
||||
private JDWP.ThreadGroupReference.Children kids() {
|
||||
JDWP.ThreadGroupReference.Children kids = null;
|
||||
try {
|
||||
Cache local = (Cache)getCache();
|
||||
|
||||
if (local != null) {
|
||||
kids = local.kids;
|
||||
}
|
||||
if (kids == null) {
|
||||
kids = JDWP.ThreadGroupReference.Children
|
||||
.process(vm, this);
|
||||
if (local != null) {
|
||||
local.kids = kids;
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace(description() +
|
||||
" temporarily caching children ");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return kids;
|
||||
}
|
||||
|
||||
public List<ThreadReference> threads() {
|
||||
return Arrays.asList((ThreadReference[])kids().childThreads);
|
||||
}
|
||||
|
||||
public List<ThreadGroupReference> threadGroups() {
|
||||
return Arrays.asList((ThreadGroupReference[])kids().childGroups);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "instance of " + referenceType().name() +
|
||||
"(name='" + name() + "', " + "id=" + uniqueID() + ")";
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.THREAD_GROUP;
|
||||
}
|
||||
}
|
||||
38
jdkSrc/jdk8/com/sun/tools/jdi/ThreadListener.java
Normal file
38
jdkSrc/jdk8/com/sun/tools/jdi/ThreadListener.java
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2013, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.EventListener;
|
||||
|
||||
interface ThreadListener extends EventListener {
|
||||
boolean threadResumable(ThreadAction action);
|
||||
/*
|
||||
* Not needed for current implementation, and hard to implement
|
||||
* correctly. (See TargetVM.handleEventCmdSet)
|
||||
* void threadSuspended(ThreadAction action);
|
||||
*/
|
||||
}
|
||||
644
jdkSrc/jdk8/com/sun/tools/jdi/ThreadReferenceImpl.java
Normal file
644
jdkSrc/jdk8/com/sun/tools/jdi/ThreadReferenceImpl.java
Normal file
@@ -0,0 +1,644 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2017, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.request.BreakpointRequest;
|
||||
import java.util.*;
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
public class ThreadReferenceImpl extends ObjectReferenceImpl
|
||||
implements ThreadReference, VMListener {
|
||||
static final int SUSPEND_STATUS_SUSPENDED = 0x1;
|
||||
static final int SUSPEND_STATUS_BREAK = 0x2;
|
||||
|
||||
private int suspendedZombieCount = 0;
|
||||
|
||||
/*
|
||||
* Some objects can only be created while a thread is suspended and are valid
|
||||
* only while the thread remains suspended. Examples are StackFrameImpl
|
||||
* and MonitorInfoImpl. When the thread resumes, these objects have to be
|
||||
* marked as invalid so that their methods can throw
|
||||
* InvalidStackFrameException if they are called. To do this, such objects
|
||||
* register themselves as listeners of the associated thread. When the
|
||||
* thread is resumed, its listeners are notified and mark themselves
|
||||
* invalid.
|
||||
* Also, note that ThreadReferenceImpl itself caches some info that
|
||||
* is valid only as long as the thread is suspended. When the thread
|
||||
* is resumed, that cache must be purged.
|
||||
* Lastly, note that ThreadReferenceImpl and its super, ObjectReferenceImpl
|
||||
* cache some info that is only valid as long as the entire VM is suspended.
|
||||
* If _any_ thread is resumed, this cache must be purged. To handle this,
|
||||
* both ThreadReferenceImpl and ObjectReferenceImpl register themselves as
|
||||
* VMListeners so that they get notified when all threads are suspended and
|
||||
* when any thread is resumed.
|
||||
*/
|
||||
|
||||
// This is cached for the life of the thread
|
||||
private ThreadGroupReference threadGroup;
|
||||
|
||||
// This is cached only while this one thread is suspended. Each time
|
||||
// the thread is resumed, we abandon the current cache object and
|
||||
// create a new initialized one.
|
||||
private static class LocalCache {
|
||||
JDWP.ThreadReference.Status status = null;
|
||||
List<StackFrame> frames = null;
|
||||
int framesStart = -1;
|
||||
int framesLength = 0;
|
||||
int frameCount = -1;
|
||||
List<ObjectReference> ownedMonitors = null;
|
||||
List<MonitorInfo> ownedMonitorsInfo = null;
|
||||
ObjectReference contendedMonitor = null;
|
||||
boolean triedCurrentContended = false;
|
||||
}
|
||||
|
||||
/*
|
||||
* The localCache instance var is set by resetLocalCache to an initialized
|
||||
* object as shown above. This occurs when the ThreadReference
|
||||
* object is created, and when the mirrored thread is resumed.
|
||||
* The fields are then filled in by the relevant methods as they
|
||||
* are called. A problem can occur if resetLocalCache is called
|
||||
* (ie, a resume() is executed) at certain points in the execution
|
||||
* of some of these methods - see 6751643. To avoid this, each
|
||||
* method that wants to use this cache must make a local copy of
|
||||
* this variable and use that. This means that each invocation of
|
||||
* these methods will use a copy of the cache object that was in
|
||||
* effect at the point that the copy was made; if a racy resume
|
||||
* occurs, it won't affect the method's local copy. This means that
|
||||
* the values returned by these calls may not match the state of
|
||||
* the debuggee at the time the caller gets the values. EG,
|
||||
* frameCount() is called and comes up with 5 frames. But before
|
||||
* it returns this, a resume of the debuggee thread is executed in a
|
||||
* different debugger thread. The thread is resumed and running at
|
||||
* the time that the value 5 is returned. Or even worse, the thread
|
||||
* could be suspended again and have a different number of frames, eg, 24,
|
||||
* but this call will still return 5.
|
||||
*/
|
||||
private LocalCache localCache;
|
||||
|
||||
private void resetLocalCache() {
|
||||
localCache = new LocalCache();
|
||||
}
|
||||
|
||||
// This is cached only while all threads in the VM are suspended
|
||||
// Yes, someone could change the name of a thread while it is suspended.
|
||||
private static class Cache extends ObjectReferenceImpl.Cache {
|
||||
String name = null;
|
||||
}
|
||||
protected ObjectReferenceImpl.Cache newCache() {
|
||||
return new Cache();
|
||||
}
|
||||
|
||||
// Listeners - synchronized on vm.state()
|
||||
private List<WeakReference<ThreadListener>> listeners = new ArrayList<WeakReference<ThreadListener>>();
|
||||
|
||||
|
||||
ThreadReferenceImpl(VirtualMachine aVm, long aRef) {
|
||||
super(aVm,aRef);
|
||||
resetLocalCache();
|
||||
vm.state().addListener(this);
|
||||
}
|
||||
|
||||
protected String description() {
|
||||
return "ThreadReference " + uniqueID();
|
||||
}
|
||||
|
||||
/*
|
||||
* VMListener implementation
|
||||
*/
|
||||
public boolean vmNotSuspended(VMAction action) {
|
||||
if (action.resumingThread() == null) {
|
||||
// all threads are being resumed
|
||||
synchronized (vm.state()) {
|
||||
processThreadAction(new ThreadAction(this,
|
||||
ThreadAction.THREAD_RESUMABLE));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Othewise, only one thread is being resumed:
|
||||
* if it is us,
|
||||
* we have already done our processThreadAction to notify our
|
||||
* listeners when we processed the resume.
|
||||
* if it is not us,
|
||||
* we don't want to notify our listeners
|
||||
* because we are not being resumed.
|
||||
*/
|
||||
return super.vmNotSuspended(action);
|
||||
}
|
||||
|
||||
/**
|
||||
* Note that we only cache the name string while the entire VM is suspended
|
||||
* because the name can change via Thread.setName arbitrarily while this
|
||||
* thread is running.
|
||||
*/
|
||||
public String name() {
|
||||
String name = null;
|
||||
try {
|
||||
Cache local = (Cache)getCache();
|
||||
|
||||
if (local != null) {
|
||||
name = local.name;
|
||||
}
|
||||
if (name == null) {
|
||||
name = JDWP.ThreadReference.Name.process(vm, this)
|
||||
.threadName;
|
||||
if (local != null) {
|
||||
local.name = name;
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sends a command to the back end which is defined to do an
|
||||
* implicit vm-wide resume.
|
||||
*/
|
||||
PacketStream sendResumingCommand(CommandSender sender) {
|
||||
synchronized (vm.state()) {
|
||||
processThreadAction(new ThreadAction(this,
|
||||
ThreadAction.THREAD_RESUMABLE));
|
||||
return sender.send();
|
||||
}
|
||||
}
|
||||
|
||||
public void suspend() {
|
||||
try {
|
||||
JDWP.ThreadReference.Suspend.process(vm, this);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
// Don't consider the thread suspended yet. On reply, notifySuspend()
|
||||
// will be called.
|
||||
}
|
||||
|
||||
public void resume() {
|
||||
/*
|
||||
* If it's a zombie, we can just update internal state without
|
||||
* going to back end.
|
||||
*/
|
||||
if (suspendedZombieCount > 0) {
|
||||
suspendedZombieCount--;
|
||||
return;
|
||||
}
|
||||
|
||||
PacketStream stream;
|
||||
synchronized (vm.state()) {
|
||||
processThreadAction(new ThreadAction(this,
|
||||
ThreadAction.THREAD_RESUMABLE));
|
||||
stream = JDWP.ThreadReference.Resume.enqueueCommand(vm, this);
|
||||
}
|
||||
try {
|
||||
JDWP.ThreadReference.Resume.waitForReply(vm, stream);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
public int suspendCount() {
|
||||
/*
|
||||
* If it's a zombie, we maintain the count in the front end.
|
||||
*/
|
||||
if (suspendedZombieCount > 0) {
|
||||
return suspendedZombieCount;
|
||||
}
|
||||
|
||||
try {
|
||||
return JDWP.ThreadReference.SuspendCount.process(vm, this).suspendCount;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(ObjectReference throwable) throws InvalidTypeException {
|
||||
validateMirrorOrNull(throwable);
|
||||
// Verify that the given object is a Throwable instance
|
||||
List<ReferenceType> list = vm.classesByName("java.lang.Throwable");
|
||||
ClassTypeImpl throwableClass = (ClassTypeImpl)list.get(0);
|
||||
if ((throwable == null) ||
|
||||
!throwableClass.isAssignableFrom(throwable)) {
|
||||
throw new InvalidTypeException("Not an instance of Throwable");
|
||||
}
|
||||
|
||||
try {
|
||||
JDWP.ThreadReference.Stop.process(vm, this,
|
||||
(ObjectReferenceImpl)throwable);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
public void interrupt() {
|
||||
try {
|
||||
JDWP.ThreadReference.Interrupt.process(vm, this);
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
|
||||
private JDWP.ThreadReference.Status jdwpStatus() {
|
||||
LocalCache snapshot = localCache;
|
||||
JDWP.ThreadReference.Status myStatus = snapshot.status;
|
||||
try {
|
||||
if (myStatus == null) {
|
||||
myStatus = JDWP.ThreadReference.Status.process(vm, this);
|
||||
if ((myStatus.suspendStatus & SUSPEND_STATUS_SUSPENDED) != 0) {
|
||||
// thread is suspended, we can cache the status.
|
||||
snapshot.status = myStatus;
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return myStatus;
|
||||
}
|
||||
|
||||
public int status() {
|
||||
return jdwpStatus().threadStatus;
|
||||
}
|
||||
|
||||
public boolean isSuspended() {
|
||||
return ((suspendedZombieCount > 0) ||
|
||||
((jdwpStatus().suspendStatus & SUSPEND_STATUS_SUSPENDED) != 0));
|
||||
}
|
||||
|
||||
public boolean isAtBreakpoint() {
|
||||
/*
|
||||
* TO DO: This fails to take filters into account.
|
||||
*/
|
||||
try {
|
||||
StackFrame frame = frame(0);
|
||||
Location location = frame.location();
|
||||
List<BreakpointRequest> requests = vm.eventRequestManager().breakpointRequests();
|
||||
Iterator<BreakpointRequest> iter = requests.iterator();
|
||||
while (iter.hasNext()) {
|
||||
BreakpointRequest request = iter.next();
|
||||
if (location.equals(request.location())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} catch (IndexOutOfBoundsException iobe) {
|
||||
return false; // no frames on stack => not at breakpoint
|
||||
} catch (IncompatibleThreadStateException itse) {
|
||||
// Per the javadoc, not suspended => return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public ThreadGroupReference threadGroup() {
|
||||
/*
|
||||
* Thread group can't change, so it's cached once and for all.
|
||||
*/
|
||||
if (threadGroup == null) {
|
||||
try {
|
||||
threadGroup = JDWP.ThreadReference.ThreadGroup.
|
||||
process(vm, this).group;
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return threadGroup;
|
||||
}
|
||||
|
||||
public int frameCount() throws IncompatibleThreadStateException {
|
||||
LocalCache snapshot = localCache;
|
||||
try {
|
||||
if (snapshot.frameCount == -1) {
|
||||
snapshot.frameCount = JDWP.ThreadReference.FrameCount
|
||||
.process(vm, this).frameCount;
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD: /* zombie */
|
||||
throw new IncompatibleThreadStateException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return snapshot.frameCount;
|
||||
}
|
||||
|
||||
public List<StackFrame> frames() throws IncompatibleThreadStateException {
|
||||
return privateFrames(0, -1);
|
||||
}
|
||||
|
||||
public StackFrame frame(int index) throws IncompatibleThreadStateException {
|
||||
List<StackFrame> list = privateFrames(index, 1);
|
||||
return list.get(0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the requested subrange within what has been retrieved?
|
||||
* local is known to be non-null. Should only be called from
|
||||
* a sync method.
|
||||
*/
|
||||
private boolean isSubrange(LocalCache snapshot,
|
||||
int start, int length) {
|
||||
if (start < snapshot.framesStart) {
|
||||
return false;
|
||||
}
|
||||
if (length == -1) {
|
||||
return (snapshot.framesLength == -1);
|
||||
}
|
||||
if (snapshot.framesLength == -1) {
|
||||
if ((start + length) > (snapshot.framesStart +
|
||||
snapshot.frames.size())) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return ((start + length) <= (snapshot.framesStart + snapshot.framesLength));
|
||||
}
|
||||
|
||||
public List<StackFrame> frames(int start, int length)
|
||||
throws IncompatibleThreadStateException {
|
||||
if (length < 0) {
|
||||
throw new IndexOutOfBoundsException(
|
||||
"length must be greater than or equal to zero");
|
||||
}
|
||||
return privateFrames(start, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Private version of frames() allows "-1" to specify all
|
||||
* remaining frames.
|
||||
*/
|
||||
synchronized private List<StackFrame> privateFrames(int start, int length)
|
||||
throws IncompatibleThreadStateException {
|
||||
|
||||
// Lock must be held while creating stack frames so if that two threads
|
||||
// do this at the same time, one won't clobber the subset created by the other.
|
||||
LocalCache snapshot = localCache;
|
||||
try {
|
||||
if (snapshot.frames == null || !isSubrange(snapshot, start, length)) {
|
||||
JDWP.ThreadReference.Frames.Frame[] jdwpFrames
|
||||
= JDWP.ThreadReference.Frames.
|
||||
process(vm, this, start, length).frames;
|
||||
int count = jdwpFrames.length;
|
||||
snapshot.frames = new ArrayList<StackFrame>(count);
|
||||
|
||||
for (int i = 0; i<count; i++) {
|
||||
if (jdwpFrames[i].location == null) {
|
||||
throw new InternalException("Invalid frame location");
|
||||
}
|
||||
StackFrame frame = new StackFrameImpl(vm, this,
|
||||
jdwpFrames[i].frameID,
|
||||
jdwpFrames[i].location);
|
||||
// Add to the frame list
|
||||
snapshot.frames.add(frame);
|
||||
}
|
||||
snapshot.framesStart = start;
|
||||
snapshot.framesLength = length;
|
||||
return Collections.unmodifiableList(snapshot.frames);
|
||||
} else {
|
||||
int fromIndex = start - snapshot.framesStart;
|
||||
int toIndex;
|
||||
if (length == -1) {
|
||||
toIndex = snapshot.frames.size() - fromIndex;
|
||||
} else {
|
||||
toIndex = fromIndex + length;
|
||||
}
|
||||
return Collections.unmodifiableList(snapshot.frames.subList(fromIndex, toIndex));
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD: /* zombie */
|
||||
throw new IncompatibleThreadStateException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<ObjectReference> ownedMonitors() throws IncompatibleThreadStateException {
|
||||
LocalCache snapshot = localCache;
|
||||
try {
|
||||
if (snapshot.ownedMonitors == null) {
|
||||
snapshot.ownedMonitors = Arrays.asList(
|
||||
(ObjectReference[])JDWP.ThreadReference.OwnedMonitors.
|
||||
process(vm, this).owned);
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace(description() +
|
||||
" temporarily caching owned monitors"+
|
||||
" (count = " + snapshot.ownedMonitors.size() + ")");
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD: /* zombie */
|
||||
throw new IncompatibleThreadStateException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return snapshot.ownedMonitors;
|
||||
}
|
||||
|
||||
public ObjectReference currentContendedMonitor()
|
||||
throws IncompatibleThreadStateException {
|
||||
LocalCache snapshot = localCache;
|
||||
try {
|
||||
if (snapshot.contendedMonitor == null &&
|
||||
!snapshot.triedCurrentContended) {
|
||||
snapshot.contendedMonitor = JDWP.ThreadReference.CurrentContendedMonitor.
|
||||
process(vm, this).monitor;
|
||||
snapshot.triedCurrentContended = true;
|
||||
if ((snapshot.contendedMonitor != null) &&
|
||||
((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0)) {
|
||||
vm.printTrace(description() +
|
||||
" temporarily caching contended monitor"+
|
||||
" (id = " + snapshot.contendedMonitor.uniqueID() + ")");
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD: /* zombie */
|
||||
throw new IncompatibleThreadStateException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return snapshot.contendedMonitor;
|
||||
}
|
||||
|
||||
public List<MonitorInfo> ownedMonitorsAndFrames() throws IncompatibleThreadStateException {
|
||||
LocalCache snapshot = localCache;
|
||||
try {
|
||||
if (snapshot.ownedMonitorsInfo == null) {
|
||||
JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor[] minfo;
|
||||
minfo = JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.process(vm, this).owned;
|
||||
|
||||
snapshot.ownedMonitorsInfo = new ArrayList<MonitorInfo>(minfo.length);
|
||||
|
||||
for (int i=0; i < minfo.length; i++) {
|
||||
JDWP.ThreadReference.OwnedMonitorsStackDepthInfo.monitor mi =
|
||||
minfo[i];
|
||||
MonitorInfo mon = new MonitorInfoImpl(vm, minfo[i].monitor, this, minfo[i].stack_depth);
|
||||
snapshot.ownedMonitorsInfo.add(mon);
|
||||
}
|
||||
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace(description() +
|
||||
" temporarily caching owned monitors"+
|
||||
" (count = " + snapshot.ownedMonitorsInfo.size() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
case JDWP.Error.INVALID_THREAD: /* zombie */
|
||||
throw new IncompatibleThreadStateException();
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
return snapshot.ownedMonitorsInfo;
|
||||
}
|
||||
|
||||
public void popFrames(StackFrame frame) throws IncompatibleThreadStateException {
|
||||
// Note that interface-wise this functionality belongs
|
||||
// here in ThreadReference, but implementation-wise it
|
||||
// belongs in StackFrame, so we just forward it.
|
||||
if (!frame.thread().equals(this)) {
|
||||
throw new IllegalArgumentException("frame does not belong to this thread");
|
||||
}
|
||||
if (!vm.canPopFrames()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target does not support popping frames");
|
||||
}
|
||||
((StackFrameImpl)frame).pop();
|
||||
}
|
||||
|
||||
public void forceEarlyReturn(Value returnValue) throws InvalidTypeException,
|
||||
ClassNotLoadedException,
|
||||
IncompatibleThreadStateException {
|
||||
if (!vm.canForceEarlyReturn()) {
|
||||
throw new UnsupportedOperationException(
|
||||
"target does not support the forcing of a method to return early");
|
||||
}
|
||||
|
||||
validateMirrorOrNull(returnValue);
|
||||
|
||||
StackFrameImpl sf;
|
||||
try {
|
||||
sf = (StackFrameImpl)frame(0);
|
||||
} catch (IndexOutOfBoundsException exc) {
|
||||
throw new InvalidStackFrameException("No more frames on the stack");
|
||||
}
|
||||
sf.validateStackFrame();
|
||||
MethodImpl meth = (MethodImpl)sf.location().method();
|
||||
ValueImpl convertedValue = ValueImpl.prepareForAssignment(returnValue,
|
||||
meth.getReturnValueContainer());
|
||||
|
||||
try {
|
||||
JDWP.ThreadReference.ForceEarlyReturn.process(vm, this, convertedValue);
|
||||
} catch (JDWPException exc) {
|
||||
switch (exc.errorCode()) {
|
||||
case JDWP.Error.OPAQUE_FRAME:
|
||||
throw new NativeMethodException();
|
||||
case JDWP.Error.THREAD_NOT_SUSPENDED:
|
||||
throw new IncompatibleThreadStateException(
|
||||
"Thread not suspended");
|
||||
case JDWP.Error.THREAD_NOT_ALIVE:
|
||||
throw new IncompatibleThreadStateException(
|
||||
"Thread has not started or has finished");
|
||||
case JDWP.Error.NO_MORE_FRAMES:
|
||||
throw new InvalidStackFrameException(
|
||||
"No more frames on the stack");
|
||||
default:
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "instance of " + referenceType().name() +
|
||||
"(name='" + name() + "', " + "id=" + uniqueID() + ")";
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.THREAD;
|
||||
}
|
||||
|
||||
void addListener(ThreadListener listener) {
|
||||
synchronized (vm.state()) {
|
||||
listeners.add(new WeakReference<ThreadListener>(listener));
|
||||
}
|
||||
}
|
||||
|
||||
void removeListener(ThreadListener listener) {
|
||||
synchronized (vm.state()) {
|
||||
Iterator<WeakReference<ThreadListener>> iter = listeners.iterator();
|
||||
while (iter.hasNext()) {
|
||||
WeakReference<ThreadListener> ref = iter.next();
|
||||
if (listener.equals(ref.get())) {
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Propagate the the thread state change information
|
||||
* to registered listeners.
|
||||
* Must be entered while synchronized on vm.state()
|
||||
*/
|
||||
private void processThreadAction(ThreadAction action) {
|
||||
synchronized (vm.state()) {
|
||||
Iterator<WeakReference<ThreadListener>> iter = listeners.iterator();
|
||||
while (iter.hasNext()) {
|
||||
WeakReference<ThreadListener> ref = iter.next();
|
||||
ThreadListener listener = ref.get();
|
||||
if (listener != null) {
|
||||
switch (action.id()) {
|
||||
case ThreadAction.THREAD_RESUMABLE:
|
||||
if (!listener.threadResumable(action)) {
|
||||
iter.remove();
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// Listener is unreachable; clean up
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
// Discard our local cache
|
||||
resetLocalCache();
|
||||
}
|
||||
}
|
||||
}
|
||||
116
jdkSrc/jdk8/com/sun/tools/jdi/TypeComponentImpl.java
Normal file
116
jdkSrc/jdk8/com/sun/tools/jdi/TypeComponentImpl.java
Normal file
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
abstract public class TypeComponentImpl extends MirrorImpl
|
||||
implements TypeComponent
|
||||
{
|
||||
protected final long ref;
|
||||
protected final String name;
|
||||
protected final String signature;
|
||||
protected final String genericSignature;
|
||||
protected final ReferenceTypeImpl declaringType;
|
||||
private final int modifiers;
|
||||
|
||||
TypeComponentImpl(VirtualMachine vm, ReferenceTypeImpl declaringType,
|
||||
long ref,
|
||||
String name, String signature,
|
||||
String genericSignature, int modifiers) {
|
||||
// The generic signature is set when this is created.
|
||||
super(vm);
|
||||
this.declaringType = declaringType;
|
||||
this.ref = ref;
|
||||
this.name = name;
|
||||
this.signature = signature;
|
||||
if (genericSignature != null && genericSignature.length() != 0) {
|
||||
this.genericSignature = genericSignature;
|
||||
} else {
|
||||
this.genericSignature = null;
|
||||
}
|
||||
this.modifiers = modifiers;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String signature() {
|
||||
return signature;
|
||||
}
|
||||
public String genericSignature() {
|
||||
return genericSignature;
|
||||
}
|
||||
|
||||
public int modifiers() {
|
||||
return modifiers;
|
||||
}
|
||||
|
||||
public ReferenceType declaringType() {
|
||||
return declaringType;
|
||||
}
|
||||
|
||||
public boolean isStatic() {
|
||||
return isModifierSet(VMModifiers.STATIC);
|
||||
}
|
||||
|
||||
public boolean isFinal() {
|
||||
return isModifierSet(VMModifiers.FINAL);
|
||||
}
|
||||
|
||||
public boolean isPrivate() {
|
||||
return isModifierSet(VMModifiers.PRIVATE);
|
||||
}
|
||||
|
||||
public boolean isPackagePrivate() {
|
||||
return !isModifierSet(VMModifiers.PRIVATE
|
||||
| VMModifiers.PROTECTED
|
||||
| VMModifiers.PUBLIC);
|
||||
}
|
||||
|
||||
public boolean isProtected() {
|
||||
return isModifierSet(VMModifiers.PROTECTED);
|
||||
}
|
||||
|
||||
public boolean isPublic() {
|
||||
return isModifierSet(VMModifiers.PUBLIC);
|
||||
}
|
||||
|
||||
public boolean isSynthetic() {
|
||||
return isModifierSet(VMModifiers.SYNTHETIC);
|
||||
}
|
||||
|
||||
long ref() {
|
||||
return ref;
|
||||
}
|
||||
|
||||
boolean isModifierSet(int compareBits) {
|
||||
return (modifiers & compareBits) != 0;
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/com/sun/tools/jdi/TypeImpl.java
Normal file
62
jdkSrc/jdk8/com/sun/tools/jdi/TypeImpl.java
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2005, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public abstract class TypeImpl extends MirrorImpl implements Type
|
||||
{
|
||||
private String myName = null;
|
||||
|
||||
TypeImpl(VirtualMachine vm)
|
||||
{
|
||||
super(vm);
|
||||
}
|
||||
|
||||
public abstract String signature();
|
||||
|
||||
public String name() {
|
||||
if (myName == null) {
|
||||
JNITypeParser parser = new JNITypeParser(signature());
|
||||
myName = parser.typeName();
|
||||
}
|
||||
return myName;
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if ((obj != null) && (obj instanceof Type)) {
|
||||
Type other = (Type)obj;
|
||||
return signature().equals(other.signature()) &&
|
||||
super.equals(obj);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return signature().hashCode();
|
||||
}
|
||||
}
|
||||
66
jdkSrc/jdk8/com/sun/tools/jdi/VMAction.java
Normal file
66
jdkSrc/jdk8/com/sun/tools/jdi/VMAction.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2011, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.EventObject;
|
||||
|
||||
/*
|
||||
* The name "action" is used to avoid confusion
|
||||
* with JDI events.
|
||||
*/
|
||||
class VMAction extends EventObject {
|
||||
private static final long serialVersionUID = -1701944679310296090L;
|
||||
|
||||
// Event ids
|
||||
static final int VM_SUSPENDED = 1;
|
||||
static final int VM_NOT_SUSPENDED = 2;
|
||||
|
||||
int id;
|
||||
ThreadReference resumingThread;
|
||||
|
||||
VMAction(VirtualMachine vm, int id) {
|
||||
this(vm, null, id);
|
||||
}
|
||||
|
||||
// For id = VM_NOT_SUSPENDED, if resumingThread != null, then it is
|
||||
// the only thread that is being resumed.
|
||||
VMAction(VirtualMachine vm, ThreadReference resumingThread, int id) {
|
||||
super(vm);
|
||||
this.id = id;
|
||||
this.resumingThread = resumingThread;
|
||||
}
|
||||
VirtualMachine vm() {
|
||||
return (VirtualMachine)getSource();
|
||||
}
|
||||
int id() {
|
||||
return id;
|
||||
}
|
||||
|
||||
ThreadReference resumingThread() {
|
||||
return resumingThread;
|
||||
}
|
||||
}
|
||||
34
jdkSrc/jdk8/com/sun/tools/jdi/VMListener.java
Normal file
34
jdkSrc/jdk8/com/sun/tools/jdi/VMListener.java
Normal file
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2000, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import java.util.EventListener;
|
||||
|
||||
interface VMListener extends EventListener {
|
||||
boolean vmSuspended(VMAction action);
|
||||
boolean vmNotSuspended(VMAction action);
|
||||
}
|
||||
47
jdkSrc/jdk8/com/sun/tools/jdi/VMModifiers.java
Normal file
47
jdkSrc/jdk8/com/sun/tools/jdi/VMModifiers.java
Normal file
@@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2004, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public interface VMModifiers
|
||||
{
|
||||
int PUBLIC = 0x00000001; /* visible to everyone */
|
||||
int PRIVATE = 0x00000002; /* visible only to the defining class */
|
||||
int PROTECTED = 0x00000004; /* visible to subclasses */
|
||||
int STATIC = 0x00000008; /* instance variable is static */
|
||||
int FINAL = 0x00000010; /* no further subclassing, overriding */
|
||||
int SYNCHRONIZED = 0x00000020; /* wrap method call in monitor lock */
|
||||
int VOLATILE = 0x00000040; /* can cache in registers */
|
||||
int BRIDGE = 0x00000040; /* Bridge method generated by compiler */
|
||||
int TRANSIENT = 0x00000080; /* not persistant */
|
||||
int VARARGS = 0x00000080; /* Method accepts var. args*/
|
||||
int NATIVE = 0x00000100; /* implemented in C */
|
||||
int INTERFACE = 0x00000200; /* class is an interface */
|
||||
int ABSTRACT = 0x00000400; /* no definition provided */
|
||||
int ENUM_CONSTANT = 0x00004000; /* enum constant field*/
|
||||
int SYNTHETIC = 0xf0000000; /* not in source code */
|
||||
}
|
||||
250
jdkSrc/jdk8/com/sun/tools/jdi/VMState.java
Normal file
250
jdkSrc/jdk8/com/sun/tools/jdi/VMState.java
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 2020, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.util.*;
|
||||
|
||||
class VMState {
|
||||
private final VirtualMachineImpl vm;
|
||||
|
||||
// Listeners
|
||||
private final List<WeakReference<VMListener>> listeners = new ArrayList<WeakReference<VMListener>>(); // synchronized (this)
|
||||
private boolean notifyingListeners = false; // synchronized (this)
|
||||
|
||||
/*
|
||||
* Certain information can be cached only when the entire VM is
|
||||
* suspended and there are no pending resumes. The field below
|
||||
* is used to track whether there are pending resumes.
|
||||
*/
|
||||
private final Set<Integer> pendingResumeCommands = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
// This is cached only while the VM is suspended
|
||||
private static class Cache {
|
||||
List<ThreadGroupReference> groups = null; // cached Top Level ThreadGroups
|
||||
List<ThreadReference> threads = null; // cached Threads
|
||||
}
|
||||
|
||||
private Cache cache = null; // synchronized (this)
|
||||
private static final Cache markerCache = new Cache();
|
||||
|
||||
private void disableCache() {
|
||||
synchronized (this) {
|
||||
cache = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void enableCache() {
|
||||
synchronized (this) {
|
||||
cache = markerCache;
|
||||
}
|
||||
}
|
||||
|
||||
private Cache getCache() {
|
||||
synchronized (this) {
|
||||
if (cache == markerCache) {
|
||||
cache = new Cache();
|
||||
}
|
||||
return cache;
|
||||
}
|
||||
}
|
||||
|
||||
VMState(VirtualMachineImpl vm) {
|
||||
this.vm = vm;
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the VM currently suspended, for the purpose of caching?
|
||||
* Must be called synchronized on vm.state()
|
||||
*/
|
||||
boolean isSuspended() {
|
||||
return cache != null;
|
||||
}
|
||||
|
||||
/*
|
||||
* A JDWP command has been completed (reply has been received).
|
||||
* Update data that tracks pending resume commands.
|
||||
*/
|
||||
void notifyCommandComplete(int id) {
|
||||
pendingResumeCommands.remove(id);
|
||||
}
|
||||
|
||||
synchronized void freeze() {
|
||||
if (cache == null && (pendingResumeCommands.isEmpty())) {
|
||||
/*
|
||||
* No pending resumes to worry about. The VM is suspended
|
||||
* and additional state can be cached. Notify all
|
||||
* interested listeners.
|
||||
*/
|
||||
processVMAction(new VMAction(vm, VMAction.VM_SUSPENDED));
|
||||
enableCache();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized PacketStream thawCommand(CommandSender sender) {
|
||||
PacketStream stream = sender.send();
|
||||
pendingResumeCommands.add(stream.id());
|
||||
thaw();
|
||||
return stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* All threads are resuming
|
||||
*/
|
||||
void thaw() {
|
||||
thaw(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tell listeners to invalidate suspend-sensitive caches.
|
||||
* If resumingThread != null, then only that thread is being
|
||||
* resumed.
|
||||
*/
|
||||
synchronized void thaw(ThreadReference resumingThread) {
|
||||
if (cache != null) {
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace("Clearing VM suspended cache");
|
||||
}
|
||||
disableCache();
|
||||
}
|
||||
processVMAction(new VMAction(vm, resumingThread, VMAction.VM_NOT_SUSPENDED));
|
||||
}
|
||||
|
||||
private synchronized void processVMAction(VMAction action) {
|
||||
if (!notifyingListeners) {
|
||||
// Prevent recursion
|
||||
notifyingListeners = true;
|
||||
|
||||
Iterator<WeakReference<VMListener>> iter = listeners.iterator();
|
||||
while (iter.hasNext()) {
|
||||
WeakReference<VMListener> ref = iter.next();
|
||||
VMListener listener = ref.get();
|
||||
if (listener != null) {
|
||||
boolean keep = true;
|
||||
switch (action.id()) {
|
||||
case VMAction.VM_SUSPENDED:
|
||||
keep = listener.vmSuspended(action);
|
||||
break;
|
||||
case VMAction.VM_NOT_SUSPENDED:
|
||||
keep = listener.vmNotSuspended(action);
|
||||
break;
|
||||
}
|
||||
if (!keep) {
|
||||
iter.remove();
|
||||
}
|
||||
} else {
|
||||
// Listener is unreachable; clean up
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
|
||||
notifyingListeners = false;
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void addListener(VMListener listener) {
|
||||
listeners.add(new WeakReference<VMListener>(listener));
|
||||
}
|
||||
|
||||
synchronized boolean hasListener(VMListener listener) {
|
||||
Iterator<WeakReference<VMListener>> iter = listeners.iterator();
|
||||
while (iter.hasNext()) {
|
||||
WeakReference<VMListener> ref = iter.next();
|
||||
if (listener.equals(ref.get())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized void removeListener(VMListener listener) {
|
||||
Iterator<WeakReference<VMListener>> iter = listeners.iterator();
|
||||
while (iter.hasNext()) {
|
||||
WeakReference<VMListener> ref = iter.next();
|
||||
if (listener.equals(ref.get())) {
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
List<ThreadReference> allThreads() {
|
||||
List<ThreadReference> threads = null;
|
||||
try {
|
||||
Cache local = getCache();
|
||||
|
||||
if (local != null) {
|
||||
// may be stale when returned, but not provably so
|
||||
threads = local.threads;
|
||||
}
|
||||
if (threads == null) {
|
||||
threads = Arrays.asList((ThreadReference[])JDWP.VirtualMachine.AllThreads.
|
||||
process(vm).threads);
|
||||
if (local != null) {
|
||||
local.threads = threads;
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace("Caching all threads (count = " +
|
||||
threads.size() + ") while VM suspended");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return threads;
|
||||
}
|
||||
|
||||
|
||||
List<ThreadGroupReference> topLevelThreadGroups() {
|
||||
List<ThreadGroupReference> groups = null;
|
||||
try {
|
||||
Cache local = getCache();
|
||||
|
||||
if (local != null) {
|
||||
groups = local.groups;
|
||||
}
|
||||
if (groups == null) {
|
||||
groups = Arrays.asList(
|
||||
(ThreadGroupReference[])JDWP.VirtualMachine.TopLevelThreadGroups.
|
||||
process(vm).groups);
|
||||
if (local != null) {
|
||||
local.groups = groups;
|
||||
if ((vm.traceFlags & VirtualMachine.TRACE_OBJREFS) != 0) {
|
||||
vm.printTrace(
|
||||
"Caching top level thread groups (count = " +
|
||||
groups.size() + ") while VM suspended");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (JDWPException exc) {
|
||||
throw exc.toJDIException();
|
||||
}
|
||||
return groups;
|
||||
}
|
||||
|
||||
}
|
||||
41
jdkSrc/jdk8/com/sun/tools/jdi/ValueContainer.java
Normal file
41
jdkSrc/jdk8/com/sun/tools/jdi/ValueContainer.java
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
/*
|
||||
* This interface allows us to pass fields, variables, and
|
||||
* array components through the same interfaces. This currently allows
|
||||
* more common code for type checking. In the future we could use it for
|
||||
* more.
|
||||
*/
|
||||
interface ValueContainer {
|
||||
Type type() throws ClassNotLoadedException;
|
||||
Type findType(String signature) throws ClassNotLoadedException;
|
||||
String typeName();
|
||||
String signature();
|
||||
}
|
||||
64
jdkSrc/jdk8/com/sun/tools/jdi/ValueImpl.java
Normal file
64
jdkSrc/jdk8/com/sun/tools/jdi/ValueImpl.java
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
abstract class ValueImpl extends MirrorImpl implements Value {
|
||||
|
||||
ValueImpl(VirtualMachine aVm) {
|
||||
super(aVm);
|
||||
}
|
||||
|
||||
static ValueImpl prepareForAssignment(Value value,
|
||||
ValueContainer destination)
|
||||
throws InvalidTypeException, ClassNotLoadedException {
|
||||
if (value == null) {
|
||||
/*
|
||||
* TO DO: Centralize JNI signature knowledge
|
||||
*/
|
||||
if (destination.signature().length() == 1) {
|
||||
throw new InvalidTypeException("Can't set a primitive type to null");
|
||||
}
|
||||
return null; // no further checking or conversion necessary
|
||||
} else {
|
||||
return ((ValueImpl)value).prepareForAssignmentTo(destination);
|
||||
}
|
||||
}
|
||||
|
||||
static byte typeValueKey(Value val) {
|
||||
if (val == null) {
|
||||
return JDWP.Tag.OBJECT;
|
||||
} else {
|
||||
return ((ValueImpl)val).typeValueKey();
|
||||
}
|
||||
}
|
||||
|
||||
abstract ValueImpl prepareForAssignmentTo(ValueContainer destination)
|
||||
throws InvalidTypeException, ClassNotLoadedException;
|
||||
|
||||
abstract byte typeValueKey();
|
||||
}
|
||||
1435
jdkSrc/jdk8/com/sun/tools/jdi/VirtualMachineImpl.java
Normal file
1435
jdkSrc/jdk8/com/sun/tools/jdi/VirtualMachineImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
271
jdkSrc/jdk8/com/sun/tools/jdi/VirtualMachineManagerImpl.java
Normal file
271
jdkSrc/jdk8/com/sun/tools/jdi/VirtualMachineManagerImpl.java
Normal file
@@ -0,0 +1,271 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2008, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.connect.spi.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.ResourceBundle;
|
||||
import java.io.IOException;
|
||||
|
||||
import java.util.ServiceLoader;
|
||||
|
||||
/* Public for use by com.sun.jdi.Bootstrap */
|
||||
public class VirtualMachineManagerImpl implements VirtualMachineManagerService {
|
||||
private List<Connector> connectors = new ArrayList<Connector>();
|
||||
private LaunchingConnector defaultConnector = null;
|
||||
private List<VirtualMachine> targets = new ArrayList<VirtualMachine>();
|
||||
private final ThreadGroup mainGroupForJDI;
|
||||
private ResourceBundle messages = null;
|
||||
private int vmSequenceNumber = 0;
|
||||
private static final int majorVersion = 1;
|
||||
private static final int minorVersion = 8;
|
||||
|
||||
private static final Object lock = new Object();
|
||||
private static VirtualMachineManagerImpl vmm;
|
||||
|
||||
public static VirtualMachineManager virtualMachineManager() {
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
JDIPermission vmmPermission =
|
||||
new JDIPermission("virtualMachineManager");
|
||||
sm.checkPermission(vmmPermission);
|
||||
}
|
||||
synchronized (lock) {
|
||||
if (vmm == null) {
|
||||
vmm = new VirtualMachineManagerImpl();
|
||||
}
|
||||
}
|
||||
return vmm;
|
||||
}
|
||||
|
||||
protected VirtualMachineManagerImpl() {
|
||||
|
||||
/*
|
||||
* Create a top-level thread group
|
||||
*/
|
||||
ThreadGroup top = Thread.currentThread().getThreadGroup();
|
||||
ThreadGroup parent = null;
|
||||
while ((parent = top.getParent()) != null) {
|
||||
top = parent;
|
||||
}
|
||||
mainGroupForJDI = new ThreadGroup(top, "JDI main");
|
||||
|
||||
/*
|
||||
* Load the connectors
|
||||
*/
|
||||
ServiceLoader<Connector> connectorLoader =
|
||||
ServiceLoader.load(Connector.class, Connector.class.getClassLoader());
|
||||
|
||||
Iterator<Connector> connectors = connectorLoader.iterator();
|
||||
|
||||
while (connectors.hasNext()) {
|
||||
Connector connector;
|
||||
|
||||
try {
|
||||
connector = connectors.next();
|
||||
} catch (ThreadDeath x) {
|
||||
throw x;
|
||||
} catch (Exception x) {
|
||||
System.err.println(x);
|
||||
continue;
|
||||
} catch (Error x) {
|
||||
System.err.println(x);
|
||||
continue;
|
||||
}
|
||||
|
||||
addConnector(connector);
|
||||
}
|
||||
|
||||
/*
|
||||
* Load any transport services and encapsulate them with
|
||||
* an attaching and listening connector.
|
||||
*/
|
||||
ServiceLoader<TransportService> transportLoader =
|
||||
ServiceLoader.load(TransportService.class,
|
||||
TransportService.class.getClassLoader());
|
||||
|
||||
Iterator<TransportService> transportServices =
|
||||
transportLoader.iterator();
|
||||
|
||||
while (transportServices.hasNext()) {
|
||||
TransportService transportService;
|
||||
|
||||
try {
|
||||
transportService = transportServices.next();
|
||||
} catch (ThreadDeath x) {
|
||||
throw x;
|
||||
} catch (Exception x) {
|
||||
System.err.println(x);
|
||||
continue;
|
||||
} catch (Error x) {
|
||||
System.err.println(x);
|
||||
continue;
|
||||
}
|
||||
|
||||
addConnector(GenericAttachingConnector.create(transportService));
|
||||
addConnector(GenericListeningConnector.create(transportService));
|
||||
}
|
||||
|
||||
// no connectors found
|
||||
if (allConnectors().size() == 0) {
|
||||
throw new Error("no Connectors loaded");
|
||||
}
|
||||
|
||||
// Set the default launcher. In order to be compatible
|
||||
// 1.2/1.3/1.4 we try to make the default launcher
|
||||
// "com.sun.jdi.CommandLineLaunch". If this connector
|
||||
// isn't found then we arbitarly pick the first connector.
|
||||
//
|
||||
boolean found = false;
|
||||
List<LaunchingConnector> launchers = launchingConnectors();
|
||||
for (LaunchingConnector lc: launchers) {
|
||||
if (lc.name().equals("com.sun.jdi.CommandLineLaunch")) {
|
||||
setDefaultConnector(lc);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found && launchers.size() > 0) {
|
||||
setDefaultConnector(launchers.get(0));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public LaunchingConnector defaultConnector() {
|
||||
if (defaultConnector == null) {
|
||||
throw new Error("no default LaunchingConnector");
|
||||
}
|
||||
return defaultConnector;
|
||||
}
|
||||
|
||||
public void setDefaultConnector(LaunchingConnector connector) {
|
||||
defaultConnector = connector;
|
||||
}
|
||||
|
||||
public List<LaunchingConnector> launchingConnectors() {
|
||||
List<LaunchingConnector> launchingConnectors = new ArrayList<LaunchingConnector>(connectors.size());
|
||||
for (Connector connector: connectors) {
|
||||
if (connector instanceof LaunchingConnector) {
|
||||
launchingConnectors.add((LaunchingConnector)connector);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(launchingConnectors);
|
||||
}
|
||||
|
||||
public List<AttachingConnector> attachingConnectors() {
|
||||
List<AttachingConnector> attachingConnectors = new ArrayList<AttachingConnector>(connectors.size());
|
||||
for (Connector connector: connectors) {
|
||||
if (connector instanceof AttachingConnector) {
|
||||
attachingConnectors.add((AttachingConnector)connector);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(attachingConnectors);
|
||||
}
|
||||
|
||||
public List<ListeningConnector> listeningConnectors() {
|
||||
List<ListeningConnector> listeningConnectors = new ArrayList<ListeningConnector>(connectors.size());
|
||||
for (Connector connector: connectors) {
|
||||
if (connector instanceof ListeningConnector) {
|
||||
listeningConnectors.add((ListeningConnector)connector);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(listeningConnectors);
|
||||
}
|
||||
|
||||
public List<Connector> allConnectors() {
|
||||
return Collections.unmodifiableList(connectors);
|
||||
}
|
||||
|
||||
public List<VirtualMachine> connectedVirtualMachines() {
|
||||
return Collections.unmodifiableList(targets);
|
||||
}
|
||||
|
||||
public void addConnector(Connector connector) {
|
||||
connectors.add(connector);
|
||||
}
|
||||
|
||||
public void removeConnector(Connector connector) {
|
||||
connectors.remove(connector);
|
||||
}
|
||||
|
||||
public synchronized VirtualMachine createVirtualMachine(
|
||||
Connection connection,
|
||||
Process process) throws IOException {
|
||||
|
||||
if (!connection.isOpen()) {
|
||||
throw new IllegalStateException("connection is not open");
|
||||
}
|
||||
|
||||
VirtualMachine vm;
|
||||
try {
|
||||
vm = new VirtualMachineImpl(this, connection, process,
|
||||
++vmSequenceNumber);
|
||||
} catch (VMDisconnectedException e) {
|
||||
throw new IOException(e.getMessage());
|
||||
}
|
||||
targets.add(vm);
|
||||
return vm;
|
||||
}
|
||||
|
||||
public VirtualMachine createVirtualMachine(Connection connection) throws IOException {
|
||||
return createVirtualMachine(connection, null);
|
||||
}
|
||||
|
||||
public void addVirtualMachine(VirtualMachine vm) {
|
||||
targets.add(vm);
|
||||
}
|
||||
|
||||
void disposeVirtualMachine(VirtualMachine vm) {
|
||||
targets.remove(vm);
|
||||
}
|
||||
|
||||
public int majorInterfaceVersion() {
|
||||
return majorVersion;
|
||||
}
|
||||
|
||||
public int minorInterfaceVersion() {
|
||||
return minorVersion;
|
||||
}
|
||||
|
||||
ThreadGroup mainGroupForJDI() {
|
||||
return mainGroupForJDI;
|
||||
}
|
||||
|
||||
String getString(String key) {
|
||||
if (messages == null) {
|
||||
messages = ResourceBundle.getBundle("com.sun.tools.jdi.resources.jdi");
|
||||
}
|
||||
return messages.getString(key);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2003, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.connect.*;
|
||||
import com.sun.jdi.VirtualMachine;
|
||||
import com.sun.jdi.VirtualMachineManager;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* VirtualMachineManager SPI
|
||||
*/
|
||||
public interface VirtualMachineManagerService extends VirtualMachineManager {
|
||||
/**
|
||||
* Replaces the default connector.
|
||||
*
|
||||
* @return the default {@link LaunchingConnector}
|
||||
* @throws java.lang.IllegalArgumentException if the given
|
||||
* connector is not a member of the list returned by
|
||||
* {@link #launchingConnectors}
|
||||
*
|
||||
* @param connector the new default connector
|
||||
*/
|
||||
void setDefaultConnector(LaunchingConnector connector);
|
||||
|
||||
/**
|
||||
* Adds a connector to the list of known connectors.
|
||||
*
|
||||
* @param connector the connector to be added
|
||||
*/
|
||||
void addConnector(Connector connector);
|
||||
|
||||
/**
|
||||
* Removes a connector from the list of known connectors.
|
||||
*
|
||||
* @param connector the connector to be removed
|
||||
*/
|
||||
void removeConnector(Connector connector);
|
||||
|
||||
}
|
||||
42
jdkSrc/jdk8/com/sun/tools/jdi/VoidTypeImpl.java
Normal file
42
jdkSrc/jdk8/com/sun/tools/jdi/VoidTypeImpl.java
Normal file
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 1999, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class VoidTypeImpl extends TypeImpl implements VoidType {
|
||||
VoidTypeImpl(VirtualMachine vm) {
|
||||
super(vm);
|
||||
}
|
||||
|
||||
public String signature() {
|
||||
return String.valueOf((char)JDWP.Tag.VOID);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return name();
|
||||
}
|
||||
}
|
||||
66
jdkSrc/jdk8/com/sun/tools/jdi/VoidValueImpl.java
Normal file
66
jdkSrc/jdk8/com/sun/tools/jdi/VoidValueImpl.java
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 1998, 2006, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
package com.sun.tools.jdi;
|
||||
|
||||
import com.sun.jdi.*;
|
||||
|
||||
public class VoidValueImpl extends ValueImpl implements VoidValue {
|
||||
|
||||
VoidValueImpl(VirtualMachine aVm) {
|
||||
super(aVm);
|
||||
}
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
return (obj != null) && (obj instanceof VoidValue) && super.equals(obj);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
/*
|
||||
* TO DO: Better hash code
|
||||
*/
|
||||
return 47245;
|
||||
}
|
||||
|
||||
public Type type() {
|
||||
return vm.theVoidType();
|
||||
}
|
||||
|
||||
ValueImpl prepareForAssignmentTo(ValueContainer destination)
|
||||
throws InvalidTypeException {
|
||||
if ("void".equals(destination.typeName())) {
|
||||
return this;
|
||||
}
|
||||
throw new InvalidTypeException();
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "<void value>";
|
||||
}
|
||||
|
||||
byte typeValueKey() {
|
||||
return JDWP.Tag.VOID;
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/com/sun/tools/jdi/resources/jdi.java
Normal file
62
jdkSrc/jdk8/com/sun/tools/jdi/resources/jdi.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.sun.tools.jdi.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jdi extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "false", "false" },
|
||||
{ "generic_attaching.address", "Address to which to attach for VM connections" },
|
||||
{ "generic_attaching.address.label", "Address" },
|
||||
{ "generic_attaching.timeout", "Timeout while waiting to attach " },
|
||||
{ "generic_attaching.timeout.label", "Timeout" },
|
||||
{ "generic_listening.address", "Address to listen for VM connections" },
|
||||
{ "generic_listening.address.label", "Address" },
|
||||
{ "generic_listening.timeout", "Timeout while waiting for connection" },
|
||||
{ "generic_listening.timeout.label", "Timeout" },
|
||||
{ "memory_attaching.description", "Attaches by shared memory to other VMs" },
|
||||
{ "memory_attaching.name", "Name of the shared memory area to which to attach for VM connections" },
|
||||
{ "memory_attaching.name.label", "Name" },
|
||||
{ "memory_listening.description", "Accepts shared memory connections initiated by other VMs" },
|
||||
{ "memory_listening.name", "Name of the shared memory area at which to listen for VM connection" },
|
||||
{ "memory_listening.name.label", "Name" },
|
||||
{ "memory_transportservice.description", "Connects debugger and debugee using a shared memory connection" },
|
||||
{ "process_attaching.description", "Attaches to debuggee by process-id (pid)" },
|
||||
{ "process_attaching.pid", "pid" },
|
||||
{ "process_attaching.pid.label", "Process-id (pid) of debuggee" },
|
||||
{ "raw.address", "Address from which to listen for a connection after the raw command is run" },
|
||||
{ "raw.address.label", "Address" },
|
||||
{ "raw.command", "Raw command to start the debugged application VM" },
|
||||
{ "raw.command.label", "Command" },
|
||||
{ "raw.description", "Launches target using user-specified command line and attaches to it" },
|
||||
{ "raw.quote", "Character used to combine space-delimited text into a single command line argument" },
|
||||
{ "raw.quote.label", "Quote" },
|
||||
{ "socket_attaching.description", "Attaches by socket to other VMs" },
|
||||
{ "socket_attaching.host", "Machine name to which to attach for VM connections" },
|
||||
{ "socket_attaching.host.label", "Host" },
|
||||
{ "socket_attaching.port", "Port number to which to attach for VM connections" },
|
||||
{ "socket_attaching.port.label", "Port" },
|
||||
{ "socket_listening.description", "Accepts socket connections initiated by other VMs" },
|
||||
{ "socket_listening.localaddr", "Local address that the listener binds to" },
|
||||
{ "socket_listening.localaddr.label", "Local address" },
|
||||
{ "socket_listening.port", "Port number at which to listen for VM connections" },
|
||||
{ "socket_listening.port.label", "Port" },
|
||||
{ "socket_transportservice.description", "Connects debugger and debugee using a TCP connection" },
|
||||
{ "sun.description", "Launches target using Sun Java VM command line and attaches to it" },
|
||||
{ "sun.home", "Home directory of the SDK or runtime environment used to launch the application" },
|
||||
{ "sun.home.label", "Home " },
|
||||
{ "sun.init_suspend", "All threads will be suspended before execution of main" },
|
||||
{ "sun.init_suspend.label", "Suspend" },
|
||||
{ "sun.main", "Main class and arguments, or if -jar is an option, the main jar file and arguments" },
|
||||
{ "sun.main.label", "Main" },
|
||||
{ "sun.options", "Launched VM options" },
|
||||
{ "sun.options.label", "Options" },
|
||||
{ "sun.quote", "Character used to combine space-delimited text into a single command line argument" },
|
||||
{ "sun.quote.label", "Quote" },
|
||||
{ "sun.vm_exec", "Name of the Java VM launcher" },
|
||||
{ "sun.vm_exec.label", "Launcher" },
|
||||
{ "true", "true" },
|
||||
{ "version_format", "Java Debug Interface (Reference Implementation) version {0}.{1} \n{2}" },
|
||||
};
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/com/sun/tools/jdi/resources/jdi_ja.java
Normal file
62
jdkSrc/jdk8/com/sun/tools/jdi/resources/jdi_ja.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.sun.tools.jdi.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jdi_ja extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "false", "false" },
|
||||
{ "generic_attaching.address", "VM\u306B\u63A5\u7D9A\u3059\u308B\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "generic_attaching.address.label", "\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "generic_attaching.timeout", "\u63A5\u7D9A\u3092\u5F85\u3064\u9593\u306E\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8 " },
|
||||
{ "generic_attaching.timeout.label", "\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8" },
|
||||
{ "generic_listening.address", "VM\u3078\u306E\u63A5\u7D9A\u3092\u30EA\u30B9\u30CB\u30F3\u30B0\u3059\u308B\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "generic_listening.address.label", "\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "generic_listening.timeout", "\u63A5\u7D9A\u3092\u5F85\u3064\u9593\u306E\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8" },
|
||||
{ "generic_listening.timeout.label", "\u30BF\u30A4\u30E0\u30A2\u30A6\u30C8" },
|
||||
{ "memory_attaching.description", "\u5171\u6709\u30E1\u30E2\u30EA\u30FC\u3067\u305D\u306E\u4ED6\u306EVM\u306B\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "memory_attaching.name", "VM\u3078\u306E\u63A5\u7D9A\u306B\u4F7F\u7528\u3055\u308C\u308B\u5171\u6709\u30E1\u30E2\u30EA\u30FC\u9818\u57DF\u540D" },
|
||||
{ "memory_attaching.name.label", "\u540D\u524D" },
|
||||
{ "memory_listening.description", "\u305D\u306E\u4ED6\u306EVM\u306B\u3088\u308A\u958B\u59CB\u3055\u308C\u308B\u5171\u6709\u30E1\u30E2\u30EA\u30FC\u63A5\u7D9A\u3092\u53D7\u3051\u5165\u308C\u307E\u3059" },
|
||||
{ "memory_listening.name", "VM\u3078\u306E\u63A5\u7D9A\u3092\u30EA\u30B9\u30CB\u30F3\u30B0\u3059\u308B\u305F\u3081\u306E\u5171\u6709\u30E1\u30E2\u30EA\u30FC\u9818\u57DF\u540D" },
|
||||
{ "memory_listening.name.label", "\u540D\u524D" },
|
||||
{ "memory_transportservice.description", "\u5171\u6709\u30E1\u30E2\u30EA\u30FC\u63A5\u7D9A\u3067\u30C7\u30D0\u30C3\u30AC\u3068\u30BF\u30FC\u30B2\u30C3\u30C8\u3092\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "process_attaching.description", "\u30C7\u30D0\u30C3\u30B0\u3059\u308B\u30D7\u30ED\u30BB\u30B9\u306B\u30D7\u30ED\u30BB\u30B9ID (pid)\u3092\u4F7F\u7528\u3057\u3066\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "process_attaching.pid", "pid" },
|
||||
{ "process_attaching.pid.label", "\u30C7\u30D0\u30C3\u30B0\u3059\u308B\u30D7\u30ED\u30BB\u30B9ID (pid)" },
|
||||
{ "raw.address", "raw\u30B3\u30DE\u30F3\u30C9\u5B9F\u884C\u5F8C\u306B\u63A5\u7D9A\u3092\u30EA\u30B9\u30CB\u30F3\u30B0\u3059\u308B\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "raw.address.label", "\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "raw.command", "\u30C7\u30D0\u30C3\u30B0\u3059\u308B\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3VM\u3092\u8D77\u52D5\u3055\u305B\u308Braw\u30B3\u30DE\u30F3\u30C9" },
|
||||
{ "raw.command.label", "\u30B3\u30DE\u30F3\u30C9" },
|
||||
{ "raw.description", "\u30E6\u30FC\u30B6\u30FC\u304C\u6307\u5B9A\u3057\u305F\u30B3\u30DE\u30F3\u30C9\u884C\u3092\u4F7F\u7528\u3057\u3066\u30BF\u30FC\u30B2\u30C3\u30C8\u3092\u8D77\u52D5\u3057\u3001\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "raw.quote", "\u5358\u4E00\u306E\u30B3\u30DE\u30F3\u30C9\u884C\u5F15\u6570\u5185\u306B\u30B9\u30DA\u30FC\u30B9\u3067\u533A\u5207\u3089\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u7D50\u3073\u4ED8\u3051\u308B\u305F\u3081\u306B\u4F7F\u7528\u3055\u308C\u308B\u6587\u5B57" },
|
||||
{ "raw.quote.label", "\u5F15\u7528\u7B26" },
|
||||
{ "socket_attaching.description", "\u30BD\u30B1\u30C3\u30C8\u3067\u305D\u306E\u4ED6\u306EVM\u306B\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "socket_attaching.host", "VM\u306B\u63A5\u7D9A\u3059\u308B\u30DE\u30B7\u30F3\u540D" },
|
||||
{ "socket_attaching.host.label", "\u30DB\u30B9\u30C8" },
|
||||
{ "socket_attaching.port", "VM\u306B\u63A5\u7D9A\u3059\u308B\u30DD\u30FC\u30C8\u756A\u53F7" },
|
||||
{ "socket_attaching.port.label", "\u30DD\u30FC\u30C8" },
|
||||
{ "socket_listening.description", "\u305D\u306E\u4ED6\u306EVM\u306B\u3088\u308A\u958B\u59CB\u3055\u308C\u308B\u30BD\u30B1\u30C3\u30C8\u63A5\u7D9A\u3092\u53D7\u5165\u308C\u307E\u3059" },
|
||||
{ "socket_listening.localaddr", "\u30EA\u30B9\u30CA\u30FC\u306E\u30D0\u30A4\u30F3\u30C9\u5148\u30ED\u30FC\u30AB\u30EB\u30FB\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "socket_listening.localaddr.label", "\u30ED\u30FC\u30AB\u30EB\u30FB\u30A2\u30C9\u30EC\u30B9" },
|
||||
{ "socket_listening.port", "VM\u3078\u306E\u63A5\u7D9A\u3092\u30EA\u30B9\u30CB\u30F3\u30B0\u3059\u308B\u30DD\u30FC\u30C8\u756A\u53F7" },
|
||||
{ "socket_listening.port.label", "\u30DD\u30FC\u30C8" },
|
||||
{ "socket_transportservice.description", "TCP\u63A5\u7D9A\u3067\u30C7\u30D0\u30C3\u30AC\u3068\u30BF\u30FC\u30B2\u30C3\u30C8\u3092\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "sun.description", "Sun\u306EJava VM\u30B3\u30DE\u30F3\u30C9\u884C\u3092\u4F7F\u7528\u3057\u3066\u30BF\u30FC\u30B2\u30C3\u30C8\u3092\u8D77\u52D5\u3057\u3001\u63A5\u7D9A\u3057\u307E\u3059" },
|
||||
{ "sun.home", "SDK\u306E\u30DB\u30FC\u30E0\u30FB\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u307E\u305F\u306F\u3001\u30A2\u30D7\u30EA\u30B1\u30FC\u30B7\u30E7\u30F3\u306E\u8D77\u52D5\u306B\u4F7F\u7528\u3055\u308C\u308B\u5B9F\u884C\u74B0\u5883" },
|
||||
{ "sun.home.label", "\u30DB\u30FC\u30E0 " },
|
||||
{ "sun.init_suspend", "\u30E1\u30A4\u30F3\u306E\u5B9F\u884C\u524D\u306B\u3059\u3079\u3066\u306E\u30B9\u30EC\u30C3\u30C9\u304C\u4E2D\u65AD\u3055\u308C\u307E\u3059\u3002" },
|
||||
{ "sun.init_suspend.label", "\u4E2D\u65AD" },
|
||||
{ "sun.main", "\u30E1\u30A4\u30F3\u30FB\u30AF\u30E9\u30B9\u3068\u5F15\u6570\u3001\u307E\u305F\u306F-jar\u304C\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5834\u5408\u306B\u306F\u30E1\u30A4\u30F3jar\u30D5\u30A1\u30A4\u30EB\u3068\u5F15\u6570" },
|
||||
{ "sun.main.label", "\u30E1\u30A4\u30F3" },
|
||||
{ "sun.options", "\u8D77\u52D5\u3059\u308BVM\u306E\u30AA\u30D7\u30B7\u30E7\u30F3" },
|
||||
{ "sun.options.label", "\u30AA\u30D7\u30B7\u30E7\u30F3" },
|
||||
{ "sun.quote", "\u5358\u4E00\u306E\u30B3\u30DE\u30F3\u30C9\u884C\u5F15\u6570\u5185\u306B\u30B9\u30DA\u30FC\u30B9\u3067\u533A\u5207\u3089\u308C\u305F\u30C6\u30AD\u30B9\u30C8\u3092\u7D50\u3073\u4ED8\u3051\u308B\u305F\u3081\u306B\u4F7F\u7528\u3055\u308C\u308B\u6587\u5B57" },
|
||||
{ "sun.quote.label", "\u5F15\u7528\u7B26" },
|
||||
{ "sun.vm_exec", "Java VM\u8D77\u52D5\u30C4\u30FC\u30EB\u540D" },
|
||||
{ "sun.vm_exec.label", "\u8D77\u52D5\u30C4\u30FC\u30EB" },
|
||||
{ "true", "true" },
|
||||
{ "version_format", "Java Debug Interface(\u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u5B9F\u88C5)\u30D0\u30FC\u30B8\u30E7\u30F3{0}.{1}\n{2}" },
|
||||
};
|
||||
}
|
||||
}
|
||||
62
jdkSrc/jdk8/com/sun/tools/jdi/resources/jdi_zh_CN.java
Normal file
62
jdkSrc/jdk8/com/sun/tools/jdi/resources/jdi_zh_CN.java
Normal file
@@ -0,0 +1,62 @@
|
||||
package com.sun.tools.jdi.resources;
|
||||
|
||||
import java.util.ListResourceBundle;
|
||||
|
||||
public final class jdi_zh_CN extends ListResourceBundle {
|
||||
protected final Object[][] getContents() {
|
||||
return new Object[][] {
|
||||
{ "false", "false" },
|
||||
{ "generic_attaching.address", "VM \u8FDE\u63A5\u6240\u9644\u52A0\u5230\u7684\u5730\u5740" },
|
||||
{ "generic_attaching.address.label", "\u5730\u5740" },
|
||||
{ "generic_attaching.timeout", "\u7B49\u5F85\u9644\u52A0\u64CD\u4F5C\u65F6\u7684\u8D85\u65F6" },
|
||||
{ "generic_attaching.timeout.label", "\u8D85\u65F6" },
|
||||
{ "generic_listening.address", "\u76D1\u542C VM \u8FDE\u63A5\u65F6\u4F7F\u7528\u7684\u5730\u5740" },
|
||||
{ "generic_listening.address.label", "\u5730\u5740" },
|
||||
{ "generic_listening.timeout", "\u7B49\u5F85\u8FDE\u63A5\u65F6\u7684\u8D85\u65F6" },
|
||||
{ "generic_listening.timeout.label", "\u8D85\u65F6" },
|
||||
{ "memory_attaching.description", "\u901A\u8FC7\u5171\u4EAB\u5185\u5B58\u9644\u52A0\u5230\u5176\u4ED6 VM" },
|
||||
{ "memory_attaching.name", "VM \u8FDE\u63A5\u6240\u9644\u52A0\u5230\u7684\u5171\u4EAB\u5185\u5B58\u533A\u57DF\u7684\u540D\u79F0" },
|
||||
{ "memory_attaching.name.label", "\u540D\u79F0" },
|
||||
{ "memory_listening.description", "\u63A5\u53D7\u7531\u5176\u4ED6 VM \u542F\u52A8\u7684\u5171\u4EAB\u5185\u5B58\u8FDE\u63A5" },
|
||||
{ "memory_listening.name", "\u76D1\u542C VM \u8FDE\u63A5\u65F6\u6240\u5728\u7684\u5171\u4EAB\u5185\u5B58\u533A\u57DF\u7684\u540D\u79F0" },
|
||||
{ "memory_listening.name.label", "\u540D\u79F0" },
|
||||
{ "memory_transportservice.description", "\u4F7F\u7528\u5171\u4EAB\u5185\u5B58\u8FDE\u63A5\u6765\u8FDE\u63A5\u8C03\u8BD5\u5668\u548C\u88AB\u8C03\u8BD5\u8FDB\u7A0B" },
|
||||
{ "process_attaching.description", "\u901A\u8FC7\u8FDB\u7A0B ID (PID) \u9644\u52A0\u5230\u88AB\u8C03\u8BD5\u8FDB\u7A0B" },
|
||||
{ "process_attaching.pid", "PID" },
|
||||
{ "process_attaching.pid.label", "\u88AB\u8C03\u8BD5\u8FDB\u7A0B\u7684\u8FDB\u7A0B ID (PID)" },
|
||||
{ "raw.address", "\u8FD0\u884C\u539F\u59CB\u547D\u4EE4\u4E4B\u540E, \u76D1\u542C\u8FDE\u63A5\u65F6\u4F7F\u7528\u7684\u5730\u5740" },
|
||||
{ "raw.address.label", "\u5730\u5740" },
|
||||
{ "raw.command", "\u7528\u4E8E\u542F\u52A8\u8C03\u8BD5\u5E94\u7528\u7A0B\u5E8F VM \u7684\u539F\u59CB\u547D\u4EE4" },
|
||||
{ "raw.command.label", "\u547D\u4EE4" },
|
||||
{ "raw.description", "\u4F7F\u7528\u7528\u6237\u6307\u5B9A\u7684\u547D\u4EE4\u884C\u542F\u52A8\u76EE\u6807\u5E76\u9644\u52A0\u5230\u8BE5\u76EE\u6807" },
|
||||
{ "raw.quote", "\u7528\u4E8E\u5C06\u4EE5\u7A7A\u683C\u5206\u9694\u7684\u6587\u672C\u7EC4\u5408\u4E3A\u4E00\u4E2A\u547D\u4EE4\u884C\u53C2\u6570\u7684\u5B57\u7B26" },
|
||||
{ "raw.quote.label", "\u5F15\u53F7" },
|
||||
{ "socket_attaching.description", "\u901A\u8FC7\u5957\u63A5\u5B57\u9644\u52A0\u5230\u5176\u4ED6 VM" },
|
||||
{ "socket_attaching.host", "VM \u8FDE\u63A5\u6240\u9644\u52A0\u5230\u7684\u8BA1\u7B97\u673A\u540D\u79F0" },
|
||||
{ "socket_attaching.host.label", "\u4E3B\u673A" },
|
||||
{ "socket_attaching.port", "VM \u8FDE\u63A5\u6240\u9644\u52A0\u5230\u7684\u7AEF\u53E3\u53F7" },
|
||||
{ "socket_attaching.port.label", "\u7AEF\u53E3" },
|
||||
{ "socket_listening.description", "\u63A5\u53D7\u7531\u5176\u4ED6 VM \u542F\u52A8\u7684\u5957\u63A5\u5B57\u8FDE\u63A5" },
|
||||
{ "socket_listening.localaddr", "\u76D1\u542C\u7A0B\u5E8F\u7ED1\u5B9A\u5230\u7684\u672C\u5730\u5730\u5740" },
|
||||
{ "socket_listening.localaddr.label", "\u672C\u5730\u5730\u5740" },
|
||||
{ "socket_listening.port", "\u76D1\u542C VM \u8FDE\u63A5\u65F6\u4F7F\u7528\u7684\u7AEF\u53E3\u53F7" },
|
||||
{ "socket_listening.port.label", "\u7AEF\u53E3" },
|
||||
{ "socket_transportservice.description", "\u4F7F\u7528 TCP \u8FDE\u63A5\u6765\u8FDE\u63A5\u8C03\u8BD5\u5668\u548C\u88AB\u8C03\u8BD5\u8FDB\u7A0B" },
|
||||
{ "sun.description", "\u4F7F\u7528 Sun Java VM \u547D\u4EE4\u884C\u542F\u52A8\u76EE\u6807\u5E76\u9644\u52A0\u5230\u8BE5\u76EE\u6807" },
|
||||
{ "sun.home", "\u7528\u4E8E\u542F\u52A8\u5E94\u7528\u7A0B\u5E8F\u7684 SDK \u6216\u8FD0\u884C\u65F6\u73AF\u5883\u7684\u4E3B\u76EE\u5F55" },
|
||||
{ "sun.home.label", "\u4E3B\u76EE\u5F55 " },
|
||||
{ "sun.init_suspend", "\u5728\u6267\u884C\u4E3B\u7C7B\u4E4B\u524D, \u5C06\u6302\u8D77\u6240\u6709\u7EBF\u7A0B" },
|
||||
{ "sun.init_suspend.label", "\u6302\u8D77" },
|
||||
{ "sun.main", "\u4E3B\u7C7B\u548C\u53C2\u6570, \u6216\u8005\u5982\u679C -jar \u662F\u4E00\u4E2A\u9009\u9879, \u5219\u4E3A\u4E3B jar \u6587\u4EF6\u548C\u53C2\u6570" },
|
||||
{ "sun.main.label", "\u4E3B" },
|
||||
{ "sun.options", "\u5DF2\u542F\u52A8\u7684 VM \u9009\u9879" },
|
||||
{ "sun.options.label", "\u9009\u9879" },
|
||||
{ "sun.quote", "\u7528\u4E8E\u5C06\u4EE5\u7A7A\u683C\u5206\u9694\u7684\u6587\u672C\u7EC4\u5408\u4E3A\u4E00\u4E2A\u547D\u4EE4\u884C\u53C2\u6570\u7684\u5B57\u7B26" },
|
||||
{ "sun.quote.label", "\u5F15\u53F7" },
|
||||
{ "sun.vm_exec", "Java VM \u542F\u52A8\u7A0B\u5E8F\u7684\u540D\u79F0" },
|
||||
{ "sun.vm_exec.label", "\u542F\u52A8\u7A0B\u5E8F" },
|
||||
{ "true", "true" },
|
||||
{ "version_format", "Java \u8C03\u8BD5\u63A5\u53E3 (\u53C2\u8003\u5B9E\u73B0) \u7248\u672C {0}.{1}\n{2}" },
|
||||
};
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user