You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kato-commits@incubator.apache.org by mo...@apache.org on 2009/05/28 17:31:27 UTC
svn commit: r779687 -
/incubator/kato/branches/experimental/maven_restructure/org.apache.kato/kato.jdi/src/main/java/org/apache/kato/tools/jdi/DTFJReader.java
Author: monteith
Date: Thu May 28 17:31:27 2009
New Revision: 779687
URL: http://svn.apache.org/viewvc?rev=779687&view=rev
Log:
Add JDWP StackFrame.GetValue and StackFrame.ThisObject support to JDI connector.
Modified:
incubator/kato/branches/experimental/maven_restructure/org.apache.kato/kato.jdi/src/main/java/org/apache/kato/tools/jdi/DTFJReader.java
Modified: incubator/kato/branches/experimental/maven_restructure/org.apache.kato/kato.jdi/src/main/java/org/apache/kato/tools/jdi/DTFJReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/branches/experimental/maven_restructure/org.apache.kato/kato.jdi/src/main/java/org/apache/kato/tools/jdi/DTFJReader.java?rev=779687&r1=779686&r2=779687&view=diff
==============================================================================
--- incubator/kato/branches/experimental/maven_restructure/org.apache.kato/kato.jdi/src/main/java/org/apache/kato/tools/jdi/DTFJReader.java (original)
+++ incubator/kato/branches/experimental/maven_restructure/org.apache.kato/kato.jdi/src/main/java/org/apache/kato/tools/jdi/DTFJReader.java Thu May 28 17:31:27 2009
@@ -28,6 +28,8 @@
import org.apache.kato.image.ImageAddressSpace;
import org.apache.kato.image.ImageFactory;
import org.apache.kato.image.ImageProcess;
+import org.apache.kato.image.KatoException;
+import org.apache.kato.image.MemoryAccessException;
import org.apache.kato.java.JavaClass;
import org.apache.kato.java.JavaClassLoader;
import org.apache.kato.java.JavaField;
@@ -94,6 +96,7 @@
public static final int ERROR_NONE = 0;
public static final int ERROR_INVALID_OBJECT = 20;
public static final int ERROR_INVALID_THREAD = 10;
+ public static final int ERROR_INVALID_SLOT = 35;
public static final int ERROR_NOT_IMPLEMENTED = 99;
public static final int ERROR_ABSENT_INFORMATION = 101;
public static final int ERROR_INTERNAL = 113;
@@ -152,6 +155,24 @@
public static final int REFERENCE_TYPE_CLASS_OBJECT = 11;
public static final int REFERENCE_TYPE_SOURCE_DEBUG_EXTENSION = 12;
+ public static final int TAG_ARRAY = 91;
+ public static final int TAG_BYTE = 66;
+ public static final int TAG_CHAR = 67;
+ public static final int TAG_OBJECT = 76;
+ public static final int TAG_FLOAT = 70;
+ public static final int TAG_DOUBLE = 68;
+ public static final int TAG_INT = 73;
+ public static final int TAG_LONG = 74;
+ public static final int TAG_SHORT = 83;
+ public static final int TAG_VOID = 86;
+ public static final int TAG_BOOLEAN = 90;
+ public static final int TAG_STRING = 115;
+ public static final int TAG_THREAD = 116;
+ public static final int TAG_THREAD_GROUP = 103;
+ public static final int TAG_CLASS_LOADER = 108;
+ public static final int TAG_CLASS_OBJECT = 99;
+
+
@@ -661,6 +682,101 @@
}
/**
+ * Transforms a JavaObject into a real java/lang/String object.
+ * Does this by extracting the following fields from java/lang/String:
+ * <pre>
+ * int offset, count;
+ * char[] value;
+ * </pre>
+ *
+ * @param object
+ * JavaObject representation of a java.lang.String object.
+ * @return String or null if there were problems.
+ * @throws IllegalArgumentException thrown if JavaObject not java/lang/String
+ */
+ public static String javaObjectToString(JavaObject object)
+ throws IllegalArgumentException {
+
+ if (object == null) {
+ return null;
+ }
+
+ String className = null;
+ JavaClass stringClass = null;
+
+ try {
+ stringClass = object.getJavaClass();
+ className = stringClass.getName();
+ } catch (CorruptDataException e) {
+ e.printStackTrace();
+ return null;
+ }
+
+ if (!className.equals("java/lang/String")) {
+ throw new IllegalArgumentException(
+ "Mismatched types - expecting java/lang/String, got `"
+ + className + "'");
+ }
+
+ int offset = 0, count = 0;
+ char[] value = null;
+ JavaObject valueArray = null;
+ boolean gotValue = false, gotOffset = false, gotCount = false;
+
+ // Get all fields, pick out interesting ones.
+ for (Object fobj : stringClass.getDeclaredFields()) {
+
+
+ if (fobj instanceof CorruptData) {
+ continue;
+ }
+
+ JavaField field = (JavaField) fobj;
+ try {
+ String fieldName = field.getName();
+
+ if (fieldName.equals("offset")) {
+ offset = field.getInt(object);
+ gotOffset = true;
+ } else if (fieldName.equals("count")) {
+ count = field.getInt(object);
+ gotCount = true;
+ } else if (fieldName.equals("value")) {
+ valueArray = (JavaObject) field.get(object);
+ gotValue = true;
+ }
+
+ } catch (KatoException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ try {
+ // Check we got all of the fields.
+ if ((gotOffset || gotCount || gotValue) == false) {
+ return null;
+ } else {
+ int length = (int) valueArray.getArraySize();
+ value = new char[length];
+ try {
+ valueArray.arraycopy(0, value, 0, length);
+ } catch (IndexOutOfBoundsException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+
+ return new String(value, offset, count);
+ } catch (CorruptDataException e) {
+ e.printStackTrace();
+ return null;
+ } catch (MemoryAccessException e) {
+ e.printStackTrace();
+ return null;
+ }
+ }
+ /**
* Convert a Vector to a byte array
* @param vctr The Vector to convert
* @return An array consisting of bytes (Not Bytes)
@@ -751,6 +867,45 @@
}
/**
+ * Add a 16bit short to the front of the Byte Vector
+ * @param vctr Vector to add the bytes to
+ * @param inShort The short to add
+ */
+ public static void addShortToVectorFront(Vector<Byte> vctr, short inShort){
+ vctr.add(0, getByteFromInt(inShort, 1));
+ vctr.add(1, getByteFromInt(inShort, 0));
+ }
+
+ /**
+ * Add a 16bit short to the end of the Byte Vector
+ * @param vctr Vector to add the bytes to
+ * @param inShort The int to add
+ */
+ public static void addShortToVector(Vector<Byte> vctr, int inShort){
+ vctr.add(getByteFromInt(inShort, 1));
+ vctr.add(getByteFromInt(inShort, 0));
+ }
+
+ /**
+ * Add a 16bit char to the front of the Byte Vector
+ * @param vctr Vector to add the bytes to
+ * @param inChar The short to add
+ */
+ public static void addCharToVectorFront(Vector<Byte> vctr, int inChar){
+ vctr.add(0, getByteFromInt(inChar, 1));
+ vctr.add(1, getByteFromInt(inChar, 0));
+ }
+
+ /**
+ * Add a 16bit char to the end of the Byte Vector
+ * @param vctr Vector to add the bytes to
+ * @param inChar The int to add
+ */
+ public static void addCharToVector(Vector<Byte> vctr, int inChar){
+ vctr.add(getByteFromInt(inChar, 1));
+ vctr.add(getByteFromInt(inChar, 0));
+ }
+ /**
* Add a string to the end of the Byte Vector as specified in the JDWP docs (4 byte length + ASCII chars)
* @param vctr Vector to add the bytes to
* @param inString The string to add
@@ -2615,7 +2770,7 @@
logr.log(JDILogger.LEVEL_VERBOSE, "StackFrame.GetValues(" + threadID + "," + frameID + "," + slots + ",...)"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$
Vector<Byte> vctr = new Vector<Byte>();
ReplyPacket rpckt = new ReplyPacket(cpckt.getSequence(), FLAG_REPLY_PACKET, ERROR_NONE);
- addIntToVector(vctr, 1);
+ addIntToVector(vctr, slots);
Iterator asIt = image.getAddressSpaces( ).iterator();
while ( asIt.hasNext( ) )
{
@@ -2642,9 +2797,136 @@
while(frames.hasNext()){
JavaStackFrame jFrame = (JavaStackFrame)frames.next();
if (jFrame.getBasePointer().getAddress() == frameID){
- vctr.add((byte)'L');
- addLongToVector(vctr,jFrame.getLocation().getMethod().getDeclaringClass().getID().getAddress());
- logr.log(JDILogger.LEVEL_VERBOSE, " " + jFrame.getLocation().getMethod().getDeclaringClass().getID().getAddress()); //$NON-NLS-1$
+// vctr.add((byte)'L');
+// addLongToVector(vctr,jFrame.getLocation().getMethod().getDeclaringClass().getID().getAddress());
+// logr.log(JDILogger.LEVEL_VERBOSE, " " + jFrame.getLocation().getMethod().getDeclaringClass().getID().getAddress()); //$NON-NLS-1$
+ // Get slot number and type of each requested variable.
+GETVALUESLOTS: for (int i=0; i < slots; i++) {
+ int slot = createIntFromBytes(inData, 20+5*i, 4);
+ byte type = inData[20+5*i+1];
+
+ Object value = jFrame.getVariable(slot);
+
+ switch(type) {
+ case TAG_ARRAY:
+ long arrayAddress = -1L;
+ if (value instanceof JavaObject) {
+ JavaObject obj = (JavaObject) value;
+ if (obj.isArray()) {
+ arrayAddress = obj.getID().getAddress();
+ }
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " Array in slot=" + slot + " value="+arrayAddress);
+ addLongToVector(vctr, arrayAddress );
+ break;
+ case TAG_BYTE:
+ byte byteVal = -1;
+
+ if (value instanceof Number) {
+ Number num = (Number) value;
+ byteVal = num.byteValue();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " byte in slot=" + slot + " value="+byteVal);
+ vctr.add(byteVal);
+ break;
+ case TAG_CHAR:
+ char charVal = (char) -1;
+
+ if (value instanceof Character) {
+ charVal = (Character) value;
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " byte in slot=" + slot + " value="+charVal);
+ addCharToVector(vctr, charVal);
+ break;
+ case TAG_OBJECT:
+ long objectAddress = -1L;
+ if (value instanceof JavaObject) {
+ JavaObject obj = (JavaObject) value;
+ objectAddress = obj.getID().getAddress();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " Object in slot=" + slot + " value="+objectAddress);
+ addLongToVector(vctr, objectAddress );
+ break;
+ case TAG_FLOAT:
+ float floatVal = -1;
+
+ if (value instanceof Number) {
+ Number num = (Number) value;
+ floatVal = num.floatValue();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " float in slot=" + slot + " value="+floatVal);
+ addIntToVector(vctr, Float.floatToIntBits(floatVal));
+ break;
+ case TAG_DOUBLE:
+ double doubleVal = -1;
+
+ if (value instanceof Number) {
+ Number num = (Number) value;
+ doubleVal = num.doubleValue();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " double in slot=" + slot + " value="+doubleVal);
+ addLongToVector(vctr, Double.doubleToLongBits(doubleVal));
+
+ break;
+ case TAG_INT:
+ int intVal = -1;
+
+ if (value instanceof Number) {
+ Number num = (Number) value;
+ intVal = num.intValue();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " int in slot=" + slot + " value="+intVal);
+ addIntToVector(vctr, intVal);
+ break;
+ case TAG_LONG:
+ long longVal = -1;
+
+ if (value instanceof Number) {
+ Number num = (Number) value;
+ longVal = num.longValue();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " long in slot=" + slot + " value="+longVal);
+ addLongToVector(vctr, longVal);
+
+ break;
+ case TAG_SHORT:
+ short shortVal = -1;
+
+ if (value instanceof Number) {
+ Number num = (Number) value;
+ shortVal = num.shortValue();
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " short in slot=" + slot + " value="+shortVal);
+ addShortToVector(vctr, shortVal);
+
+ break;
+ case TAG_BOOLEAN:
+ boolean booleanVal = false;
+
+ if (value instanceof Boolean) {
+ booleanVal = ((Boolean) value);
+ }
+
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " boolean in slot=" + slot + " value="+booleanVal);
+ vctr.add(booleanVal ? (byte) 1 : (byte) 0);
+ break;
+ case TAG_STRING:
+ String stringVal= "";
+
+ if (value instanceof JavaObject) {
+ stringVal = javaObjectToString( (JavaObject) value);
+ }
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " string in slot=" + slot + " value=\""+stringVal+"\"");
+ addStringToVector(vctr, stringVal);
+ break;
+ default:
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " unable to handle type "+type+" in "+jFrame.getLocation());
+ rpckt = new ReplyPacket(cpckt.getSequence(), FLAG_REPLY_PACKET, ERROR_NONE);
+ vctr = new Vector<Byte>();
+ break GETVALUESLOTS;
+ }
+
+ }
}
}
}
@@ -2693,14 +2975,22 @@
if (jFrame.getBasePointer().getAddress() == frameID){
Vector<Byte> vctr = new Vector<Byte>();
ReplyPacket rpckt = new ReplyPacket(cpckt.getSequence(), FLAG_REPLY_PACKET, ERROR_NONE);
- if (jFrame.getLocation().getMethod().getDeclaringClass().isArray()){
- vctr.add((byte)'[');
- }else{
- vctr.add((byte)'L');
+
+ if ((jFrame.getLocation().getMethod().getModifiers() & Modifier.STATIC) !=0) {
+ addLongToVector(vctr, 0); // Return null as static method.
+ }
+
+ Object value = jFrame.getVariable(0);
+ long objectAddress = -1;
+ if (value instanceof JavaObject) {
+ JavaObject obj = (JavaObject) value;
+ if (obj.isArray()) {
+ objectAddress = obj.getID().getAddress();
+ }
}
- addLongToVector(vctr, jFrame.getLocation().getMethod().getDeclaringClass().getID().getAddress());
- logr.log(JDILogger.LEVEL_VERYVERBOSE, jFrame.getLocation().getMethod().getName());
- logr.log(JDILogger.LEVEL_VERYVERBOSE, jFrame.getLocation().getMethod().getDeclaringClass().getName() + "{" + jFrame.getLocation().getMethod().getDeclaringClass().getID().getAddress() + "}"); //$NON-NLS-1$ //$NON-NLS-2$
+ logr.log(JDILogger.LEVEL_VERBOSE, " " +jFrame.getLocation() + " return this object value="+objectAddress);
+ addLongToVector(vctr, objectAddress );
+
rpckt.setData(vectorToByte(vctr));
return rpckt;
}