incubator-kato-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From monte...@apache.org
Subject svn commit: r816693 [2/2] - in /incubator/kato/trunk/org.apache.kato/kato.cjvmti/src/main/java/org/apache/kato/jvmti: javaruntime/ javaruntime/model/ reader/
Date Fri, 18 Sep 2009 16:10:35 GMT
Modified: incubator/kato/trunk/org.apache.kato/kato.cjvmti/src/main/java/org/apache/kato/jvmti/reader/CJVMTIBinReader.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.cjvmti/src/main/java/org/apache/kato/jvmti/reader/CJVMTIBinReader.java?rev=816693&r1=816692&r2=816693&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.cjvmti/src/main/java/org/apache/kato/jvmti/reader/CJVMTIBinReader.java
(original)
+++ incubator/kato/trunk/org.apache.kato/kato.cjvmti/src/main/java/org/apache/kato/jvmti/reader/CJVMTIBinReader.java
Fri Sep 18 16:10:34 2009
@@ -46,8 +46,11 @@
 import org.apache.kato.jvmti.javaruntime.model.JThread;
 import org.apache.kato.jvmti.javaruntime.model.Model;
 
-
-
+/**
+ * 
+ * CJVMTIBinReader - Reads cjvmti dump files 
+ *
+ */
 public class CJVMTIBinReader {
 
 	private static final byte CJVMTI_BYTE = 0x1c;
@@ -90,14 +93,13 @@
 	private static final byte CJVMTI_CLASS_INTERFACES = 0x24;
 	private long selfGeneratedIDs;
 	private int selfGeneratedMonitorIDs = 1;
-	FileImageInputStream in = null;
 	FileImageInputStream variablesIn = null;
 	Model model = new Model();
 	static Logger log = CLogger.logr;
 
 	JClassLoader readerJCL;// Class loader for reader generated classes
 	JClassLoader bootJCL;// Class loader for boot class loader (return nulls in
-	
+
 	// jvmti
 	JClass intArray;// "[int"
 	//
@@ -117,107 +119,93 @@
 	JObject nullObject;
 	HashMap<JObject, JClass> objectArrayClasses;
 
+	public static void simpler(Model m, Model m2){
+		System.out.println("");
+	}
 	@SuppressWarnings("unchecked")
 	public static void main(String[] args) {
-		
-		File f = new File("c:\\cjvmti.cdmp");
+
+		File f = new File("c:\\cjvmtiV0.cdmp");
+		File f2 = new File("c:\\cjvmtiVDu.cdmp");
 		log.setLevel(Level.ALL);
 		ConsoleHandler handle = new ConsoleHandler();
-		handle.setLevel(Level.FINER);
+		handle.setLevel(Level.ALL);
 		log.addHandler(handle);
-		
-		log.log(Level.FINEST,f.toString());
+
+		log.log(Level.FINEST, f.toString());
 		CJVMTIBinReader cjvm = null;
+		CJVMTIBinReader cjvmEx = null;
 		try {
 			cjvm = new CJVMTIBinReader(f);
+			cjvmEx = new CJVMTIBinReader(f2);
 		} catch (IOException e) {
 			e.printStackTrace();
 			System.exit(0);
 		}
-		log.log(Level.FINER,"");
-		log.log(Level.FINER,"");
-		log.log(Level.FINER,"");
+		simpler(cjvm.model, cjvmEx.model);
+		log.log(Level.FINER, "");
+		log.log(Level.FINER, "");
+		log.log(Level.FINER, "");
+		cjvmEx.toString();
 		List<JavaThread> jthreads = cjvm.getModel().getThreads();
 
 		for (JavaThread t : jthreads) {
 			try {
-				log.log(Level.FINEST,t.getName());
+				log.log(Level.FINEST, t.getName());
 				for (JavaStackFrame jsf : t.getStackFrames()) {
 					for (JavaVariable jv : jsf.getVariables()) {
 
 						try {
-							log.log(Level.FINEST,"" + jv.getName() + " "
+							log.log(Level.FINEST, "" + jv.getName() + " "
 									+ jv.getSignature() + " ");
 						} catch (DataUnavailable e) {
 							// TODO Auto-generated catch block
 							e.printStackTrace();
 						}
-						log.log(Level.FINEST,"" + jv.getValue());
+						log.log(Level.FINEST, "" + jv.getValue());
 					}
 				}
 			} catch (CorruptDataException e) {
-				// TODO Auto-generated catch block
 				e.printStackTrace();
 			}
 		}
-
-	
-
-//		try {
-//			JavaClass jclC = cjvm.getModel().getObjectAtAddress(376679)
-//					.getJavaClass();
-//			JavaObject obj = cjvm.getModel().getObjectAtAddress(376679);
-//			log.log(Level.FINEST," num Fields " + ((JObject) obj).getNumFields());
-//			log.log(Level.FINEST," " + jclC.getID().getAddress());
-//			while (jclC != null) {
-//				for (JavaField field : jclC.getDeclaredFields()) {
-//					if (field.getSignature().equals("Ljava/lang/String;")) {
-//						log.log(Level.FINEST,"Found string");
-//						log.log(Level.FINEST,field.getSignature() + " field "
-//								+ field.getName() + " " + jclC.getName());
-//
-//						try {
-//							log.log(Level.FINEST,"HEre" + field.getString(obj));
-//						} catch (MemoryAccessException e) {
-//							// TODO Auto-generated catch block
-//							e.printStackTrace();
-//						}
-//					}
-//				}
-//				jclC = jclC.getSuperclass();
-//			}
-//		} catch (CorruptDataException e) {
-//			// TODO Auto-generated catch block
-//			e.printStackTrace();
-//		}
-//		log.log(Level.FINEST," "+cjvm.getModel().getObjectAtAddress(380215));
-		log.log(Level.INFO,"Finished test read");
+		
+		log.log(Level.INFO, "Finished test read");
 	}
 
+	/**
+	 * Attempts to read in a cjvmti dump file
+	 * @param base Target file
+	 * @throws IOException
+	 */
 	public CJVMTIBinReader(File base) throws IOException {
-		RandomAccessFile raf = new RandomAccessFile(base, "r");
-		in = new FileImageInputStream(raf);
-		RandomAccessFile dumpF = raf;
+		boolean bigEndian = true;
+		
+		//log.setLevel(Level.ALL);
+		ConsoleHandler handle = new ConsoleHandler();
+		//handle.setLevel(Level.ALL);
+		//log.addHandler(handle);
+
+		//log.log(Level.FINEST, base.toString());
 
 		// Currently split file setout, open variable file
 
-		RandomAccessFile raf2 = new RandomAccessFile(new File(base.getParent()
-				+ "\\cjvmtiV.cdmp"), "r");
+		RandomAccessFile raf2 = new RandomAccessFile(base, "r");
 		variablesIn = new FileImageInputStream(raf2);
-		selfGeneratedIDs = variablesIn.length() + 1;
-		if (dumpF.readInt() == 1) {
-			in.setByteOrder(ByteOrder.BIG_ENDIAN);
+		
+		selfGeneratedIDs = variablesIn.length() + 1; // Ensure classes generated by the reader
do not collide with dump file class references
+		variablesIn.readLong();
+		if (variablesIn.readInt() == 1) {
 			variablesIn.setByteOrder(ByteOrder.BIG_ENDIAN);
 		} else {
-			in.setByteOrder(ByteOrder.LITTLE_ENDIAN);
 			variablesIn.setByteOrder(ByteOrder.LITTLE_ENDIAN);
 		}
 
-		variablesIn.read();
-		dumpF.seek(0);
+		variablesIn.seek(0);
+		variablesIn.readLong();
 
 		// check Endian setting
-		if (in.readInt() != 1) {
+		if (variablesIn.readInt() != 1) {
 			System.err
 					.println("Incorrect format for reader/failed to set endian");
 			throw new IOException();
@@ -226,49 +214,62 @@
 		StringBuilder sb = new StringBuilder();
 
 		for (int i = 0; i < 12; i++) {
-			sb.append((char) in.readByte());
+			sb.append((char) variablesIn.readByte());
 		}
 
 		if (!sb.toString().equals("CJVMTI V0.01")) {
-			System.err.println("Incorrect format for reader");
+			System.err.println("Incorrect format for reader _" + sb.toString()
+					+ "_");
 			throw new IOException();
 		}
-		log.log(Level.INFO,"CJVMTI Format V0.01");
-		log.log(Level.INFO,"Starting reading in..");
-
-		Long time = in.readLong();
+		log.log(Level.INFO, "CJVMTI Format V0.01");
+		log.log(Level.INFO, "Starting reading in..");
 
+		Long time = variablesIn.readLong();
 
 		Date creationDate = new Date((time * 1000));
-		log.log(Level.INFO,"Date of creation: " + creationDate.toString());
+		log.log(Level.INFO, "Date of creation: " + creationDate.toString());
 
 		JMonitor.model = model;
 		generateClassLoaderForReader();
 		generatePrimitiveArrayClasses();
-		// check id
-
-		while (true) {
+		
+		
 			byte recordGroup = 0;
 
 			try {
-				recordGroup = (byte) in.readUnsignedByte();
-				log.log(Level.FINEST,"RG: " + recordGroup);
+				recordGroup = (byte) variablesIn.readUnsignedByte();
+				log.log(Level.FINEST, "RG: " + recordGroup);
 			} catch (EOFException ee) {
-				log.log(Level.FINEST,"Finished");
-				break;
+				log.log(Level.FINEST, "Finished");
 			}
+			
+			
 			switch (recordGroup) {
 			case CJVMTI_THREAD:
-				nreadThread(in.getStreamPosition() - 1);
+				int numThreads = variablesIn.readInt();
+				long threadRefs[] = new long[numThreads];
+				for (int i = 0; i < numThreads; i++){
+					threadRefs[i] = variablesIn.readLong();
+				}
+				for (int i = 0; i < numThreads; i++) {
+					log.finest("Reading thread at "+Long.toHexString(threadRefs[i]));
+					nreadThread(threadRefs[i]);
+				}
 				break;
 			default:
 				error("record group " + recordGroup + " is not understood");
 			}
-		}
-		log.log(Level.INFO,"CJVMTI bin reader complete" );
+		
+		log.log(Level.INFO, "CJVMTI bin reader complete");
 	}
 
-	private JLocalVariableTableEntry nlocalVarTable(JClass c)
+	/**
+	 * Local variable table information
+	 * @return
+	 * @throws IOException
+	 */
+	private JLocalVariableTableEntry nlocalVarTable()
 			throws IOException {
 		// log.log(Level.FINEST,"Get local var table");
 		String name = readCString(variablesIn);
@@ -288,6 +289,11 @@
 		return jlvt;
 	}
 
+	/**
+	 * Method information
+	 * @param c Defining class
+	 * @throws IOException
+	 */
 	private void nmethodDetails(JClass c) throws IOException {
 		if (variablesIn.readByte() != CJVMTI_METHOD)
 			throw new IOException();
@@ -297,17 +303,23 @@
 		String mGenSig = readCString(variablesIn);
 		int modifiers = variablesIn.readInt();
 		int count = variablesIn.readInt();
+		
+		
 		JMethod jm = model.getMethod(methodID);
 		jm.name = mName;
 		jm.signature = mSig;
 		if (mGenSig.equals(" ")) {
-			jm.genericsignature = null;
+			jm.genericsignature = null; // Not currently keeping it null, left as reminder
 		}
 		jm.genericsignature = mGenSig;
 		jm.mods = modifiers;
+		
 		for (int i = 0; i < count; i++) {
-			jm.addLocalVariableTableEntry(nlocalVarTable(c));
+			JLocalVariableTableEntry jlte = nlocalVarTable();
+			jm.addLocalVariableTableEntry(jlte);
 		}
+		
+		// Line number table
 		int lntLength = variablesIn.readInt();
 		for (int i = 0; i < lntLength; i++) {
 			int lNum = variablesIn.readInt();
@@ -317,6 +329,12 @@
 		c.addMethod(jm);
 	}
 
+	/**
+	 * Static field details
+	 * @param c Defining class
+	 * @return Number of static fields
+	 * @throws IOException
+	 */
 	private int nstaticFieldDetails(JClass c) throws IOException {
 		int fieldCount = variablesIn.readInt();
 		for (int i = 0; i < fieldCount; i++) {
@@ -331,11 +349,16 @@
 			fl.signature = sig;
 			fl.staticField = true;
 			fl.modifiers = modifiers;
-			fl.index = i; // used to fill in fields
+			fl.index = i; // Used to ensure references are filled in the order when filling in static
values
 		}
 		return fieldCount;
 	}
 
+	/**
+	 * Instance field details
+	 * @param c Defining class
+	 * @throws IOException
+	 */
 	private void instanceFieldDetails(JClass c) throws IOException {
 		int fieldCount = variablesIn.readInt();
 		for (int i = 0; i < fieldCount; i++) {
@@ -351,10 +374,15 @@
 			fl.staticField = false;
 			fl.modifiers = modifiers;
 			fl.index = i; // used to fill in fields
-			// log.log(Level.FINEST,"Field " + fl.index);
 		}
 	}
 
+	/**
+	 * Read class at defined position
+	 * @param ref Position in file
+	 * @return
+	 * @throws IOException
+	 */
 	private JClass nreadClass(long ref) throws IOException {
 		variablesIn.seek(ref);
 		if (ref == 0) {
@@ -362,33 +390,43 @@
 		if (variablesIn.readByte() == CJVMTI_CLASS) {
 			return nreadClass();
 		} else {
-			log.log(Level.FINEST,"IO EX" + Long.toHexString(ref));
+			log.log(Level.FINEST, "IO EX" + Long.toHexString(ref));
 			throw new IOException();
 		}
 	}
 
+	/**
+	 * Read class at current position
+	 * @return
+	 * @throws IOException
+	 */
 	private JClass nreadClass() throws IOException {
 		long id = variablesIn.getStreamPosition();
-		id--;
+		id--; // Class id/ImagePointer
+		
 		JClass c = model.getClass(id);
+		
+		// Prevent reference loops (check if this class is partly filled in)
 		if (c.classSig != null)
 			return c;
+		
 		int modifiers = variablesIn.readInt();
 		c.modifiers = (short) modifiers;
-		log.log(Level.FINEST,"mods " + modifiers + " " + c.modifiers);
+		log.log(Level.FINEST, "mods " + modifiers + " " + c.modifiers);
 		String name = readCString(variablesIn);
 		String sourceFile = readCString(variablesIn);
 		String genSig = readCString(variablesIn);
 
 		// TODO move this to C implementation
 		if (sourceFile.equals("NoSource")) {
-			sourceFile = null;
+			if (!(name.indexOf("[")>-1)&&name.indexOf("L")>-1){
+				sourceFile = name.substring(name.lastIndexOf("/")+1, name.indexOf(";")); // Small attempt
to extend number of sourcefiles reported to Eclipse
+			}
 		}
 		c.classSig = name;
 		c.classid = id;
 		c.sourceFile = sourceFile;
-		long currentFileLoc = variablesIn.getStreamPosition();
-		variablesIn.seek(currentFileLoc);
+		
 		if (variablesIn.readByte() == CJVMTI_METHOD) {
 			int num = variablesIn.readInt();
 			for (int i = 0; i < num; i++) {
@@ -444,19 +482,19 @@
 		} else {
 			throw new IOException();
 		}
+		
 		c.superClassID = supC;
-		c.locIn = 1;
 		if (supC != CJVMTI_NULL_OBJECT) {
 			c.superclass = nreadClass(supC);
 		}
-		c.locIn = 2;
-		// Use index to fill into \the correct slot
+
+		// Read static field references
 		for (JField fl : (List<JField>) c.getDeclaredFields()) {
 			if (fl.staticField) {
 				fl.staticValue = nreadReference(refs[fl.index]);
 			}
 		}
-		log.log(Level.FINEST,"num interf: " + interfaceClasses.length + " "
+		log.log(Level.FINEST, "num interf: " + interfaceClasses.length + " "
 				+ c.classSig);
 		// Follow interface references
 		for (long interfaceRef : interfaceClasses) {
@@ -468,7 +506,7 @@
 		if (classLoaderRef == 0) {
 			bootJCL.addClass(c);
 			c.classloader = bootJCL;
-			//c.classloader = null;
+			// c.classloader = null;
 		} else {
 			JClassLoader jcl = model.getLoader(classLoaderRef);
 			jcl.addClass(c);
@@ -478,7 +516,7 @@
 			}
 			c.classloader = jcl;
 			try {
-				log.log(Level.FINEST,"Class loader : "
+				log.log(Level.FINEST, "Class loader : "
 						+ c.getClassLoader().getObject().getJavaClass()
 								.getName() + " for " + c.getName());
 			} catch (CorruptDataException e) {
@@ -486,16 +524,16 @@
 				e.printStackTrace();
 			}
 		}
-		c.locIn = 3;
-
-		if (c.classloader == null) {
-			//log.log(Level.FINEST,"No valid class loader");
-			//System.exit(0);
-		}
 
 		return c;
 	}
 
+	/**
+	 * Conveniance class for loading objects
+	 * @param position Position in file
+	 * @return Populated JObject or null
+	 * @throws IOException
+	 */
 	private JObject nreadObject(long position) throws IOException {
 		variablesIn.seek(position);
 		if (position == CJVMTI_NULL_OBJECT) {
@@ -508,6 +546,11 @@
 		}
 	}
 
+	/**
+	 * Reads an object at the current file position
+	 * @return Populated java object
+	 * @throws IOException
+	 */
 	private JObject nreadObject() throws IOException {
 		long objectID = variablesIn.getStreamPosition() - 1;
 		long classRef = variablesIn.readLong();
@@ -515,14 +558,15 @@
 		long offset = variablesIn.getStreamPosition();
 		// log.log(Level.FINEST,"objectID " + Long.toHexString(objectID));
 		JClass c = nreadClass(classRef);
-		log.log(Level.FINEST,"Obj id " + Long.toHexString(objectID));
+		log.log(Level.FINEST, "Obj id " + Long.toHexString(objectID));
 		JObject obj = model.getObject(classRef, objectID);
+		
 		if (obj.visited)
 			return obj; // Prevent reference loop
-
 		obj.visited = true;
+		
+		// Calculate how many instance fields the reader can see on the class hierarchy
 		int instanceFieldCount = 0;
-
 		JClass superClass = c;
 		while (superClass != null) {
 			for (JField jf : (List<JField>) superClass.getDeclaredFields()) {
@@ -531,12 +575,15 @@
 			}
 			superClass = model.getClass(superClass.superClassID);
 		}
+		
+		// Check they match the dump files recoard
 		if (numInstanceFields != instanceFieldCount) {
-			log.log(Level.FINEST,"Non-matching " + numInstanceFields + " found "
-					+ instanceFieldCount);
+			log.log(Level.FINEST, "Non-matching " + numInstanceFields
+					+ " found " + instanceFieldCount);
 			System.exit(0);
 		}
 
+		// Now read in all the references
 		long instanceRefs[] = new long[instanceFieldCount];
 		variablesIn.seek(offset);
 		int countUp = 0;
@@ -545,8 +592,10 @@
 			countUp++;
 		}
 		offset = variablesIn.getStreamPosition();
+		
+		
+		// Follow the references grabbing the correct jfield for the hierarchy of classes
 		int fieldCount = 0;
-
 		int fieldOffset;
 		fieldOffset = 0;
 		superClass = c;
@@ -554,6 +603,10 @@
 			for (JField jf : (List<JField>) superClass.getDeclaredFields()) {
 				if (!jf.staticField) {
 					fieldCount++;
+					if (instanceRefs[fieldOffset +jf.index] == 0x9999999999999999L){
+						log.fine("Error, unwritten reference");
+					}
+					log.finest("Reading in "+fieldCount);
 
 					obj
 							.addValue(jf.getFieldID(),
@@ -566,11 +619,17 @@
 			superClass = model.getClass(superClass.superClassID);
 		}
 
-		log.log(Level.FINEST," " + fieldCount + "  " + numInstanceFields + " "
+		log.log(Level.FINEST, " " + fieldCount + "  " + numInstanceFields + " "
 				+ instanceFieldCount + " " + c.classSig);
 		return obj;
 	}
 
+	/**
+	 * Takes a reference (and thus a file position) and returns a populated object
+	 * @param position Position in file
+	 * @return
+	 * @throws IOException
+	 */
 	private Object nreadReference(long position) throws IOException {
 		if (position == CJVMTI_NULL_OBJECT) {
 			return null;
@@ -606,7 +665,7 @@
 				long classType = variablesIn.readLong();
 				length = variablesIn.readInt();
 				long currentReadPos = variablesIn.getStreamPosition();
-				log.log(Level.FINEST,"pos " + classType);
+				log.log(Level.FINEST, "Object Array " + classType);
 				JClass arrayClass = nreadClass(classType);
 				variablesIn.seek(currentReadPos);
 				JObject objA[] = new JObject[length];
@@ -617,7 +676,7 @@
 						objA[counter] = (JObject) null;
 						continue;
 					}
-					log.log(Level.FINEST,"Reading " + counter + " at "
+					log.log(Level.FINEST, "Reading " + counter + " at "
 							+ Long.toHexString(objReference));
 					currentReadPos = variablesIn.getStreamPosition();
 					objA[counter] = (JObject) nreadReference(objReference);
@@ -725,68 +784,37 @@
 				System.exit(0);
 			}
 		} catch (Exception e) {
-			log.log(Level.FINEST,e.toString());
+			
+			log.log(Level.FINEST, e.toString());
 			e.printStackTrace();
+			log.finest("Tried to read at "+Long.toHexString(position));
 			System.exit(0);
 		}
 		return null;
 	}
 
+	
+	/**
+	 * This is used to simulate the java boot class loader  
+	 */
 	private void generateClassLoaderForReader() {
 
-		// generate system classloader
-		
-		
-		
-		selfGeneratedIDs++;
-		JClassLoader rootJCL = model.getLoader(selfGeneratedIDs);
-		JClass rootCLC = model.getClass(selfGeneratedIDs);
-		rootCLC.classSig = "Ljava/lang/SystemClassLoaderBASE;";
-		JObject rootObj = model.getObject(selfGeneratedIDs, selfGeneratedIDs);
-		rootJCL.obj = rootObj;
-		selfGeneratedIDs++;
-		
-		
+		// generate system classloader 
+
 		selfGeneratedIDs++;
 		bootJCL = model.getLoader(selfGeneratedIDs);
 		JClass bootCLC = model.getClass(selfGeneratedIDs);
 		bootCLC.classSig = "Ljava/lang/CJVMTISystemClassLoader;";
 		JObject bootObj = model.getObject(selfGeneratedIDs, selfGeneratedIDs);
 		bootJCL.obj = bootObj;
-		//rootJCL.addClass(bootCLC);
+		// rootJCL.addClass(bootCLC);
 		bootCLC.classloader = null;
 		readerJCL = bootJCL;
 	}
-	
-
-
-	private JClass getArrayClass(JObject type) {
-		if (objectArrayClasses == null) {
-			objectArrayClasses = new HashMap<JObject, JClass>();
-		}
-		if (objectArrayClasses.get(type) != null) {
-			return objectArrayClasses.get(type);
-		} else {
-			selfGeneratedIDs++;
-			JClass c = model.getClass(selfGeneratedIDs);
-			try {
-				c.classSig = "[" + type.getJavaClass().getName();
-			} catch (CorruptDataException e) {
-				// TODO Auto-generated catch block
-				e.printStackTrace();
-				c.classSig = "LUnknownObjectArray;";
-			}
-			readerJCL.addClass(c);
-			objectArrayClasses.put(type, c);
-			return c;
-		}
-	}
-
-	private void generateNullObject() {
-		selfGeneratedIDs++;
-
-	}
 
+	/**
+	 * Manually add the primitive array classes
+	 */
 	private void generatePrimitiveArrayClasses() {
 		// "[int"
 		selfGeneratedIDs++;
@@ -837,16 +865,12 @@
 		readerJCL.addClass(charArray);
 	}
 
-	private String readName() throws IOException {
-		int nameLength = in.readInt();
-		if (nameLength > 0) {
-			byte name[] = new byte[nameLength];
-			in.readFully(name);
-			return new String(name);
-		}
-		return null;
-	}
-
+	/**
+	 * Read a C style null terminated string
+	 * @param z Input stream pointing at the start of the string
+	 * @return
+	 * @throws IOException
+	 */
 	private String readCString(FileImageInputStream z) throws IOException {
 		StringBuilder sb = new StringBuilder();
 		char cur;
@@ -856,152 +880,205 @@
 		return sb.toString();
 	}
 
-	public JLocalVariable nreadLocalVars() throws IOException {
-		JLocalVariable jlv = new JLocalVariable();
-		String sig = readCString(in);
-		String name = readCString(in);
-		int length = in.readInt();
-		int slot = in.readInt();
-		long reference = in.readLong();
-		nreadReference(reference);
-		jlv.slot = slot;
-		jlv.setValue(nreadReference(reference));
-		return jlv;
-	}
-
-	private void nreadFrames(JThread t) throws IOException {
-		long startPos;
-		int frameCount = in.readInt();
-		if (frameCount == 0)
-			log.log(Level.FINEST,"No Frames");
-		for (int i = 0; i < frameCount; i++) {
-			startPos = in.getStreamPosition();
-			if (in.readByte() == CJVMTI_FRAME) {
-				log.log(Level.FINEST,"Reading frame" + i + " of " + frameCount);
-				long frameSize = in.readLong();
-				byte jvmtiErr = in.readByte();
-				if (jvmtiErr == CJVMTI_JVMTI_ERROR) {
-					log.log(Level.FINEST,"Data not available");
-					in.seek(startPos + frameSize + 1);
-					continue;
-				}
-				long methodID = in.readLong();
-				String methodName = readCString(in);
-				log.log(Level.FINEST,"Method name is: " + methodName);
-				long declaringClass = in.readLong();
-				Object o = (JClass) nreadReference(declaringClass); // Get class
-				// info for
-				// this
-				// frame
-				JClass clazz = null;
-				if (!(clazz instanceof JClass)) {
-					clazz = (JClass) o;
-				}
-				byte depth = in.readByte();
+
+
+	/**
+	 * Read a stack frame
+	 * @param pos Position of frame in file
+	 * @param t Thread the frame is contained in 
+	 * @throws IOException
+	 */
+	private void nreadFrames(long pos, JThread t) throws IOException {
+		variablesIn.seek(pos);
+		byte val = variablesIn.readByte();
+		if (val == CJVMTI_FRAME){
+			log.finest(("Reading frame"));
+		}else if (val == CJVMTI_JVMTI_ERROR) {
+			log.finest("No frame information!");
+			return;
+		}else{
+			log.finer("Error reading frame");
+			System.exit(0);
+		}
+		
+				
+				
+				long methodID = variablesIn.readLong();
+				String methodName = readCString(variablesIn);
+				log.log(Level.FINEST, "Method name is: " + methodName);
+				long declaringClass = variablesIn.readLong();
+				long cPos = variablesIn.getStreamPosition(); // Save where we are before reading in the
declaring class
+				JClass clazz = (JClass) nreadReference(declaringClass);
+				variablesIn.seek(cPos); // Return to our read position
+				
+				
+				byte depth = variablesIn.readByte();
 				if (depth == CJVMTI_LOCAL_NATIVECALL) {
-					log.log(Level.FINEST,"Native call");
-					in.seek(startPos + frameSize + 1);
-					continue;
+					log.log(Level.FINEST, "Native call");
+					JStackFrame jsf = new JStackFrame();
+					JLocation loc = new JLocation();
+					JMethod jm = model.getMethod(methodID);
+					loc.linenumber = -1;
+					loc.method = jm;
+					loc.setAddress(-1);
+					loc.filename = clazz.sourceFile;
+					if (loc.filename == null){
+						loc.filename = "nativeCall"; // ..
+					}
+					jsf.setLocation(loc);
+					t.addStackFrame(jsf);
+					return;
 				} else if (depth == CJVMTI_LOCAL_VARIABLE) {
-					log.log(Level.FINEST,"Local var");
+					log.log(Level.FINEST, "Local var");
 				} else if (depth == CJVMTI_JVMTI_ERROR) {
-					log.log(Level.FINEST,"Data unavailable");
-					in.seek(startPos + frameSize + 1);
-					continue;
+					log.log(Level.FINEST, "Data unavailable");
+					return;
 				}
 
-				long location = in.readLong();
-				log.log(Level.FINEST,"Location is " + location);
-				// now set up JStackFrame and location
+				long location = variablesIn.readLong();
+				log.log(Level.FINEST, "Location is " + location);
+				
+				
 				JStackFrame jsf = new JStackFrame();
 				JLocation loc = new JLocation();
 				jsf.setLocation(loc);
 				loc.setAddress(location);
+				
 				if (clazz != null) {
 					loc.filename = clazz.sourceFile;
 				}
+				
 				loc.method = model.getMethod(methodID);
-				// loc.linenumber = loc.method.getLineNumber(location);
-				loc.linenumber = (int) location;
-				log.log(Level.FINEST," Line number " + loc.linenumber + " to "
+				loc.linenumber = loc.method.getLineNumber(location);
+				log.log(Level.FINEST, " Line number " + loc.linenumber + " to "
 						+ location);
-				int varCount = in.readInt();
-				log.log(Level.FINEST,"vars: " + varCount);
+				int varCount = variablesIn.readInt();
+				int slots[] = new int[varCount];
+				long lvarReference[] = new long[varCount];
+				log.log(Level.FINEST, "vars: " + varCount);
+				
+				// Read in all the variable references
 				for (int i2 = 0; i2 < varCount; i2++) {
-					jsf.addVariable(nreadLocalVars());
+					slots[i2] = variablesIn.readInt();
+					lvarReference[i2] = variablesIn.readLong();
+				}
+				
+				// Follow all the variable references
+				for (int i2 = 0; i2 < varCount; i2++){
+					log.finest("Slot "+slots[i2]+" at "+Long.toHexString(lvarReference[i2]));
+					JLocalVariable jlv = new JLocalVariable();
+					jlv.slot = slots[i2];
+					long cpos = variablesIn.getStreamPosition();
+					jlv.value = nreadReference(lvarReference[i2]);
+					variablesIn.seek(cpos);
+					jsf.addVariable(jlv);
 				}
 
 				t.addStackFrame(jsf);
-				in.seek(startPos + frameSize + 1);
-			} else {
-				log.log(Level.FINEST,"Error " + in.getStreamPosition() + " "
-						+ in.readByte());
-			}
-		}
+			
+		
 
 	}
 
+	/**
+	 * Read monitor information
+	 * @param t Thread context
+	 * @throws IOException
+	 */
 	private void readMonitor(JThread t) throws IOException {
-		int ownedMonitorCount = in.readInt();
-		log.log(Level.FINEST,"Owned monitor count " + ownedMonitorCount);
-		if (ownedMonitorCount == 0)
-			return;
-
+		int ownedMonitorCount = variablesIn.readInt();
+		log.log(Level.FINEST, "Owned monitor count " + ownedMonitorCount);
+		if (ownedMonitorCount == 0) return;
 		for (int i = 0; i < ownedMonitorCount; i++) {
-			long objID = in.readLong();
-			nreadReference(objID);
+			log.finest("Monitor "+i+" of "+ ownedMonitorCount);
+			long objID = variablesIn.readLong();
+			long cPos = variablesIn.getStreamPosition(); // Save current read 
+			nreadReference(objID); // Follow reference
+			variablesIn.seek(cPos); // Return to read point
 			JMonitor monitor = model.getMonitor(objID);
 			monitor.setObject(monitor.id);
 			monitor.setOwner(t.id);
 		}
 	}
 
+	/**
+	 * Get contended monitor information
+	 * @param t Thread context
+	 * @throws IOException
+	 */
 	private void readContendedMonitor(JThread t) throws IOException {
-		long contendedObject = in.readLong();
-		log.log(Level.FINEST,"Contended object: "
+		long contendedObject = variablesIn.readLong();
+		log.log(Level.FINEST, "Contended object: "
 				+ Long.toHexString(contendedObject));
 		if (contendedObject != CJVMTI_NULL_OBJECT) {
 			JMonitor monitor = model.getMonitor(contendedObject);
+			long cPos = variablesIn.getStreamPosition();
 			nreadReference(contendedObject);
+			variablesIn.seek(cPos);
 			monitor.addWaiter(t.id);
 			monitor.setObject(contendedObject);
 		}
 	}
 
 	private void nreadThread(long id) throws IOException {
-		log.log(Level.FINEST,"Reading thread");
-		long size = in.readLong();
-		String threadname = readCString(in);
-		long objectRef = in.readLong();
+		variablesIn.seek(id);
+		if (variablesIn.read() == CJVMTI_THREAD){
+			log.finest("Reading thread information");
+		}else{
+			log.fine("Error");
+			System.exit(0);
+		}
+		String threadname = readCString(variablesIn);
+		log.finest("thread name "+threadname);
+		
+		long objectRef = variablesIn.readLong();
+		long cpos = variablesIn.getStreamPosition();
 		nreadReference(objectRef);
+		variablesIn.seek(cpos);
+		
 		JThread t = model.getThread(objectRef);
 		t.threadName = threadname;
-		log.log(Level.FINEST,t.threadName);
+		log.log(Level.FINEST, t.threadName);
 		t.groupID = 0;
-		t.priority = (short) in.readInt();
-		t.daemon = (short) in.readByte();
+		t.priority = (short) variablesIn.readInt();
+		t.daemon = (short) variablesIn.readByte();
 		readMonitor(t);
 		readContendedMonitor(t);
 
-		nreadFrames(t);
-		in.seek(id + size + 1);
+		
+		if (variablesIn.read()==CJVMTI_FRAME){
+			log.finest("Reading frames");
+		}else{
+			log.fine("Error reading frames");
+		}
+		int frameCount = variablesIn.readInt();
+		long frameRefs[] = new long[frameCount];
+		for (int i = 0; i < frameCount; i ++){
+			frameRefs[i] = variablesIn.readLong();
+		}
+		for (int i = 0; i < frameCount; i++){
+			log.finest("Reading frame "+i+" of "+frameCount+ " at "+Long.toHexString(frameRefs[i]));
+			nreadFrames(frameRefs[i], t);
+		}
 	}
-
+	
+	/**
+	 * Conveniance method for printing stream position on error
+	 * @param msg
+	 * @throws IOException
+	 */
 	private void error(String msg) throws IOException {
 		long offset = -1;
-		try {
-			offset = in.getStreamPosition();
-		} catch (IOException e) {
-
-		}
-		throw new IOException("at offset " + offset + ": " + msg);
+		throw new IOException("at offset "
+				+ Long.toHexString(variablesIn.getStreamPosition()) + ": " + msg);
 
 	}
 
-	class VariableValue {
-		String signature = null;
-	}
 
+	/**
+	 * Get java model 
+	 * @return JavaModel
+	 */
 	public Model getModel() {
 		return model;
 	}



Mime
View raw message