incubator-kato-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ccris...@apache.org
Subject svn commit: r754949 [4/5] - in /incubator/kato/trunk/import/org.apache.kato.tools.katoview: ./ .settings/ src/ src/com/ src/com/ibm/ src/com/ibm/dtfj/ src/com/ibm/dtfj/dtfjview/ src/com/ibm/dtfj/dtfjview/commands/ src/com/ibm/dtfj/dtfjview/commands/hel...
Date Mon, 16 Mar 2009 16:43:31 GMT
Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSymCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSymCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSymCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSymCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.infocommands;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Exceptions;
+import com.ibm.dtfj.image.CorruptData;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.image.DataUnavailable;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.image.ImageSection;
+import com.ibm.dtfj.image.ImageModule; 
+import com.ibm.dtfj.image.ImageAddressSpace;
+import com.ibm.dtfj.image.ImageProcess;
+
+public class InfoSymCommand extends Command{
+	
+	public InfoSymCommand(Output o){
+		super(o, "sym", "outputs a list of available modules",
+				"parameters: none\n\n" +
+				"for each process in the address spaces, outputs a list " +
+				"of module sections for each module with their start and " +
+				"end addresses, names, and sizes\n");
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		int asnum = 0;
+		Iterator itAddressSpace = loadedImage.getAddressSpaces();
+		
+		// iterate through the address spaces
+		while (itAddressSpace.hasNext()) {
+			ImageAddressSpace ias = (ImageAddressSpace)itAddressSpace.next();
+			out.print("\n\tlibraries for address space # " + asnum + "\n");
+			
+			Iterator itProcess = ias.getProcesses();
+			
+			// iterate through the processes
+			while (itProcess.hasNext())	{
+				ImageProcess ip = (ImageProcess)itProcess.next();
+				
+				out.print("\t process id: ");
+				try {
+					out.print(ip.getID());
+				} catch (DataUnavailable du) {
+					out.print(Exceptions.getDataUnavailableString());
+				} catch (CorruptDataException cde) {
+					out.print(Exceptions.getCorruptDataExceptionString());
+				}
+				out.print("\n\n");
+				
+				Iterator iLibs;
+				try {
+					iLibs = ip.getLibraries();
+				} catch (DataUnavailable du) {
+					iLibs = null;
+					out.println(Exceptions.getDataUnavailableString());
+				} catch (CorruptDataException cde) {
+					iLibs = null;
+					out.println(Exceptions.getCorruptDataExceptionString());
+				}
+				
+				// iterate through the libraries
+				while (null != iLibs && iLibs.hasNext()) {
+					Object next = iLibs.next();
+					if (next instanceof ImageModule) {
+						ImageModule imageModule = (ImageModule)next;
+						try {
+							out.print("\t  " + imageModule.getName());
+						} catch (CorruptDataException cde) {
+							out.print("\t  " + Exceptions.getCorruptDataExceptionString());
+						}
+						out.print(", sections:\n");
+
+						Iterator itSection = imageModule.getSections();
+					
+						// iterate through the library sections
+						while (itSection.hasNext()) {
+							next = itSection.next();
+							if (next instanceof ImageSection) {
+								ImageSection is = (ImageSection)next;
+								out.print("\t   0x" +
+									Long.toHexString(is.getBaseAddress().getAddress()) + " - 0x" +
+									Long.toHexString(is.getBaseAddress().getAddress() + is.getSize()));
+								out.print(", name: \"");
+								out.print(is.getName());
+								out.print("\", size: 0x");
+								out.print(Long.toHexString(is.getSize()));
+								out.print("\n");	
+							} else if (next instanceof CorruptData) {
+								// warn the user that this image section is corrupt
+								out.print("\t   <corrupt section encountered>\n");
+							} else {
+								// unexpected type in iterator
+								out.print("\t   <corrupt section encountered>\n");
+							}
+						}
+						out.print("\n");
+					
+					} else if (next instanceof CorruptData) {
+						CorruptData corruptObj = (CorruptData)next;
+						// warn the user that this image library is corrupt
+						out.print("\t  <corrupt library encountered: " + corruptObj.toString() + ">\n\n");
+					} else {
+						// unexpected type in iterator
+						out.print("\t  <corrupt library encountered>\n\n");
+					}
+				}
+			}
+			asnum++;
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSystemCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSystemCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSystemCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoSystemCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.infocommands;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Stack;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.image.DataUnavailable;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.runtime.ManagedRuntime;
+
+public class InfoSystemCommand extends Command {
+
+	public InfoSystemCommand(Output o){
+		super(o, "system", "displays information about the system the core dump is from",
+				"parameters: none\n\n" +
+				"prints the following information about the system the core " +
+				"dump is from:\n" +
+				"  - operating system\n" +
+				"  - amount of memory\n" +
+				"  - virtual machine(s) present\n"
+				);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties){
+		if (!args.isEmpty())
+		{
+			out.error("\"info system\" command does not take any parameters");
+		}
+		else
+		{
+			Iterator itRuntime = Utils.getRuntimes(loadedImage);
+			ManagedRuntime mr;
+			String output = "";
+			try {
+				output += "\nSystem:\t\t";
+				output += loadedImage.getSystemType() + "\n";
+				output += "System Memory:\t";
+				output += loadedImage.getInstalledMemory() + " bytes\n";
+				output += "Virtual Machine(s):\n";
+				
+				int count = 1;
+				while (itRuntime.hasNext()) {
+					mr = (ManagedRuntime)itRuntime.next();
+					output += "\tRuntime #" + count + ":\n\t\t";
+					output += mr.getVersion() + "\n";
+					count++;
+				}
+			} catch (DataUnavailable d) {
+				
+			} catch (CorruptDataException e) {
+				
+			}
+			
+			if (!output.equals(""))
+				out.println(output);
+			else
+				out.error("error occurred while processing \"info system\"");
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoThreadCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoThreadCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoThreadCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/infocommands/InfoThreadCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,611 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.infocommands;
+
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.Iterator;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Exceptions;
+import com.ibm.dtfj.dtfjview.commands.helpers.MonitorState;
+import com.ibm.dtfj.dtfjview.commands.helpers.StateToString;
+import com.ibm.dtfj.dtfjview.commands.helpers.ThreadData;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.CorruptData;
+import com.ibm.dtfj.image.DTFJException;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.image.ImageProcess;
+import com.ibm.dtfj.image.ImageRegister;
+import com.ibm.dtfj.image.ImageSection;
+import com.ibm.dtfj.image.ImageThread;
+import com.ibm.dtfj.image.ImageAddressSpace;
+import com.ibm.dtfj.image.ImageStackFrame;
+import com.ibm.dtfj.image.DataUnavailable;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.runtime.ManagedRuntime;
+import com.ibm.dtfj.java.JavaMonitor;
+import com.ibm.dtfj.java.JavaRuntime;
+import com.ibm.dtfj.java.JavaThread;
+import com.ibm.dtfj.java.JavaStackFrame;
+import com.ibm.dtfj.java.JavaLocation;
+import com.ibm.dtfj.java.JavaObject;
+
+public class InfoThreadCommand extends Command{
+	
+	private int pointerSize;
+	
+	public InfoThreadCommand(Output o){
+		super(o, "thread", "displays information about Java and native threads",
+				"parameters: none, \"*\", or thread name\n\n" +
+				"prints the following information about the current thread, " +
+				"all threads, or the specified thread, respectively:\n" +
+				" - thread id\n" +
+				" - registers\n" +
+				" - stack sections\n" +
+				" - thread frames: procedure name and base pointer\n" +
+				" - the thread properties\n" +
+				" - associated Java thread (if applicable):\n" +
+				"  - name of Java thread\n" +
+				"  - address of associated java.lang.Thread object\n" +
+				"  - current state according to JVMTI specification\n" +
+				"  - current state relative to java.lang.Thread.State\n" +
+				"  - the Java thread priority\n" +
+				"  - the monitor the thread is waiting to enter or waiting on notify\n" +
+				"  - thread frames: base pointer, method, and filename:line\n"
+				);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties){
+		if (args.isEmpty())
+		{
+			ImageAddressSpace ias = (ImageAddressSpace)properties.get("current_address_space");
+			String id;
+			
+			try {
+				ImageThread it = ias.getCurrentProcess().getCurrentThread();
+				if (null != it)
+					id = it.getID();
+				else
+				{
+					out.print("\n\tNo current (failing) thread, try specifying a native thread ID or '*'\n");
+					
+					ImageProcess ip = ias.getCurrentProcess();
+					if (ip!=null){
+						printThreadSummary(ip , out);
+					}
+					
+					return;
+				}
+			} catch (CorruptDataException e) {
+				out.error("exception encountered while getting information about " +
+						"current thread");
+				return;
+			}
+			args.push(id);
+		}
+
+		String param = (String)args.pop();
+		
+		if (!args.isEmpty())
+		{
+			out.error("\"info thread\" takes at most one parameter, which, if " +
+					"specified, must be a thread ID or \"*\"");
+			return;
+		}
+		
+		if (param.equals("*"))
+		{
+			out.print("\n");
+			printAddressSpaceInfo(loadedImage, out, null, getJavaThreads(loadedImage, null));
+			out.print("\n");
+		}
+		else
+		{
+			out.print("\n");
+			printAddressSpaceInfo(loadedImage, out, param, getJavaThreads(loadedImage, param));
+			out.print("\n");
+		}
+	}
+	
+	private void printAddressSpaceInfo(Image loadedImage, Output out, String id, Map threads)
+	{
+		Iterator itAddressSpace;
+		ImageAddressSpace ias;
+		int asnum = 0;
+		
+		itAddressSpace = loadedImage.getAddressSpaces();
+		while (itAddressSpace.hasNext()) {
+			ias = (ImageAddressSpace)itAddressSpace.next();
+			out.print("\n\tnative threads for address space # " + asnum + "\n");
+			printProcessInfo(ias, out, id, threads);
+			asnum++;
+		}
+		
+		if (!threads.isEmpty()) {
+			out.print("\n\tJava threads not associated with known native threads:\n\n");
+			
+			// retrieve any orphaned Java threads from the hashmap
+			ArrayList ta = (ArrayList)threads.remove(null);
+			if ( ta != null ) {
+				for ( int i=0; i<ta.size(); i++) {
+					ThreadData td = (ThreadData)ta.get(i);
+					printJavaThreadInfo(out, td.getThread(), getMonitors(td.getRuntime()));
+				}
+			}
+		}
+	}
+	
+	private void printProcessInfo(ImageAddressSpace ias, Output out, String id, Map threads)
+	{
+		Iterator itProcess;
+		ImageProcess ip;
+		boolean found = false;
+		
+		itProcess = ias.getProcesses();
+		while (itProcess.hasNext())
+		{
+			ip = (ImageProcess)itProcess.next();
+			pointerSize = ip.getPointerSize();
+			
+			out.print("\t process id: ");
+			try {
+				out.print(ip.getID());
+			} catch (DataUnavailable d) {
+				out.print(Exceptions.getDataUnavailableString());
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			out.print("\n\n");
+			found = printThreadInfo(ip, out, id, threads);
+		}
+		
+		if (!found)
+		{
+			out.print("\t no native threads found with specified id\n");
+		}
+	}
+	
+	private boolean printThreadInfo(ImageProcess ip, Output out, String id, Map threads)
+	{
+		Iterator itThread;
+		ImageThread it;
+		boolean found = false;
+		
+		itThread = ip.getThreads();
+		while (itThread.hasNext())
+		{
+			Object next = itThread.next();
+			if (next instanceof CorruptData) {
+				continue;
+			}
+			it = (ImageThread)next;
+			String currID;
+			
+			try {
+				currID = it.getID();
+			} catch (CorruptDataException e) {
+				currID = null;
+			}
+			
+			if (null == id || id.equals(currID))
+			{
+				out.print("\t  thread id: ");
+				out.print(currID);
+				out.print("\n");
+				printRegisters(it);
+				
+				out.print("\t   stack sections:");
+				out.print("\n");
+				
+				Iterator itStackSection = it.getStackSections();
+				while (itStackSection.hasNext()) {
+					Object nextStackSection = itStackSection.next();
+					if (nextStackSection instanceof CorruptData) {
+						out.print("\t    " + Exceptions.getCorruptDataExceptionString() + "\n");
+						continue;
+					}
+					ImageSection is = (ImageSection)nextStackSection;
+					printStackSection(is);
+				}
+				printStackFrameInfo(it, out);
+								
+				out.print("\t   properties:");
+				out.print("\n");
+				printProperties(it, out);
+				out.print("\n");
+				
+				out.print("\t   associated Java thread: ");
+				ThreadData td = (ThreadData)threads.remove(currID);
+				if (null != td) {
+					out.print("\n");
+					printJavaThreadInfo(out, td.getThread(), getMonitors(td.getRuntime()));
+				} else {
+					out.print("<no associated Java thread>\n");
+				}
+				out.print("\n");
+				found = true;
+			}
+		}
+		
+		return found;
+	}
+	
+	public void printRegisters(ImageThread it)
+	{
+		out.print("\t   registers:");
+		out.print("\n");
+		
+		int count = 0;
+		Iterator itImageRegister = it.getRegisters();
+		while (itImageRegister.hasNext())
+		{
+			if (count % 4 == 0)
+			{
+				if (0 != count)
+					out.print("\n");
+				out.print("\t    ");
+			}
+			ImageRegister ir = (ImageRegister)itImageRegister.next();
+			printRegisterInfo(ir);
+			count++;
+		}
+		out.print("\n");
+	}
+	
+	public void printRegisterInfo(ImageRegister ir)
+	{
+		out.print(Utils.padWithSpaces(ir.getName(), 8) + " = ");
+		try {
+			out.print(toAdjustedHex(ir.getValue().longValue()));
+		} catch (CorruptDataException e) {
+			out.print(Exceptions.getCorruptDataExceptionString());
+		}
+		out.print("   ");
+	}
+	
+	public void printStackSection(ImageSection is)
+	{
+		long startAddr = is.getBaseAddress().getAddress();
+		long size = is.getSize();
+		long endAddr = startAddr + size;
+
+		out.print("\t    ");
+		out.print(Utils.toHex(startAddr));
+		out.print(" to ");
+		out.print(Utils.toHex(endAddr));
+		out.print(" (length ");
+		out.print(Utils.toHex(size));
+		out.print(")\n");
+	}
+	
+	private void printStackFrameInfo(ImageThread it, Output out)
+	{
+		Iterator itStackFrame;
+		ImageStackFrame isf;
+		
+		try {
+			itStackFrame = it.getStackFrames();
+		} catch (DataUnavailable d) {
+			out.print("\t   error with stack frames: " + Exceptions.getDataUnavailableString() + "\n");
+			return;
+		}
+		
+		out.print("\t   stack frames:");
+		out.print("\n");
+
+		while (itStackFrame.hasNext())
+		{
+			isf = (ImageStackFrame)itStackFrame.next();
+			out.print("\t    bp: ");
+			try {
+				out.print(toAdjustedHex(isf.getBasePointer().getAddress()));
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			out.print(" pc: ");
+			try {
+				out.print(toAdjustedHex(isf.getProcedureAddress().getAddress()));
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			out.print(" ");
+			try {
+				out.print(isf.getProcedureName());
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			out.print("\n");
+		}
+	}
+	
+	private Map getJavaThreads(Image loadedImage, String id)
+	{
+		ManagedRuntime mr;
+		Iterator itRuntime = Utils.getRuntimes(loadedImage);
+		Map threads = new HashMap();
+		
+		while (itRuntime.hasNext()) {
+			mr = (ManagedRuntime)itRuntime.next();
+			if (mr instanceof JavaRuntime)
+			{
+				JavaRuntime jr = (JavaRuntime)mr;
+				Iterator itThread = jr.getThreads();
+				
+				while (itThread.hasNext()) {
+					JavaThread jt = (JavaThread)itThread.next();
+					String currID;
+
+					try {
+						ImageThread it = jt.getImageThread();  
+						currID = it.getID();
+					} catch (DTFJException e) {
+						currID = null;
+					}
+					
+					if (null == id) {
+						// thread id set to null means we want all the threads, and we
+						// save all orphaned java threads in a list within the hashmap
+						if ( null == currID) {
+							if (threads.containsKey(null)) {
+								ArrayList ta = (ArrayList)threads.get(null);
+								ta.add(new ThreadData(jt, jr));
+						    } else {
+						    	ArrayList ta = new ArrayList(1);
+						    	ta.add(new ThreadData(jt, jr));
+							    threads.put(null, ta);
+						    }
+						} else {
+							threads.put(currID, new ThreadData(jt, jr));
+						}
+					} else if (id.equals(currID)) {
+						// we just want the specific java thread that matches the native one
+						threads.put(currID, new ThreadData(jt, jr));
+					}
+				}
+			}
+		}
+		
+		return threads;
+	}
+	
+	private Map getMonitors(JavaRuntime jr)
+	{
+		Map monitors = new HashMap();
+		
+		Iterator itMonitor = jr.getMonitors();
+		while (itMonitor.hasNext()) {
+			JavaMonitor jm = (JavaMonitor)itMonitor.next();
+			Iterator itEnterWaiter = jm.getEnterWaiters();
+			while (itEnterWaiter.hasNext()) {
+				JavaThread jt = (JavaThread)itEnterWaiter.next();
+				monitors.put(jt, new MonitorState(jm, MonitorState.WAITING_TO_ENTER));
+			}
+			Iterator itNotifyWaiter = jm.getNotifyWaiters();
+			while (itNotifyWaiter.hasNext()) {
+				JavaThread jt = (JavaThread)itNotifyWaiter.next();
+				monitors.put(jt, new MonitorState(jm, MonitorState.WAITING_TO_BE_NOTIFIED_ON));
+			}
+		}
+		
+		return monitors;
+	}
+	
+	private void printJavaThreadInfo(Output out, JavaThread jt, Map monitors)
+	{
+		out.print("\t    name:          ");
+		try {
+			out.print(jt.getName());
+		} catch (CorruptDataException e) {
+			out.print(Exceptions.getCorruptDataExceptionString());
+		}
+		out.print("\n");
+		
+		out.print("\t    Thread object: ");
+		try {
+			JavaObject threadObj = jt.getObject();
+			if (null == threadObj) {
+				out.print("<no associated Thread object>");
+			} else {
+				out.print(Utils.toHex(threadObj.getID().getAddress()));
+			}
+		} catch (CorruptDataException cde) {
+			out.print(Exceptions.getCorruptDataExceptionString());
+		}
+		out.print("\n");
+		
+		out.print("\t    JVMTI state:   ");
+		try {
+			out.print(StateToString.getJVMTIStateString(jt.getState()));
+		} catch (CorruptDataException cde) {
+			out.print(Exceptions.getCorruptDataExceptionString());
+		}
+		out.print("\n");
+
+		out.print("\t    Thread.State:  ");
+		try {
+			out.print(StateToString.getThreadStateString(jt.getState()));
+		} catch (CorruptDataException cde) {
+			out.print(Exceptions.getCorruptDataExceptionString());
+		}
+		out.print("\n");
+		
+		out.print("\t    Priority:      ");
+		try {
+			Integer pri = new Integer(jt.getPriority());
+			out.print(pri.toString());
+		} catch (CorruptDataException e) {
+			out.print(Exceptions.getCorruptDataExceptionString());
+		}
+		out.print("\n");
+		
+		out.print("\t    monitor:       ");
+		MonitorState ms = (MonitorState)monitors.get(jt);
+		if (null == ms) {
+			out.print("<no associated monitor>");
+		} else {
+			try {
+				String name = ms.getMonitor().getName();
+				if (name.equals("")) {
+					name = "<unnamed>";
+				}
+				out.print(ms.getStatusString() + " \"" + name + "\"");
+			} catch (CorruptDataException cde) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			JavaObject jo = ms.getMonitor().getObject();
+			if (null == jo) {
+				// working with a raw monitor
+				out.print(" with ID ");
+				// FIXME: once DTFJ implements IDs, output ID
+				out.print("<unavailable>");
+			} else {
+				// working with a Java monitor
+				out.print(" with object ");
+				out.print(Utils.toHex(jo.getID().getAddress()));
+			}
+		}
+		out.print("\n");
+		
+		out.print("\t    thread frames: ");
+		printJavaStackFrameInfo(jt, out);
+		out.print("\n");
+	}
+	
+	private void printJavaStackFrameInfo(JavaThread jt, Output out)
+	{
+		Iterator itStackFrame;
+		JavaStackFrame jsf;
+		JavaLocation jl;
+
+		itStackFrame = jt.getStackFrames();
+		if (!itStackFrame.hasNext()) {
+			out.print("<no frames to print>\n");
+			return;
+		} else {
+			out.print("\n");
+		}
+		while (itStackFrame.hasNext()) {
+			// this iterator can contain JavaStackFrame or CorruptData objects
+			Object next = itStackFrame.next();
+			if (next instanceof CorruptData) {
+				out.print("\t     " + Exceptions.getCorruptDataExceptionString() + "\n");
+				return;
+			} else {
+			    jsf = (JavaStackFrame)next;
+			}
+			try {
+				jl = jsf.getLocation();
+			} catch (CorruptDataException e) {
+				out.print("\t     " + Exceptions.getCorruptDataExceptionString()+ "\n");
+				return;
+			}
+			
+			out.print("\t     bp: ");
+			try {
+				out.print(toAdjustedHex(jsf.getBasePointer().getAddress()));
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			
+			out.print("    method: ");
+			try {
+				String signature = jl.getMethod().getSignature();
+				out.print(Utils.getReturnValueName(signature) + " " +
+						jl.getMethod().getDeclaringClass().getName() + "." +
+						jl.getMethod().getName() +
+						Utils.getMethodSignatureName(signature)
+						);
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			} catch (DataUnavailable e) {
+				out.print(Exceptions.getDataUnavailableString());
+			}
+
+			out.print("    filename:line: ");
+			try {
+				out.print(jl.getFilename());
+			} catch (DataUnavailable d) {
+				out.print(Exceptions.getDataUnavailableString());
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			out.print(":");
+			try {
+				out.print(Integer.toString(jl.getLineNumber()));
+			} catch (DataUnavailable d) {
+				out.print(Exceptions.getDataUnavailableString());
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			out.print("\n");
+		}
+	}
+
+	private String toAdjustedHex(long l)
+	{
+		if (pointerSize > 32) {
+			return "0x" + Utils.toFixedWidthHex(l);
+		} else if (31 == pointerSize) {
+			return "0x" + Utils.toFixedWidthHex((int)(l & (((long)1) << pointerSize) - 1));
+		} else {
+			return "0x" + Utils.toFixedWidthHex((int)l);
+		}
+	}
+	
+	private void printThreadSummary(ImageProcess ip, Output out)
+	{
+		// Prints a summary list of native thread IDs
+		int count = 0;
+		Iterator itThread = ip.getThreads();
+			
+		while (itThread.hasNext()) {
+			Object next = itThread.next();
+			if (next instanceof CorruptData)
+		        continue;
+			ImageThread it = (ImageThread)next;
+			
+			if (count % 8 == 0) {
+				if (0 == count)
+					out.print("\n\n\tNative thread IDs for current process:");
+				out.print("\n\t ");
+			}
+			
+			try {
+				out.print(Utils.padWithSpaces(it.getID(), 8));
+			} catch (CorruptDataException e) {
+				out.print(Exceptions.getCorruptDataExceptionString());
+			}
+			count++;
+		}
+		out.print("\n");
+	}
+	private void printProperties(ImageThread it, Output out)
+	{
+		Properties jtp = it.getProperties();
+		Enumeration keys = jtp.propertyNames();
+		while (keys.hasMoreElements())
+		{
+			String propertyKey = keys.nextElement().toString();
+			out.print("\t    " + propertyKey + ": " + jtp.getProperty(propertyKey));
+			out.print("\n");
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetHeapdumpCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetHeapdumpCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetHeapdumpCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetHeapdumpCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,102 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.setcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.heapdump.HeapDumpSettings;
+import com.ibm.dtfj.image.Image;
+
+public class SetHeapdumpCommand extends Command
+{
+	private static final String SHORT_DESCRIPTION = "configures heapdump format, filename and multiple heap support";
+	private static final String COMMAND_NAME = "heapdump";
+	private static final String LONG_DESCRIPTION = "parameters: [phd|txt], [file <filename>], [multiplefiles on|off]\n\n" 
+		+ "[phd|txt] - the format for the heapdump. Default: phd.\n"
+		+ "[file <filename>] - the file to write the heapdump to. Default: <core file name>.phd or <core file name>.txt.\n\n"
+		+ "[multiplefiles on|off] - if set to on, multiple heaps are written to separate heapdumps. If set to off, multiple heaps are written " +
+				"to the same heapdump. Default: off.\n\n"
+		+ "Use \"show heapdump\" to see current settings.\n";
+
+	public SetHeapdumpCommand(Output o)
+	{
+		super(o, COMMAND_NAME, SHORT_DESCRIPTION, LONG_DESCRIPTION);
+	}
+
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		if(args.isEmpty()) {
+			out.error("\"set heapdump\" requires at least one parameter\n");
+			return;
+		}
+		
+		String arg1 = (String) args.pop();
+		
+		if(arg1.equalsIgnoreCase("phd")) {
+			HeapDumpSettings.setPHDHeapDumps(properties);
+			
+			out.print("Heapdump format set to PHD\n");
+		} else if (arg1.equalsIgnoreCase("txt")){
+			HeapDumpSettings.setClassicHeapDumps(properties);
+			
+			out.print("Heapdump format set to classic (TXT)\n");
+		} else if (arg1.equalsIgnoreCase("file")) {
+			if(args.isEmpty()) {
+				out.error("\"set heapdump file\" requires at least one parameter\n");
+				return;
+			}
+			
+			if(args.size() > 1) {
+				out.error("\"set heapdump file\" accepts 1 parameter. You supplied " + args.size() + ".\n");
+				return;
+			}
+			
+			String filename = (String) args.pop();
+			
+			String originalFileName = HeapDumpSettings.getFileName(properties);
+			
+			HeapDumpSettings.setFileName(filename, properties);
+			
+			out.print("Heapdump file changed from " + originalFileName + " to " + filename + "\n");
+		} else if (arg1.equalsIgnoreCase("multiplefiles")) {
+			if(args.isEmpty()) {
+				out.error("\"set heapdump multiplefiles\" requires one parameter: on or off\n");
+				return;
+			}
+			
+			if(args.size() > 1) {
+				out.error("\"set heapdump multiplefiles\" requires one parameter: on or off. You suppled " + args.size() + " parameters\n");
+				return;
+			}
+			
+			String setting = (String) args.pop();
+			
+			if(setting.equalsIgnoreCase("on")) {
+				out.println("Multiple heaps will be dumped into multiple heapdumps");
+				HeapDumpSettings.setMultipleHeapsMultipleFiles(properties);
+			} else if (setting.equalsIgnoreCase("off")) {
+				out.println("Multiple heaps will be dumped into a single heapdump");
+				HeapDumpSettings.setMultipleHeapsSingleFile(properties);
+			} else {
+				out.error("Unrecognised setting: " + setting + ". Valid options are \"on\" or \"off\"\n");
+			}
+		} else {
+			out.error(arg1 + " is not a valid parameter for the \"set heapdump\" command");
+		}
+	}
+
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetLoggingCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetLoggingCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetLoggingCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/setcommands/SetLoggingCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.setcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+
+import com.ibm.dtfj.dtfjview.FileOutputChannel;
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.Image;
+
+public class SetLoggingCommand extends Command {
+
+	public SetLoggingCommand(Output o){
+		super(o, "logging", "configures several logging-related parameters, " +
+				"starts/stops logging",
+				
+				"parameters: [on|off], file <filename>, overwrite [on|off], " +
+				"redirect [on|off]\n\n" +
+				"- [on|off] - turns logging on or off (default: off)\n" +
+				"- file <filename> - sets the file to log to; this will be relative " +
+				"to the directory returned by the \"pwd\" command unless an " +
+				"absolute path is specified; if the file is set while logging is on, " +
+				"the change will take effect the next time logging is started " +
+				"(default: <not set>)\n" +
+				"- overwrite [on|off] - turns overwriting of the specified log file " +
+				"on or off (off means that the log file will be appended to); if " +
+				"this is on, the log file will be cleared every time \"set logging " +
+				"on\" is run (default: off)\n" +
+				"- redirect [on|off] - turns redirecting to file on or off (on means " +
+				"that non-error output goes only to the log file (not the console) " +
+				"when logging is on, off means that non-error output goes to both " +
+				"the console and the log file); redirection must be turned off " +
+				"logging can be turned off (default: off)\n"
+		);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties){
+		if (args.isEmpty())
+		{
+			out.error("\"set logging\" requires at least one parameter");
+			return;
+		}
+
+		String arg1 = (String)args.pop();
+		if (arg1.equals("on"))
+		{
+			if (!args.isEmpty())
+			{
+				out.error("\"set logging on\" does not take any additional parameters");
+				return;
+			}
+			
+			String logging = (String)properties.get("set_logging");
+			if (null != logging && logging.equals("on"))
+			{
+				out.error("logging is already turned on");
+				return;
+			}
+			
+			String filename = (String)properties.get("set_logging_file");
+			if (null == filename)
+			{
+				out.error("log file not yet set; set log file with \"set logging file <filename>\"");
+				return;
+			}
+			
+			File logfile = Utils.absPath(properties, filename);
+			String filepath = logfile.getPath();
+			FileWriter f;
+			try {
+				f = new FileWriter(logfile, appendToFile(properties));
+			} catch (IOException e) {
+				f = null;
+				out.error("IOException encountered while opening file \"" + filepath +
+						"\"; make sure the file can be written to");
+				return;
+			}
+
+			out.addChannel(new FileOutputChannel(f), true);
+			properties.put("set_logging", "on");
+			properties.put("current_logging_file", filepath);
+			
+			out.print("\n");
+			out.print("\tlogging turned on; outputting to \"" + filepath + "\"");
+			out.print("\n\n");
+		}
+		else if (arg1.equals("off"))
+		{
+			if (!args.isEmpty())
+			{
+				out.error("\"set logging off\" does not take any additional parameters");
+				return;
+			}
+
+			String redirect = (String)properties.get("set_logging_redirect");
+			if (null != redirect && redirect.equals("on"))
+			{
+				out.error("cannot turn off logging when redirecting to only a file is " +
+						"turned on; turn off redirecting to only a file and try again");
+				return;
+			}
+
+			String logging = (String)properties.get("set_logging");
+			if (null == logging || logging.equals("off"))
+			{
+				out.error("logging is already turned off");
+				return;
+			}
+			
+			properties.put("set_logging", "off");
+			
+			out.print("\n");
+			out.print("\tlogging turned off; was logging to \"" +
+					(String)properties.get("current_logging_file") + "\"");
+			out.print("\n\n");
+			
+			out.removeFileChannel();
+			properties.put("current_logging_file", null);
+		}
+		else if (arg1.equals("file"))
+		{
+			if (args.isEmpty())
+			{
+				out.error("\"set logging file\" requires a filename parameter");
+				return;
+			}
+
+			String filename = (String)args.pop();
+			
+			if (!args.isEmpty())
+			{
+				out.error("\"set logging file\" takes exactly one parameter");
+				return;
+			}
+			
+			String oldFile = (String)properties.put("set_logging_file", filename);
+			
+			out.print("\n");
+			if (null == oldFile) {
+				out.print("\tlog file set to \"" + filename + "\"");
+			} else {
+				out.print("\tlog file changed from \"" + oldFile + "\" to \"" + filename + "\"");
+			}
+			out.print("\n\n");
+		}
+		else if (arg1.equals("overwrite"))
+		{
+			if (args.isEmpty())
+			{
+				out.error("\"set logging overwrite\" requires on/off parameter");
+				return;
+			}
+
+			String param = (String)args.pop();
+			
+			if (!args.isEmpty())
+			{
+				out.error("\"set logging overwrite\" takes exactly one parameter");
+				return;
+			}
+			
+			if (param.equals("on"))
+			{
+				String oldParam;
+				oldParam = (String)properties.put("set_logging_overwrite", "on");
+				
+				if (null == oldParam || oldParam.equals("off"))
+				{
+					out.print("\n");
+					out.print("\toverwriting of log file option changed from \"off\" to \"on\"");
+					out.print("\n\n");
+				}
+				else
+				{
+					out.print("\n");
+					out.print("\toverwriting of log file option not changed (already \"on\")");
+					out.print("\n\n");
+				}
+			}
+			else if (param.equals("off"))
+			{
+				String oldParam;
+				oldParam = (String)properties.put("set_logging_overwrite", "off");
+				
+				if (null == oldParam || oldParam.equals("off"))
+				{
+					out.print("\n");
+					out.print("\toverwriting of log file option not changed (already \"off\")");
+					out.print("\n\n");
+				}
+				else
+				{
+					out.print("\n");
+					out.print("\toverwriting of log file option changed from \"on\" to \"off\"");
+					out.print("\n\n");
+				}
+			}
+			else
+			{
+				out.error("parameter for \"set logging overwrite\" must be \"on\" or \"off\"");
+				return;
+			}
+		}
+		else if (arg1.equals("redirect"))
+		{
+			if (args.isEmpty())
+			{
+				out.error("\"set logging redirect\" requires on/off parameter");
+				return;
+			}
+
+			String param = (String)args.pop();
+			
+			if (!args.isEmpty())
+			{
+				out.error("\"set logging redirect\" takes exactly one parameter");
+				return;
+			}
+
+			if (param.equals("on"))
+			{
+				String logging = (String)properties.get("set_logging");
+				if (null == logging || logging.equals("off"))
+				{
+					out.error("cannot redirect to only a file because logging is off; " +
+							"turn logging on and try again");
+					return;
+				}
+				
+				String oldParam;
+				oldParam = (String)properties.put("set_logging_redirect", "on");
+				
+				if (null == oldParam || oldParam.equals("off"))
+				{
+					out.print("\n");
+					out.print("\tredirecting to file only option changed from \"off\" to \"on\"");
+					out.print("\n\n");
+					out.setConsoleNoPrint(true);
+				}
+				else
+				{
+					out.print("\n");
+					out.print("\tredirecting to file only option not changed (already \"on\")");
+					out.print("\n\n");
+				}
+			}
+			else if (param.equals("off"))
+			{
+				String oldParam;
+				oldParam = (String)properties.put("set_logging_redirect", "off");
+				
+				if (null == oldParam || oldParam.equals("off"))
+				{
+					out.print("\n");
+					out.print("\tredirecting to file only option not changed (already \"off\")");
+					out.print("\n\n");
+				}
+				else
+				{
+					out.setConsoleNoPrint(false);
+					out.print("\n");
+					out.print("\tredirecting to file only option changed from \"on\" to \"off\"");
+					out.print("\n\n");
+				}
+			}
+			else
+			{
+				out.error("parameter for \"set logging redirect\" must be \"on\" or \"off\"");
+				return;
+			}
+		}
+		else
+		{
+			out.error("\"" + arg1 + "\" is not a valid parameter for the \"set logging\" command");
+			return;
+		}
+	}
+	
+	private boolean appendToFile(HashMap properties)
+	{
+		String append = (String)properties.get("set_logging_overwrite");
+		if (append == null || !append.equals("on"))
+			return true;
+		else
+			return false;
+	}
+
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowHeapdumpCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowHeapdumpCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowHeapdumpCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowHeapdumpCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,52 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.showcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.heapdump.HeapDumpSettings;
+import com.ibm.dtfj.image.Image;
+
+public class ShowHeapdumpCommand extends Command
+{
+	public static final String COMMAND_NAME = "heapdump";
+	public static final String COMMAND_DESCRIPTION = "displays heapdump settings";
+	public static final String LONG_DESCRIPTION = "Parameters:none\n\n"
+		+ "Prints heapdump format and file name.\n"
+		+ "Use \"set heapdump\" to change settings\n";
+
+	public ShowHeapdumpCommand(Output o) {
+		super(o,COMMAND_NAME,COMMAND_DESCRIPTION,LONG_DESCRIPTION);
+	}
+
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		if(! args.isEmpty()) {
+			out.error("\"show heapdump\" does not take any parameters.");
+			return;
+		}
+		
+		out.print("Heapdump Settings:\n\n");
+		
+		out.print("\tFormat: " + (HeapDumpSettings.areHeapDumpsPHD(properties) ? "PHD" : "Classic (TXT)") + "\n");
+		out.print("\tFile Name: " + HeapDumpSettings.getFileName(properties) + "\n");
+		out.print("\tMultiple heaps will be written to " 
+				+ (HeapDumpSettings.multipleHeapsInMultipleFiles(properties) ? "multiple files":"a single file") 
+				+ "\n");
+	}
+	
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowLoggingCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowLoggingCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowLoggingCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/showcommands/ShowLoggingCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.showcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.image.Image;
+
+public class ShowLoggingCommand extends Command {
+
+	public ShowLoggingCommand(Output o){
+		super(o, "logging", "displays the current values of logging settings",
+				"parameters: none\n\n" +
+				"outputs following values, which are generally set by the \"set " +
+				 "logging\" command:\n" +
+				" set_logging = [on|off]\n" +
+				" set_logging_file = <filename>\n" +
+				" set_logging_overwrite = [on|off]\n" +
+				" set_logging_redirect = [on|off]\n" +
+				" current_logging_file = <filename> - file that is currently being " +
+				 "logged to; could be different than set_logging_file if that value " +
+				 "was changed after logging was started"
+				);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties){
+		if (!args.isEmpty())
+		{
+			out.error("\"show logging\" does not take any parameters");
+			return;
+		}
+		
+		String fileVal = (String)properties.get("set_logging_file");
+		if (null == fileVal)
+			fileVal = "<not set>";
+		else
+			fileVal = "\"" + fileVal + "\"";
+		
+		String currentFileVal = (String)properties.get("current_logging_file");
+		if (null == currentFileVal)
+			currentFileVal = "<not currently logging>";
+		else
+			currentFileVal = "\"" + currentFileVal + "\"";
+
+		out.print("\n");
+		printKeyVal(properties, "set_logging");
+		out.println("\t" + "set_logging_file" + " = " + fileVal);
+		printKeyVal(properties, "set_logging_overwrite");
+		printKeyVal(properties, "set_logging_redirect");
+		out.print("\n");
+		out.println("\t" + "current_logging_file" + " = " + currentFileVal);
+			
+		out.print("\n");
+	}
+	
+	private void printKeyVal(HashMap properties, String key)
+	{
+		out.println("\t" + key + " = " + getVal(properties, key));
+	}
+	
+	private String getVal(HashMap properties, String key)
+	{
+		String val = (String)properties.get(key);
+
+		if (null == val)
+			return "off";
+		else
+			return val;
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XDCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XDCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XDCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XDCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.xcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.Iterator;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.image.ImageAddressSpace;
+import com.ibm.dtfj.image.ImagePointer;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.image.MemoryAccessException;
+
+public class XDCommand extends Command {
+
+	public XDCommand(Output o){
+		super(o, "d", "displays the integer at the specified address",
+				"parameters: 0x<addr>\n\n" +
+				"Displays the integer at the specified address, adjusted for the " +
+				"endianness of the architecture this dump file is from.\n\n" +
+				"Note: This command uses the number of items and unit size passed to " +
+				"it by the \"x/\" command.\n"
+		);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		int numUnits = ((Integer)args.pop()).intValue();
+		int unitSize = ((Integer)args.pop()).intValue();
+		
+		if (args.isEmpty())
+		{
+			out.error("\"x/d\" command takes exactly one parameter");
+			return;
+		}
+
+		String param = (String)args.pop();
+		if (!args.isEmpty())
+		{
+			out.error("\"x/d\" only takes one parameter");
+			return;
+		}
+		Long address;
+		
+		address = Utils.longFromStringWithPrefix(param);
+		if (null == address)
+		{
+			out.error("invalid hex address specified; address must be specified as "
+					+ "\"0x<hex_address>\"");
+			return;
+		}
+
+		out.print("\n");
+		
+		for (int index = 0; index < numUnits; index++)
+		{
+			boolean found = false;
+			Iterator itImageAddressSpace = loadedImage.getAddressSpaces();
+			long currAddr = address.longValue() + (index * unitSize);
+			
+			out.print("\t");
+			out.print(Utils.toHex(currAddr));
+			out.print(": ");
+			
+			while (itImageAddressSpace.hasNext() && !found)
+			{
+				ImageAddressSpace ias = (ImageAddressSpace)itImageAddressSpace.next();
+				ImagePointer ip = ias.getPointer(currAddr);
+				
+				byte b = 0;
+				short s = 0;
+				int i = 0;
+				long l = 0;
+				try {
+					switch (unitSize)
+					{
+					case 1:
+						b = ip.getByteAt(0);
+						break;
+					case 2:
+						s = ip.getShortAt(0);
+						break;
+					case 4:
+						i = ip.getIntAt(0);
+						break;
+					case 8:
+						l = ip.getLongAt(0);
+						break;
+					}
+					
+					found = true;
+				} catch (CorruptDataException e) {
+					found = false;
+				} catch (MemoryAccessException e) {
+					found = false;
+				}
+
+				if (found)
+				{
+					switch (unitSize)
+					{
+					case 1:
+						out.print(Byte.toString(b));
+						break;
+					case 2:
+						out.print(Short.toString(s));
+						break;
+					case 4:
+						out.print(Integer.toString(i));
+						break;
+					case 8:
+						out.print(Long.toString(l));
+						break;
+					}
+				}
+			}
+			
+			if (!found)
+			{
+				out.print("<address not found in any address space>");
+			}
+			out.print("\n");
+		}
+		
+		out.print("\n");
+	}
+	
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XJCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XJCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XJCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XJCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,306 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.xcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.Iterator;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.ClassOutput;
+import com.ibm.dtfj.dtfjview.commands.helpers.Exceptions;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.java.JavaRuntime;
+import com.ibm.dtfj.java.JavaHeap;
+import com.ibm.dtfj.java.JavaObject;
+import com.ibm.dtfj.java.JavaClass;
+import com.ibm.dtfj.runtime.ManagedRuntime;
+
+public class XJCommand extends Command {
+
+	public XJCommand(Output o){
+		super(o, "j", "displays information about a particular object or all " +
+				"objects of a class",
+				
+				"parameters: 0x<object_addr>, <class_name>\n\n" +
+				"If given class name, all static fields with their values will be " +
+				"printed, followed by all objects of that class with their fields " +
+				"and values.\n\n" +
+				"If given an object address (in hex), static fields for that object's " +
+				"class will not be printed; the other fields and values of that object " +
+				"will be printed along with its address.\n\n" +
+				"Note: this command ignores the number of items and unit size passed " +
+				"to it by the \"x/\" command.\n"
+		);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		args.pop();	// pop and discard number of units to display
+		args.pop();	// pop and discard unit size
+		
+		boolean supers = false;
+		
+		if (args.isEmpty())
+		{
+			out.error("\"x/j\" command requires one or two parameters");
+			return;
+		}
+		else
+		{
+			String param = (String)args.pop();
+			Long objAddress;
+			String objName;
+			
+			objAddress = Utils.longFromStringWithPrefix(param);
+			if (null == objAddress)
+			{
+				objName = param;
+				
+				if (!args.isEmpty())
+				{
+					String option = (String)args.pop();
+					if (option.equals("super"))
+					{
+						supers = true;
+					}
+					else if (option.equals("nosuper"))
+					{
+						supers = false;
+					}
+					else
+					{
+						out.error("second parameter for \"x/j\" must be \"super\" or" +
+								" \"nosuper\"");
+						return;
+					}
+				}
+			}
+			else
+			{
+				objName = null;
+			}
+			
+			if (!args.isEmpty())
+			{
+				out.error("\"x/j\" takes at most one parameter if address is specified" +
+						" or two parameters if class name is specified");
+				return;
+			}
+			
+			printRuntimeObjects(loadedImage, objAddress, objName, out, supers);
+		}
+	}
+	
+	private void printRuntimeObjects(Image loadedImage, Long objAddress, String objName,
+			Output out, boolean supers)
+	{
+		ManagedRuntime mr;
+		Iterator itRuntime = Utils.getRuntimes(loadedImage);
+		int count = 1;
+
+		out.print("\n");
+		while (itRuntime.hasNext()) {
+			mr = (ManagedRuntime)itRuntime.next();
+			if (mr instanceof JavaRuntime)
+			{
+				out.print("\truntime #" + count + " - version: ");
+				try {
+					out.print(mr.getVersion());
+				} catch (CorruptDataException e) {
+					out.print(Exceptions.getCorruptDataExceptionString());
+				}
+				out.print("\n");
+				
+				printHeapObjects((JavaRuntime)mr, objAddress, objName, out, supers);
+			}
+			count++;
+		}
+	}
+	
+	private void printHeapObjects(JavaRuntime jr, Long objAddress, String objName,
+			Output out, boolean supers)
+	{
+		JavaHeap jh;
+		Iterator itHeap = jr.getHeaps();
+		int count = 1;
+		
+		while (itHeap.hasNext()) {
+			jh = (JavaHeap)itHeap.next();
+			
+			out.print("\t heap #" + count + " - name: ");
+			out.print(jh.getName());
+			out.print("\n\n");
+			
+			printObjects(jh, objAddress, objName, out, supers, jr);
+			count++;
+		}
+	}
+	
+	private void printObjects(JavaHeap jh, Long objAddress, String objName, Output out,
+			boolean supers, JavaRuntime jr)
+	{
+		JavaObject jo;
+		Iterator itObject = jh.getObjects();
+		boolean found = false;
+
+		if (objName != null)
+		{
+			JavaClass objClass = Utils.getClassGivenName(objName, jr, out);
+			
+			// if we couldn't find a class of that name, return; the passed in class name could
+			//  still be an array type or it might not exist
+			if (null == objClass)
+			{
+				out.print("\t  could not find class with name \"" + objName + "\"\n\n");
+				return;
+			}
+			
+			ClassOutput.printStaticFields(objClass, out);
+			
+			while (itObject.hasNext())
+			{
+				jo = (JavaObject)itObject.next();
+
+
+				String className;
+				String hierarchy = "";
+				JavaClass jc;
+
+				try {
+					jc = jo.getJavaClass();
+				} catch (CorruptDataException e) {
+					out.print("\t  <error getting class while traversing objects: ");
+					out.print(Exceptions.getCorruptDataExceptionString());
+					out.print(">\n");
+					jc = null;
+				}
+
+				boolean foundSuperclass = false;
+				while (jc != null && !foundSuperclass)
+				{
+					try {
+						className = jc.getName();
+					} catch (CorruptDataException e) {
+						out.print("\t  <error getting class name while traversing objects: ");
+						out.print(Exceptions.getCorruptDataExceptionString());
+						out.print(">\n");
+						jc = null;
+						continue;
+					}
+						
+					if (hierarchy.equals(""))
+						hierarchy = className;
+					else
+						hierarchy = className + " => " + hierarchy;
+
+					if (className.equals(objName))
+					{
+						found = true;
+						foundSuperclass = true;
+						out.print("\t  ");
+						out.print(hierarchy);
+						out.print(" @ ");
+						out.print(Utils.toHex(jo.getID().getAddress()));
+						out.print("\n");
+						
+						ClassOutput.printFields(jo, jc, jr, out);
+					}
+					else
+					{
+						if (supers)
+						{
+							try {
+								jc = jc.getSuperclass();
+							} catch (CorruptDataException e) {
+								out.print("\t  <error getting superclass while traversing objects: ");
+								out.print(Exceptions.getCorruptDataExceptionString());
+								out.print(">\n");
+								jc = null;
+							}
+						}
+						else
+						{
+							jc = null;
+						}
+					}
+				}
+			}
+		}
+		else // objAddress != null
+		{
+			boolean done = false;
+			while (itObject.hasNext() && !done)
+			{
+				jo = (JavaObject)itObject.next();
+
+
+				if (jo.getID().getAddress() == objAddress.longValue())
+				{
+					JavaClass jc;
+					
+					found = true;
+					out.print("\t  ");
+					try {
+						jc = jo.getJavaClass();
+					} catch (CorruptDataException e) {
+						out.print("\t  <error getting class while traversing objects: ");
+						out.print(Exceptions.getCorruptDataExceptionString());
+						out.print(">");
+						jc = null;
+					}
+					
+					if (null != jc)
+					{
+						try {
+							out.print(jc.getName());
+						} catch (CorruptDataException e) {
+							out.print("\t  <error getting class name while traversing objects: ");
+							out.print(Exceptions.getCorruptDataExceptionString());
+							out.print(">");
+						}
+						out.print(" @ ");
+						out.print(Utils.toHex(objAddress.longValue()));
+						out.print("\n");
+						
+						ClassOutput.printFields(jo, jc, jr, out);
+					
+						done = true;	// assumes only one object can exist at a specific memory address
+					}
+				}
+			}
+		}
+		
+		if (!found)
+		{
+			if (objName != null)
+			{
+				out.print("\t  <no object of class \"");
+				out.print(objName);
+				out.print("\" exists>\n\n");
+			}
+			else // objAddress != null
+			{
+				out.print("\t  <no object found at address ");
+				out.print(Utils.toHex(objAddress.longValue()));
+				out.print(">\n\n");
+			}
+		}
+	}
+
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XKCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XKCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XKCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XKCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,233 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.xcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.Iterator;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Exceptions;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.CorruptData;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.image.ImageAddressSpace;
+import com.ibm.dtfj.image.ImageProcess;
+import com.ibm.dtfj.image.ImageSection;
+import com.ibm.dtfj.image.ImagePointer;
+import com.ibm.dtfj.image.ImageModule;
+import com.ibm.dtfj.image.DataUnavailable;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.image.ImageSymbol;
+import com.ibm.dtfj.image.MemoryAccessException;
+
+public class XKCommand extends Command {
+
+	public XKCommand(Output o){
+		super(o, "k", "displays the specified memory section as if it were a stack frame",
+				"parameters: 0x<addr>\n\n" +
+				"Displays the value of each section (whose size is defined by the " +
+				"pointer size of this architecture) of memory, adjusted for the " +
+				"endianness of the architecture this dump file is from, starting at the " +
+				"specified address.  It also displays a module with a module section " +
+				"and an offset from the start of that module section in memory if the " +
+				"pointer points to that module section.  " +
+				"If no symbol is found, it displays a \"*\" and an offset from the " +
+				"current address if the pointer points to an address within 4KB (4096 " +
+				"bytes) of the current address.\n\n" +
+				"While this command can work on an arbitrary section of memory, it is " +
+				"probably most useful when used on a section of memory that refers to a " +
+				"stack frame.  To find the memory section of a thread's stack frame, use " +
+				"the \"info thread\" command.\n\n" +
+				"Note: This command uses the number of items passed to " +
+				"it by the \"x/\" command, but ignores the unit size.\n");
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		int numUnits = ((Integer)args.pop()).intValue();
+		args.pop();	// pop and discard unitSize; we ignore this value
+		
+		if (args.isEmpty())
+		{
+			out.error("\"x/k\" command takes exactly one parameter");
+			return;
+		}
+
+		String param = (String)args.pop();
+		if (!args.isEmpty())
+		{
+			out.error("\"x/k\" only takes one parameter");
+			return;
+		}
+		
+		Long address = Utils.longFromStringWithPrefix(param);
+		
+		if (null == address)
+		{
+			out.error("invalid hex address specified; address must be specified as "
+					+ "\"0x<hex_address>\"");
+			return;
+		}
+		
+		ImageAddressSpace ias = (ImageAddressSpace)properties.get("current_address_space");
+		int pointerSize = getIASPointerSize(ias);
+		int unitSize;
+		
+		if (pointerSize > 32)
+			unitSize = 8;
+		else
+			unitSize = 4;
+		
+		out.print("\n");
+		
+		for (int index = 0; index < numUnits; index++)
+		{
+			boolean found = false;
+			long currAddr = address.longValue() + (index * unitSize);
+			ImagePointer ip = ias.getPointer(currAddr);
+			
+			out.print("\t");
+			out.print(Utils.toHex(currAddr));
+			out.print("   ");
+
+			long l = 0;
+			try {
+				l = ip.getPointerAt(0).getAddress();
+				found = true;
+			} catch (CorruptDataException e) {
+				found = false;
+			} catch (MemoryAccessException e) {
+				found = false;
+			}
+
+			if (found) {
+				long pointer = l;
+				
+				out.print(toAdjustedHex(l, pointerSize));
+				out.print("   ");
+
+				if (31 == pointerSize) {
+					pointer = (int)(pointer & (((long)1) << pointerSize) - 1);
+				}
+				
+				if (printSymbol(pointer, l - currAddr, pointerSize, ias)) {
+				} else if (printStackPointer(pointer, l - currAddr, pointerSize, ias)) {
+				}
+				out.print("\n");
+			} else {
+				out.print("<address not found in any address space or exception occurred>\n");
+			}
+		}
+		
+		out.print("\n");
+	}
+	
+	private boolean printSymbol(long pointer, long diff, int pointerSize, ImageAddressSpace ias)
+	{
+		Iterator itProcess = ias.getProcesses();
+		while (itProcess.hasNext()) {
+			ImageProcess ip = (ImageProcess)itProcess.next();
+			Iterator itModule;
+			try {
+				itModule = ip.getLibraries();
+			} catch (CorruptDataException e) {
+				// FIXME
+				itModule = null;
+			} catch (DataUnavailable e) {
+				// FIXME
+				itModule = null;
+			}
+			while (null != itModule && itModule.hasNext()) {
+				ImageModule im = (ImageModule)itModule.next();
+				Iterator itImageSection = im.getSections();
+				while (itImageSection.hasNext()) {
+					ImageSection is = (ImageSection)itImageSection.next();
+					long startAddr = is.getBaseAddress().getAddress();
+					long endAddr = startAddr + is.getSize();
+					
+					if (pointer >= startAddr && pointer < endAddr) {
+						/* can we find a matching symbol? */
+						long maxDifference = pointer - startAddr;
+						ImageSymbol bestSymbol = null;
+						for (Iterator iter = im.getSymbols(); iter.hasNext();) {
+							Object next = iter.next();
+							if (next instanceof CorruptData)
+								continue;
+							ImageSymbol symbol = (ImageSymbol) next;
+							long symbolAddress = symbol.getAddress().getAddress();
+							if (symbolAddress <= pointer && pointer - symbolAddress < maxDifference) {
+								maxDifference = pointer - symbolAddress;
+								bestSymbol = symbol;
+							}
+						}
+
+						try {
+							out.print(im.getName());
+						} catch (CorruptDataException e) {
+							out.print(Exceptions.getCorruptDataExceptionString());
+						}
+						out.print("::");
+						if (bestSymbol == null) {
+							out.print(is.getName());
+						} else {
+							out.print(bestSymbol.getName());
+						}
+						out.print("+");
+						out.print(Long.toString(maxDifference));
+						
+						// if we find the address in the symbols, there's no need to continue
+						//  trying to find it elsewhere in the address space
+						return true;
+					}
+				}
+			}
+		}
+		
+		return false;
+	}
+	
+	private boolean printStackPointer(long pointer, long diff, int pointerSize, ImageAddressSpace ias)
+	{
+		if (Math.abs(diff) <= 4096) {	
+			if (diff < 0) {
+				out.print(" .");
+				out.print(Long.toString(diff));
+			} else {
+				out.print(" .+");
+				out.print(Long.toString(diff));
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	private int getIASPointerSize(ImageAddressSpace ias)
+	{
+		return ((ImageProcess)ias.getProcesses().next()).getPointerSize();
+	}
+
+	private String toAdjustedHex(long l, int pointerSize)
+	{
+		if (pointerSize > 32) {
+			return Utils.toFixedWidthHex(l);
+		} else if (31 == pointerSize) {
+			return Utils.toFixedWidthHex((int)(l & (((long)1) << pointerSize) - 1));
+		} else {
+			return Utils.toFixedWidthHex((int)l);
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XXCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XXCommand.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XXCommand.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/commands/xcommands/XXCommand.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,145 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.commands.xcommands;
+
+import java.util.HashMap;
+import java.util.Stack;
+import java.util.Iterator;
+
+import com.ibm.dtfj.dtfjview.Output;
+import com.ibm.dtfj.dtfjview.commands.Command;
+import com.ibm.dtfj.dtfjview.commands.helpers.Utils;
+import com.ibm.dtfj.image.Image;
+import com.ibm.dtfj.image.ImageAddressSpace;
+import com.ibm.dtfj.image.ImagePointer;
+import com.ibm.dtfj.image.CorruptDataException;
+import com.ibm.dtfj.image.MemoryAccessException;
+
+public class XXCommand extends Command {
+
+	public XXCommand(Output o){
+		super(o, "x", "displays the hex value of the bytes at the specified address",
+				"parameters: 0x<addr>\n\n" +
+				"Displays the hex value of the bytes at the specified address, " +
+				"adjusted for the endianness of the architecture this dump file is " +
+				"from.\n\n" +
+				"Note: This command uses the number of items and unit size passed to " +
+				"it by the \"x/\" command.\n"
+		);
+		child_commands = null;
+	}
+	
+	public void doCommand(Stack args, Image loadedImage, HashMap properties)
+	{
+		int numUnits = ((Integer)args.pop()).intValue();
+		int unitSize = ((Integer)args.pop()).intValue();
+		
+		if (args.isEmpty())
+		{
+			out.error("\"x/x\" command takes exactly one parameter");
+			return;
+		}
+
+		String param = (String)args.pop();
+		if (!args.isEmpty())
+		{
+			out.error("\"x/x\" only takes one parameter");
+			return;
+		}
+		Long address;
+		
+		address = Utils.longFromStringWithPrefix(param);
+		if (null == address)
+		{
+			out.error("invalid hex address specify; address must be specified as "
+					+ "\"0x<hex_address>\"");
+			return;
+		}
+
+		out.print("\n");
+		
+		for (int index = 0; index < numUnits; index++)
+		{
+			boolean found = false;
+			Iterator itImageAddressSpace = loadedImage.getAddressSpaces();
+			long currAddr = address.longValue() + (index * unitSize);
+			
+			out.print("\t");
+			out.print(Utils.toHex(currAddr));
+			out.print(": ");
+			
+			while (itImageAddressSpace.hasNext() && !found)
+			{
+				ImageAddressSpace ias = (ImageAddressSpace)itImageAddressSpace.next();
+				ImagePointer ip = ias.getPointer(currAddr);
+				
+				byte b = 0;
+				short s = 0;
+				int i = 0;
+				long l = 0;
+				try {
+					switch (unitSize)
+					{
+					case 1:
+						b = ip.getByteAt(0);
+						break;
+					case 2:
+						s = ip.getShortAt(0);
+						break;
+					case 4:
+						i = ip.getIntAt(0);
+						break;
+					case 8:
+						l = ip.getLongAt(0);
+						break;
+					}
+					
+					found = true;
+				} catch (CorruptDataException e) {
+					found = false;
+				} catch (MemoryAccessException e) {
+					found = false;
+				}
+
+				if (found)
+				{
+					switch (unitSize)
+					{
+					case 1:
+						out.print(Utils.toFixedWidthHex(b));
+						break;
+					case 2:
+						out.print(Utils.toFixedWidthHex(s));
+						break;
+					case 4:
+						out.print(Utils.toFixedWidthHex(i));
+						break;
+					case 8:
+						out.print(Utils.toFixedWidthHex(l));
+						break;
+					}
+				}
+			}
+			
+			if (!found)
+			{
+				out.print("<address not found in any address space>");
+			}
+			out.print("\n");
+		}
+		
+		out.print("\n");
+	}
+	
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpFormatter.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpFormatter.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpFormatter.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpFormatter.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,144 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.heapdump;
+
+import java.io.IOException;
+
+/**
+ * Abstract class to decouple the formatting of heapdumps from the walking of
+ * the internal data structures that hold the source data.
+ * 
+ */
+public abstract class HeapDumpFormatter
+{
+	protected final String _version;   
+	protected final boolean _is64Bit;
+
+	/**
+	 * Constructor
+	 * 
+	 * @param version JVM version information to be included in heapdump header
+	 * @param is64Bit True if we are dumping a 64 bit image, false otherwise
+	 */
+	protected HeapDumpFormatter(String version,boolean is64Bit)
+	{
+		this._version = version;
+		this._is64Bit = is64Bit;
+	}
+
+	/**
+	 * Adds a class to the heapdump.
+	 * 
+	 * @param address
+	 *            Address of class
+	 * @param name
+	 *            Name of class
+	 * @param superClassAddress
+	 *            Address of superclass
+	 * @param size
+	 *            Size of class, bytes
+	 * @param instanceSize
+	 *            Size of objects of this class
+	 * @param hashCode
+	 *            Hashcode
+	 * @param references
+	 *            Iterator of Long addresses (some of which may be null)
+	 * @throws IOException
+	 */
+	public abstract void addClass(long address, String name,
+			long superClassAddress, int size, int instanceSize, int hashCode, ReferenceIterator references)
+			throws IOException;
+
+	/**
+	 * Adds an object to the heapdump.
+	 * 
+	 * @param address
+	 *            Address of object
+	 * @param classAddress
+	 *            Address of class of object
+	 * @param className
+	 *            Name of class of object
+	 * @param size
+	 *            Size of object, bytes
+	 * @param hashCode
+	 *            Hashcode of object
+	 * @param references
+	 *            Iterator of Long addresses (some of which may be null)
+	 * @throws IOException
+	 */
+	public abstract void addObject(long address, long classAddress,
+			String className, int size, int hashCode, ReferenceIterator references)
+			throws IOException;
+
+	/**
+	 * Adds a primitive array object to the heapdump
+	 * 
+	 * Type code is: 0 - bool, 1 - char, 2 - float, 3 - double, 4 - byte, 5 - short, 6 -
+	 * int, 7 - long
+	 * 
+	 * @param address
+	 *            Address of object
+	 * @param arrayClassAddress
+	 *           Address of primitive array class
+	 * @param type
+	 *            Type code - see above
+	 * @param size
+	 *            Size of object, bytes.
+	 * @param hashCode
+	 *            Hashcode of object
+	 * @param numberOfElements
+	 *            Number of elements in the array
+	 * @throws IOException
+	 * @throws IllegalArgumentException
+	 *             if invalid type is supplied
+	 */
+	public abstract void addPrimitiveArray(long address, long arrayClassAddress, int type, int size,
+			int hashCode, int numberOfElements) throws IOException,
+			IllegalArgumentException;
+
+	/**
+	 * Adds an object array to the heapdump.
+	 * 
+	 * @param address
+	 *            Address of object
+	 * @param arrayClassAddress
+	 *            Address of class of array object
+	 * @param arrayClassName
+	 *            Name of class of array object
+	 * @param elementClassAddress
+	 *            Address of class of elements
+	 * @param elementClassName
+	 *            Name of class of elements
+	 * @param size
+	 *            Size of object, bytes
+	 * @param numberOfElements
+	 *            number of elements in the array
+	 * @param hashCode
+	 *            Hashcode of object
+	 * @param references
+	 *            Iterator of Long addresses (some of which may be null)
+	 * @throws IOException
+	 */
+	public abstract void addObjectArray(long address, long arrayClassAddress,
+			String arrayClassName, long elementClassAddress,
+			String elementClassName, int size, int numberOfElements,
+			int hashCode, ReferenceIterator references) throws IOException;
+	
+	/**
+	 * Closes the heapdump
+	 * 
+	 * @throws IOException
+	 */
+	public abstract void close() throws IOException;
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpSettings.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpSettings.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpSettings.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/HeapDumpSettings.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,104 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.heapdump;
+
+import java.util.Map;
+
+import com.ibm.dtfj.dtfjview.Session;
+
+/**
+ * Encapsulates the marshalling and unmarshalling of heapdump
+ * settings through the properties map.
+ * 
+ */
+public class HeapDumpSettings
+{
+	public static final String HEAP_DUMP_FILE_PROPERTY = "heap_dump_file";
+	public static final String HEAP_DUMP_FORMAT_PROPERTY = "heap_dump_format"; 
+	public static final String MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY = "heap_dump_multiple_heaps_multiple_files";
+	
+	public static void setFileName(String fileName,Map properties) 
+	{
+		properties.put(HEAP_DUMP_FILE_PROPERTY, fileName);
+	}
+	
+	/**
+	 * Returns the filename to use for writing out a heap dump, either based
+	 * on what the user has set or by generating the default name based on the 
+	 * image name
+	 */
+	public static String getFileName(Map properties)
+	{
+		String propertyFileName = (String) properties.get(HEAP_DUMP_FILE_PROPERTY);
+		
+		if(propertyFileName != null) {
+			return propertyFileName;
+		} else {
+			return getDefaultHeapDumpFileName(properties);
+		}
+	}
+	
+	private static String getDefaultHeapDumpFileName(Map properties)
+	{
+		String baseFileName = (String) properties.get(Session.CORE_FILE_PATH_PROPERTY);
+		
+		if(areHeapDumpsPHD(properties)) {
+			return baseFileName + ".phd";
+		} else {
+			return baseFileName + ".txt";
+		}
+	}
+	
+	public static void setClassicHeapDumps(Map properties)
+	{
+		properties.put(HEAP_DUMP_FORMAT_PROPERTY, "classic");
+	}
+	
+	public static boolean areHeapDumpsPHD(Map properties) 
+	{
+		Object formatValue = properties.get(HEAP_DUMP_FORMAT_PROPERTY);
+		
+		if(formatValue != null && formatValue.equals("classic")) {
+			return false;
+		} else {
+			return true;
+		}
+	}
+	
+	public static void setPHDHeapDumps(Map properties)
+	{
+		properties.put(HEAP_DUMP_FORMAT_PROPERTY, "phd");
+	}
+
+	public static void setMultipleHeapsMultipleFiles(Map properties)
+	{
+		properties.put(MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY, "true");
+	}
+	
+	public static void setMultipleHeapsSingleFile(Map properties)
+	{
+		properties.put(MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY, "false");
+	}
+	
+	public static boolean multipleHeapsInMultipleFiles(Map properties)
+	{
+		Object multipleFilesValue = properties.get(MULTIPLE_HEAPS_MULTIPLE_FILES_PROPERTY);
+		
+		if(multipleFilesValue == null) {
+			return false;
+		} else {
+			return multipleFilesValue.equals("true");
+		}
+	}
+}

Added: incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/LongArrayReferenceIterator.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/LongArrayReferenceIterator.java?rev=754949&view=auto
==============================================================================
--- incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/LongArrayReferenceIterator.java (added)
+++ incubator/kato/trunk/import/org.apache.kato.tools.katoview/src/com/ibm/dtfj/dtfjview/heapdump/LongArrayReferenceIterator.java Mon Mar 16 16:43:29 2009
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ ******************************************************************************/
+package com.ibm.dtfj.dtfjview.heapdump;
+
+
+public class LongArrayReferenceIterator implements ReferenceIterator 
+{
+	private final long _fields[];
+	private int _index = 0;
+	
+	public LongArrayReferenceIterator(long[] fields) {
+		if(fields != null) {
+			_fields = fields;
+		} else {
+			_fields = new long[0];
+		}
+	}
+	
+	public boolean hasNext()
+	{
+		return _index < (_fields.length);
+	}
+
+	public Long next()
+	{
+		Long toReturn = new Long(_fields[_index]);
+		
+		_index++;
+		
+		return toReturn;
+	}
+
+	public void reset()
+	{
+		_index = 0;
+	}
+	
+}



Mime
View raw message