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;
 										}