You are viewing a plain text version of this content. The canonical link for it is here.
Posted to kato-commits@incubator.apache.org by mo...@apache.org on 2009/11/23 15:54:15 UTC
svn commit: r883384 [40/47] - in /incubator/kato/trunk/org.apache.kato: ./
kato.anttasks/src/main/java/org/apache/kato/anttasks/
kato.anttasks/src/main/java/org/apache/kato/anttasks/sitebuilder/
kato.anttasks/src/main/java/org/apache/kato/anttasks/tck/...
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HeapdumpCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HeapdumpCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HeapdumpCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HeapdumpCommand.java Mon Nov 23 15:53:48 2009
@@ -1,879 +1,879 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.lang.reflect.Modifier;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Set;
-import java.util.Stack;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import javax.tools.diagnostics.image.CorruptData;
-import javax.tools.diagnostics.image.CorruptDataException;
-import javax.tools.diagnostics.image.DataUnavailable;
-import javax.tools.diagnostics.image.Image;
-import javax.tools.diagnostics.image.ImageAddressSpace;
-import javax.tools.diagnostics.image.ImageProcess;
-import javax.tools.diagnostics.image.DiagnosticException;
-import javax.tools.diagnostics.image.MemoryAccessException;
-import javax.tools.diagnostics.runtime.java.JavaClass;
-import javax.tools.diagnostics.runtime.java.JavaClassLoader;
-import javax.tools.diagnostics.runtime.java.JavaField;
-import javax.tools.diagnostics.runtime.java.JavaHeap;
-import javax.tools.diagnostics.runtime.java.JavaObject;
-import javax.tools.diagnostics.runtime.java.JavaRuntime;
-
-import org.apache.kato.katoview.Output;
-import org.apache.kato.katoview.heapdump.HeapDumpFormatter;
-import org.apache.kato.katoview.heapdump.HeapDumpSettings;
-import org.apache.kato.katoview.heapdump.LongListReferenceIterator;
-import org.apache.kato.katoview.heapdump.ReferenceIterator;
-import org.apache.kato.katoview.heapdump.classic.ClassicHeapDumpFormatter;
-
-
-/**
- * Command for dumping heapdumps from Kato.
- *
- * Contains the heap-walking logic for building the reference tree.
- *
- */
-public class HeapdumpCommand extends Command
-{
- public static final String COMMAND_NAME = "heapdump";
- public static final String DESCRIPTION = "generates a heapdump";
- public static final String LONG_DESCRIPTION = "Parameters: [heapname+]\n\n"
- + "\t[heapname+] - space-separated name of heap or heaps to dump. Use \"info heap\" to get the list of heap names. Default: all heaps are dumped.\n\n"
- + "Writes a heapdump from the memory image.\n"
- + "The file name and format are controlled using the \"set heapdump\" command; the current settings "
- + "can be displayed using \"show heapdump\".\n";
-
- private static final String PROTECTION_DOMAIN_FIELD_NAME = "protectionDomain";
- /**
- * Regexp pattern used to extract a subset of the versions string
- */
- private static final Pattern J9_VERSION_PATTERN = Pattern.compile("(IBM J9 VM.*?\\))");
- //Do not change the order this array - the indexes are used to extract type codes in the getPrimitiveTypeCode method
- private static final String[] PRIMITIVE_TYPES = { "boolean", "char",
- "float", "double", "byte", "short", "int", "long", "void" };
- private int _numberOfObjects = 0;
- private int _numberOfClasses = 0;
- private int _numberOfErrors = 0;
- private boolean _verbose = false;
-
- public HeapdumpCommand(Output o)
- {
- super(o, COMMAND_NAME, DESCRIPTION, LONG_DESCRIPTION);
- child_commands = null;
- }
-
- public void doCommand(Stack args, Image loadedImage, HashMap properties)
- {
- Set heapsToDump = new HashSet();
-
- while(! args.isEmpty()) {
- heapsToDump.add(args.pop());
- }
-
- _numberOfObjects = 0;
- _numberOfErrors = 0;
- _numberOfClasses = 0;
-
- Object verboseModeStr = properties.get("verbose.mode");
- _verbose = verboseModeStr != null ? verboseModeStr.equals("on") : false;
-
- ImageAddressSpace addressSpace = (ImageAddressSpace) properties.get("current_address_space");
-
- if(addressSpace == null) {
- out.error("Couldn't get handle on address space");
- return;
- }
-
- JavaRuntime runtime = getRuntime(addressSpace);
-
- if(runtime == null) {
- return;
- }
-
- if(! heapArgumentsAreValid(runtime,heapsToDump)) {
- return;
- }
-
- String version = getVersionString(runtime);
-
- boolean is64Bit = addressSpace.getCurrentProcess().getPointerSize() == 64;
- String filename = HeapDumpSettings.getFileName(properties);
- boolean phdFormat = HeapDumpSettings.areHeapDumpsPHD(properties);
-
- try {
- if(HeapDumpSettings.multipleHeapsInMultipleFiles(properties)) {
- dumpMultipleHeapsInSeparateFiles(runtime,version,is64Bit,phdFormat,filename,heapsToDump);
- } else {
- dumpMultipleHeapsInOneFile(runtime,version,is64Bit,phdFormat,filename,heapsToDump);
- }
-
- if(_numberOfErrors == 0) {
- out.print("\nSuccessfully wrote " + _numberOfObjects + " objects and " + _numberOfClasses + " classes\n");
- } else {
- out.print("\nWrote "
- + _numberOfObjects
- + " objects and "
- + _numberOfClasses
- + " classes and encountered "
- + _numberOfErrors
- + " errors."
- + (! _verbose ? " Start KatoView with -verbose for more detail." : "")
- + "\n");
- }
- }
- catch (IOException ex) {
- out.error("I/O error writing dump:\n");
- StringWriter writer = new StringWriter();
- ex.printStackTrace(new PrintWriter(writer));
- out.error(writer.toString());
- }
- }
-
- /**
- * Checks the list of heaps to dump as specified by the user.
- * @param runtime Current java runtime
- * @param heapsToDump Set of strings the user passed as heaps to dump
- * @return True if all the names are valid heaps, false otherwise
- */
- private boolean heapArgumentsAreValid(JavaRuntime runtime, Set heapsToDump)
- {
- if(heapsToDump.size() == 0) {
- return true;
- }
-
- Set workingSet = new HashSet();
- workingSet.addAll(heapsToDump);
-
- Iterator heapIt = runtime.getHeaps().iterator();
-
- while(heapIt.hasNext()) {
- Object potential = heapIt.next();
-
- if(potential instanceof JavaHeap) {
- JavaHeap thisHeap = (JavaHeap)potential;
-
- workingSet.remove(thisHeap.getName());
- } else if (potential instanceof CorruptData) {
- reportError("Corrupt heap found. Address = " + ((CorruptData)potential).getAddress(),null);
- _numberOfErrors++;
- } else {
- _numberOfErrors++;
- reportError("Unexpected type " + potential.getClass().getName() + " found in heap iterator",null);
- }
- }
-
- if(workingSet.isEmpty()) {
- return true;
- } else {
- StringBuffer buffer = new StringBuffer();
- buffer.append("These specified heaps do not exist:\n");
-
- Iterator nameIterator = workingSet.iterator();
-
- while(nameIterator.hasNext()) {
- buffer.append("\t\t" + nameIterator.next() + "\n");
- }
-
- buffer.append("\tUse \"info heap\" to see list of heap names");
-
- out.error(buffer.toString());
-
- return false;
- }
- }
-
- /**
- * Extracts a minimal version string from the full -version output
- */
- private String getVersionString(JavaRuntime runtime)
- {
- try {
- String rawVersion = runtime.getVersion();
-
- Matcher matcher = J9_VERSION_PATTERN.matcher(rawVersion);
-
- if(matcher.find()) {
- String minimalVersion = matcher.group(1);
- return minimalVersion;
- } else {
- _numberOfErrors++;
- reportError("Could not parse version string: " + rawVersion,null);
- return rawVersion;
- }
- }
- catch (CorruptDataException e) {
- _numberOfErrors++;
- out.error("Could not read version string from dump: data corrupted at "
- + e.getCorruptData().getAddress());
- return "*Corrupt*";
- }
- }
-
- private JavaRuntime getRuntime(ImageAddressSpace addressSpace)
- {
- ImageProcess process = addressSpace.getCurrentProcess();
-
- if(process == null) {
- out.error("Couldn't get handle on current process");
- return null;
- }
-
- Iterator runtimeIterator = process.getRuntimes().iterator();
-
- if(! runtimeIterator.hasNext()) {
- out.error("Cannot find a runtime");
- return null;
- }
-
- Object potential = runtimeIterator.next();
-
- if(potential instanceof CorruptData) {
- out.error("Runtime data is corrupt");
- return null;
- }
-
- return (JavaRuntime) potential;
- }
-
- private void dumpMultipleHeapsInOneFile(JavaRuntime runtime,
- String version, boolean is64Bit, boolean phdFormat, String filename, Set heapsToDump) throws IOException
- {
- Iterator heapIterator = runtime.getHeaps().iterator();
-
- HeapDumpFormatter formatter = getFormatter(filename, version, is64Bit, phdFormat);
-
- out.print("Writing " + ( phdFormat ? "PHD" : "Classic") + " format heapdump into " + filename);
-
- dumpClasses(formatter,runtime);
-
- while (heapIterator.hasNext()) {
- Object thisHeapObj = heapIterator.next();
-
- if (thisHeapObj instanceof CorruptData) {
- out.error("Corrupt heap data found at: "
- + ((CorruptData) thisHeapObj).getAddress());
- _numberOfErrors++;
- continue;
- }
-
- JavaHeap thisHeap = (JavaHeap) thisHeapObj;
-
- if(heapsToDump.size() > 0 && ! heapsToDump.contains(thisHeap.getName())) {
- continue;
- }
-
- dumpHeap(formatter, thisHeap);
- }
-
- formatter.close();
- }
-
- private void dumpMultipleHeapsInSeparateFiles(JavaRuntime runtime,String version, boolean is64Bit, boolean phdFormat,String baseFileName, Set heapsToDump) throws IOException
- {
- Iterator heapIterator = runtime.getHeaps().iterator();
-
- HeapDumpFormatter formatter = null;
-
- while (heapIterator.hasNext()) {
- Object thisHeapObj = heapIterator.next();
-
- if (thisHeapObj instanceof CorruptData) {
- out.error("Heap corrupted at: "
- + ((CorruptData) thisHeapObj).getAddress());
- _numberOfErrors++;
- continue;
- }
-
- JavaHeap thisHeap = (JavaHeap) thisHeapObj;
-
- // Create a new heapdump formatter for every heap we find
- if (formatter != null) {
- formatter.close();
- }
-
- if(heapsToDump.size() > 0 && ! heapsToDump.contains(thisHeap.getName())) {
- continue;
- }
-
- String fileName = getFileNameForHeap(thisHeap,baseFileName);
-
- out.print("Writing "
- + ( phdFormat ? "PHD" : "Classic")
- + " format heapdump for heap "
- + thisHeap.getName()
- + " into "
- + fileName + "\n");
-
- formatter = getFormatter(fileName, version, is64Bit, phdFormat);
-
- //We have to dump classes in every heapdump
- dumpClasses(formatter,runtime);
-
- dumpHeap(formatter, thisHeap);
- }
-
- if(formatter != null) {
- formatter.close();
- }
- }
-
- /**
- * Walks the runtime classes and passes them through the formatter interface
- */
- private void dumpClasses(HeapDumpFormatter formatter, JavaRuntime runtime) throws IOException
- {
- Iterator classLoaderIt = runtime.getJavaClassLoaders().iterator();
-
- int numberOfClasses = 0;
-
-ITERATING_LOADERS:while(classLoaderIt.hasNext()) {
- Object potential = classLoaderIt.next();
-
- if(potential instanceof CorruptData) {
- _numberOfErrors++;
- reportError("CorruptData found in classloader list at address: " + ((CorruptData)potential).getAddress(), null);
- continue ITERATING_LOADERS;
- }
-
- JavaClassLoader thisClassLoader = (JavaClassLoader)potential;
-
- Iterator classesIt = thisClassLoader.getDefinedClasses().iterator();
-
-ITERATING_CLASSES:while(classesIt.hasNext()) {
- potential = classesIt.next();
-
- numberOfClasses++;
-
- try {
-
- if(potential instanceof CorruptData) {
- _numberOfErrors++;
- reportError("CorruptData found in class list for classloader "
- + Long.toHexString(thisClassLoader.getObject().getID().getAddress())
- + " at address: " + ((CorruptData)potential).getAddress(), null);
- continue ITERATING_CLASSES;
- }
-
- JavaClass thisJavaClass = (JavaClass)potential;
-
- JavaClass superClass = thisJavaClass.getSuperclass();
-
- JavaObject classObject = thisJavaClass.getObject();
-
- int instanceSize = 0;
-
- if(thisJavaClass.isArray()) {
- instanceSize = 0;
- } else {
- // we need to figure out a way of determining the instance size for a class
- }
-
- formatter.addClass(thisJavaClass.getID().getAddress(),
- thisJavaClass.getName(),
- superClass != null ? superClass.getID().getAddress() : 0,
- classObject != null ? (int)classObject.getSize() : 0,
- instanceSize,
- classObject != null ? (int)classObject.getPersistentHashcode() : 0,
- getClassReferences(thisJavaClass) );
- } catch(DiagnosticException ex) {
- //Handle CorruptDataException and DataUnavailableException the same way
- _numberOfErrors++;
- reportError(null,ex);
- continue ITERATING_CLASSES;
- }
- }
- }
-
- _numberOfClasses = numberOfClasses;
- }
-
- /**
- * Walks the supplied heap and passes the artifacts through the formatter
- */
- private void dumpHeap(HeapDumpFormatter formatter, JavaHeap thisHeap)
- throws IOException
- {
- Iterator objectIterator = thisHeap.getObjects().iterator();
-
- while (objectIterator.hasNext()) {
- Object next = objectIterator.next();
- _numberOfObjects++;
-
- if (next instanceof CorruptData) {
- _numberOfErrors++;
- reportError("Corrupt object data found at " + ((CorruptData)next).getAddress() + " while walking heap " + thisHeap.getName(),null);
- continue;
- }
-
- try {
- JavaObject thisObject = (JavaObject) next;
- JavaClass thisClass = thisObject.getJavaClass();
-
- int hashcode = 0;
-
- try {
- hashcode = (int) thisObject.getHashcode();
- }
- catch (DataUnavailable ex) {
- _numberOfErrors++;
- reportError("Failed to get hashcode for object: " + thisObject.getID(),ex);
- }
-
- if (thisObject.isArray()) {
- if (isPrimitive(thisClass.getComponentType())) {
- formatter.addPrimitiveArray(thisObject.getID().getAddress(),
- thisClass.getID().getAddress(),
- getPrimitiveTypeCode(thisClass.getComponentType()),
- (int) thisObject.getSize(),
- hashcode,
- thisObject.getArraySize());
- }
- else {
-
- formatter.addObjectArray(thisObject.getID().getAddress(),
- thisClass.getID().getAddress(),
- thisClass.getName(),
- thisClass.getComponentType().getID().getAddress(),
- thisClass.getComponentType().getName(),
- (int) thisObject.getSize(),
- thisObject.getArraySize(),
- hashcode,
- getObjectReferences(thisObject));
- }
- }
- else {
- formatter.addObject(thisObject.getID().getAddress(),
- thisClass.getID().getAddress(),
- thisClass.getName(),
- (int)thisObject.getSize(),
- hashcode,
- getObjectReferences(thisObject));
- }
- }
- catch (CorruptDataException ex) {
- _numberOfErrors++;
- reportError(null,ex);
- continue;
- }
- }
- }
-
- /* Reference code reimplemented (rather than using the Kato getReferences() API)
- * because we are trying to match the behaviour of the runtime heapdump rather than
- * the GC spec. The set of references we're trying to create is different.
- */
-
- /**
- * Gets the references for the supplied class
- *
- * @param thisJavaClass Class being examined
- */
- private ReferenceIterator getClassReferences(JavaClass thisJavaClass)
- {
- List references = new LinkedList();
-
- try {
- //Statics
- addStaticReferences(thisJavaClass, references);
-
- addProtectionDomainReference(thisJavaClass,references);
-
- //Classloader
- JavaClassLoader loader = thisJavaClass.getClassLoader();
-
- if(loader != null) {
- JavaObject loaderObject = loader.getObject();
- if(loaderObject != null) {
- references.add(new Long(loaderObject.getID().getAddress()));
- } else {
- reportError("Null loader object returned for class: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null);
- _numberOfErrors++;
- }
- } else {
- reportError("Null classloader returned for class: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null);
- _numberOfErrors++;
- }
-
- //Heap object
- JavaObject classObject = thisJavaClass.getObject();
- if(classObject != null) {
- references.add(new Long(classObject.getID().getAddress()));
- } else {
- _numberOfErrors++;
- reportError("Couldn't get Java class loader for: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null);
- }
-
- } catch(DiagnosticException ex) {
- reportError(null,ex);
- _numberOfErrors++;
- }
-
- return new LongListReferenceIterator(references);
- }
-
- private JavaField _protectionDomainField;
-
- private void addProtectionDomainReference(JavaClass thisJavaClass,
- List references) throws CorruptDataException, MemoryAccessException
-
- {
- JavaObject classObject = thisJavaClass.getObject();
-
- //Protection domain hangs off the protectionDomain field on the class object
- if(_protectionDomainField == null) {
- JavaClass javaLangClassObject = classObject.getJavaClass();
- if(javaLangClassObject == null) {
- _numberOfErrors++;
- reportError("Couldn't find java.lang.Class class",null);
- return;
- }
- Iterator fieldsIt = javaLangClassObject.getDeclaredFields().iterator();
-
- while(fieldsIt.hasNext()) {
- Object potential = fieldsIt.next();
-
- if(potential instanceof JavaField) {
- JavaField field = (JavaField) potential;
-
- if(field.getName().equals(PROTECTION_DOMAIN_FIELD_NAME)) {
- _protectionDomainField = field;
- }
- } else if(potential instanceof CorruptData) {
- _numberOfErrors++;
- reportError("CorruptData found walking fields for java.lang.Class. Bad address = "
- + ((CorruptData)potential).getAddress()
- ,null);
- } else {
- _numberOfErrors++;
- reportError("Unexpected type "
- + potential.getClass()
- + " returned from fields iterator."
- ,null);
- }
- }
-
- if(_protectionDomainField == null) {
- _numberOfErrors++;
- reportError("Couldn't find protection domain field.",null);
- return;
- }
- }
-
- Object potential = _protectionDomainField.get(classObject);
-
- if(potential instanceof JavaObject) {
- JavaObject protectionDomain = (JavaObject)potential;
-
- references.add(new Long(protectionDomain.getID().getAddress()));
- } else if (potential instanceof CorruptData) {
- _numberOfErrors++;
- reportError("Corrupt data found in protectionDomainField of "
- + thisJavaClass.getName()
- + " at address "
- + ((CorruptData)potential).getAddress()
- ,null);
- } else if (potential == null) {
- //Do nothing
- } else {
- reportError("Unexpected type: "
- + potential.getClass().getName()
- + " found in protectionDomain field of "
- + thisJavaClass.getName()
- ,null);
- _numberOfErrors++;
- }
- }
-
- /**
- * Extracts static references from class
- * @param thisClass Class being examined
- * @param references List to add references to
- */
- private void addStaticReferences(JavaClass thisClass, List references)
- throws CorruptDataException, MemoryAccessException
- {
- Iterator fieldsIt = thisClass.getDeclaredFields().iterator();
-
- while(fieldsIt.hasNext()) {
- Object potential = fieldsIt.next();
-
- if(potential instanceof CorruptData) {
- reportError("Corrupt field found in class "
- + thisClass.getName()
- + "(" + thisClass.getID() + ") at "
- + ((CorruptData)potential).getAddress()
- ,null);
- _numberOfErrors++;
- continue;
- }
-
- JavaField field = (JavaField) potential;
-
- if(! Modifier.isStatic(field.getModifiers())) {
- continue;
- }
-
- Object referent = field.get(thisClass.getObject());
-
- if(referent instanceof CorruptData) {
- _numberOfErrors++;
- reportError("Corrupt referent found in class "
- + thisClass.getName()
- + "(" + thisClass.getID() + ") from field "
- + field.getName()
- + " at address "
- + ((CorruptData)potential).getAddress()
- ,null);
- } else if (referent instanceof JavaObject) {
- JavaObject referredObject = (JavaObject) referent;
-
- references.add(new Long(referredObject.getID().getAddress()));
- } else if (referent == null) {
- references.add(new Long(0));
- } else if (referent instanceof Number || referent instanceof Boolean || referent instanceof Character) {
- //Ignore
- } else {
- reportError("Unexpected type: "
- + referent.getClass().getName()
- + " returned from field "
- + field.getName()
- + " from class "
- + thisClass.getName()
- + "(" + thisClass.getID()+ ")"
- ,null);
- _numberOfErrors++;
- }
- }
- }
-
- /**
- * Gets instance references for objects
- * @param thisObject Object being examined
- * @return Iterator of references
- */
- private ReferenceIterator getObjectReferences(JavaObject thisObject)
- {
- List references = new LinkedList();
-
- try {
- JavaClass thisClass = thisObject.getJavaClass();
-
- if(thisClass.isArray()) {
- addArrayReferences(thisObject, references);
- } else {
- addRegularObjectReferences(thisObject, references,thisClass);
- }
- } catch(DiagnosticException ex) {
- _numberOfErrors++;
- reportError(null,ex);
- }
-
- return new LongListReferenceIterator(references);
- }
-
- /**
- * Extracts the instance references from object arrays
- * @param arrayObject Array
- * @param references List to add references to
- */
- private void addArrayReferences(JavaObject arrayObject, List references)
- throws CorruptDataException, MemoryAccessException
- {
- JavaObject[] localArray = new JavaObject[arrayObject.getArraySize()];
- arrayObject.arraycopy(0, localArray, 0, arrayObject.getArraySize());
-
- for(int i=0;i!=localArray.length;i++) {
- if(localArray[i] != null) {
- references.add(new Long(localArray[i].getID().getAddress()));
- } else {
- references.add(new Long(0));
- }
- }
- }
-
- /**
- * Extracts the instance references from a regular (non-array) object
- * @param object Object being walked
- * @param references List to add references to
- * @param thisClass Class of object
- */
- private void addRegularObjectReferences(JavaObject object,
- List references, JavaClass thisClass) throws CorruptDataException,
- MemoryAccessException
- {
- while(thisClass != null) {
-
- Iterator fieldsIt = thisClass.getDeclaredFields().iterator();
-
-WALKING_FIELDS: while(fieldsIt.hasNext()) {
- Object potential = fieldsIt.next();
-
- if(potential instanceof CorruptData) {
- _numberOfErrors++;
- reportError("Corrupt data found at address "
- + ((CorruptData)potential).getAddress()
- + " walking fields of class: "
- + thisClass.getName()
- + "(" + thisClass.getID() + ")"
- ,null);
- continue WALKING_FIELDS;
- }
-
- JavaField field = (JavaField) potential;
-
- if(Modifier.isStatic(field.getModifiers())) {
- continue WALKING_FIELDS;
- }
-
- Object referent = field.get(object);
-
- if(referent instanceof CorruptData) {
- _numberOfErrors++;
- reportError("Corrupt data found in referent at address "
- + ((CorruptData)referent).getAddress()
- + " walking field "
- + field.getName()
- + " of class: "
- + thisClass.getName()
- + "(" + thisClass.getID() + ")"
- ,null);
- continue WALKING_FIELDS;
- } else if (referent instanceof JavaObject) {
- JavaObject referredObject = (JavaObject) referent;
-
- references.add(new Long(referredObject.getID().getAddress()));
- } else if (referent == null) {
- references.add(new Long(0));
- } else if (referent instanceof Number || referent instanceof Boolean || referent instanceof Character) {
- //Ignore
- } else {
- reportError("Unexpected type: " + referent.getClass().getName() + " found in referent",null);
- _numberOfErrors++;
- }
- }
-
- thisClass = thisClass.getSuperclass();
- }
- }
-
- /**
- * Checks if class is primitive
- *
- * @param clazz
- * Class under test
- * @return True if clazz represents a primitive type, false otherwise
- */
- private static boolean isPrimitive(JavaClass clazz)
- throws CorruptDataException
- {
- String name = clazz.getName();
-
- /* Fastpath, anything containing a / cannot be primitive */
- if (name.indexOf("/") != -1) {
- return false;
- }
-
- for (int i = 0; i != PRIMITIVE_TYPES.length; i++) {
- if (PRIMITIVE_TYPES[i].equals(name)) {
- return true;
- }
- }
-
- return false;
- }
-
- /**
- * Converts a class into a primitive type code (as used by the HeapdumpFormatter interface).
- * @param clazz
- * @return
- */
- private int getPrimitiveTypeCode(JavaClass clazz)
- throws CorruptDataException
- {
- String name = clazz.getName();
-
- for (int i = 0; i != PRIMITIVE_TYPES.length; i++) {
- if (PRIMITIVE_TYPES[i].equals(name)) {
- return i;
- }
- }
-
- throw new IllegalArgumentException("Class: " + name
- + " is not primitive");
- }
-
- /**
- * Factory method for HeapDumpFormatters
- * @param fileName File name for output file
- * @param version Version string
- * @param is64Bit True if 64 bit
- * @param phdFormat True if using PhD format
- */
- private HeapDumpFormatter getFormatter(String fileName, String version,
- boolean is64Bit, boolean phdFormat) throws IOException
- {
- return new ClassicHeapDumpFormatter(new FileWriter(fileName),version,is64Bit);
- }
-
- /**
- * Modifies the base file name to include the heap name, whilst maintaining
- * the suffix
- */
- private String getFileNameForHeap(JavaHeap thisHeap, String baseFileName)
- {
- int pointIndex = baseFileName.lastIndexOf(".");
-
- if(pointIndex != -1) {
- return baseFileName.substring(0,pointIndex) + "." + thisHeap.getName() + baseFileName.substring(pointIndex);
- } else {
- return baseFileName + "." + thisHeap.getName();
- }
- }
-
- /**
- * Internal error handling routine that only reports the supplied message if verbose was supplied on the command line.
- */
- private void reportError(String msg,Throwable t)
- {
- //Property set in Session.imageFromCommandLine when -verbose specified on command line
- if(!_verbose) {
- return;
- }
-
- if(msg != null) {
- out.error(msg);
- }
-
- if(t != null) {
- StringWriter writer = new StringWriter();
-
- t.printStackTrace(new PrintWriter(writer));
-
- out.error(writer.toString());
- }
- }
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Set;
+import java.util.Stack;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.tools.diagnostics.image.CorruptData;
+import javax.tools.diagnostics.image.CorruptDataException;
+import javax.tools.diagnostics.image.DataUnavailable;
+import javax.tools.diagnostics.image.Image;
+import javax.tools.diagnostics.image.ImageAddressSpace;
+import javax.tools.diagnostics.image.ImageProcess;
+import javax.tools.diagnostics.image.DiagnosticException;
+import javax.tools.diagnostics.image.MemoryAccessException;
+import javax.tools.diagnostics.runtime.java.JavaClass;
+import javax.tools.diagnostics.runtime.java.JavaClassLoader;
+import javax.tools.diagnostics.runtime.java.JavaField;
+import javax.tools.diagnostics.runtime.java.JavaHeap;
+import javax.tools.diagnostics.runtime.java.JavaObject;
+import javax.tools.diagnostics.runtime.java.JavaRuntime;
+
+import org.apache.kato.katoview.Output;
+import org.apache.kato.katoview.heapdump.HeapDumpFormatter;
+import org.apache.kato.katoview.heapdump.HeapDumpSettings;
+import org.apache.kato.katoview.heapdump.LongListReferenceIterator;
+import org.apache.kato.katoview.heapdump.ReferenceIterator;
+import org.apache.kato.katoview.heapdump.classic.ClassicHeapDumpFormatter;
+
+
+/**
+ * Command for dumping heapdumps from Kato.
+ *
+ * Contains the heap-walking logic for building the reference tree.
+ *
+ */
+public class HeapdumpCommand extends Command
+{
+ public static final String COMMAND_NAME = "heapdump";
+ public static final String DESCRIPTION = "generates a heapdump";
+ public static final String LONG_DESCRIPTION = "Parameters: [heapname+]\n\n"
+ + "\t[heapname+] - space-separated name of heap or heaps to dump. Use \"info heap\" to get the list of heap names. Default: all heaps are dumped.\n\n"
+ + "Writes a heapdump from the memory image.\n"
+ + "The file name and format are controlled using the \"set heapdump\" command; the current settings "
+ + "can be displayed using \"show heapdump\".\n";
+
+ private static final String PROTECTION_DOMAIN_FIELD_NAME = "protectionDomain";
+ /**
+ * Regexp pattern used to extract a subset of the versions string
+ */
+ private static final Pattern J9_VERSION_PATTERN = Pattern.compile("(IBM J9 VM.*?\\))");
+ //Do not change the order this array - the indexes are used to extract type codes in the getPrimitiveTypeCode method
+ private static final String[] PRIMITIVE_TYPES = { "boolean", "char",
+ "float", "double", "byte", "short", "int", "long", "void" };
+ private int _numberOfObjects = 0;
+ private int _numberOfClasses = 0;
+ private int _numberOfErrors = 0;
+ private boolean _verbose = false;
+
+ public HeapdumpCommand(Output o)
+ {
+ super(o, COMMAND_NAME, DESCRIPTION, LONG_DESCRIPTION);
+ child_commands = null;
+ }
+
+ public void doCommand(Stack args, Image loadedImage, HashMap properties)
+ {
+ Set heapsToDump = new HashSet();
+
+ while(! args.isEmpty()) {
+ heapsToDump.add(args.pop());
+ }
+
+ _numberOfObjects = 0;
+ _numberOfErrors = 0;
+ _numberOfClasses = 0;
+
+ Object verboseModeStr = properties.get("verbose.mode");
+ _verbose = verboseModeStr != null ? verboseModeStr.equals("on") : false;
+
+ ImageAddressSpace addressSpace = (ImageAddressSpace) properties.get("current_address_space");
+
+ if(addressSpace == null) {
+ out.error("Couldn't get handle on address space");
+ return;
+ }
+
+ JavaRuntime runtime = getRuntime(addressSpace);
+
+ if(runtime == null) {
+ return;
+ }
+
+ if(! heapArgumentsAreValid(runtime,heapsToDump)) {
+ return;
+ }
+
+ String version = getVersionString(runtime);
+
+ boolean is64Bit = addressSpace.getCurrentProcess().getPointerSize() == 64;
+ String filename = HeapDumpSettings.getFileName(properties);
+ boolean phdFormat = HeapDumpSettings.areHeapDumpsPHD(properties);
+
+ try {
+ if(HeapDumpSettings.multipleHeapsInMultipleFiles(properties)) {
+ dumpMultipleHeapsInSeparateFiles(runtime,version,is64Bit,phdFormat,filename,heapsToDump);
+ } else {
+ dumpMultipleHeapsInOneFile(runtime,version,is64Bit,phdFormat,filename,heapsToDump);
+ }
+
+ if(_numberOfErrors == 0) {
+ out.print("\nSuccessfully wrote " + _numberOfObjects + " objects and " + _numberOfClasses + " classes\n");
+ } else {
+ out.print("\nWrote "
+ + _numberOfObjects
+ + " objects and "
+ + _numberOfClasses
+ + " classes and encountered "
+ + _numberOfErrors
+ + " errors."
+ + (! _verbose ? " Start KatoView with -verbose for more detail." : "")
+ + "\n");
+ }
+ }
+ catch (IOException ex) {
+ out.error("I/O error writing dump:\n");
+ StringWriter writer = new StringWriter();
+ ex.printStackTrace(new PrintWriter(writer));
+ out.error(writer.toString());
+ }
+ }
+
+ /**
+ * Checks the list of heaps to dump as specified by the user.
+ * @param runtime Current java runtime
+ * @param heapsToDump Set of strings the user passed as heaps to dump
+ * @return True if all the names are valid heaps, false otherwise
+ */
+ private boolean heapArgumentsAreValid(JavaRuntime runtime, Set heapsToDump)
+ {
+ if(heapsToDump.size() == 0) {
+ return true;
+ }
+
+ Set workingSet = new HashSet();
+ workingSet.addAll(heapsToDump);
+
+ Iterator heapIt = runtime.getHeaps().iterator();
+
+ while(heapIt.hasNext()) {
+ Object potential = heapIt.next();
+
+ if(potential instanceof JavaHeap) {
+ JavaHeap thisHeap = (JavaHeap)potential;
+
+ workingSet.remove(thisHeap.getName());
+ } else if (potential instanceof CorruptData) {
+ reportError("Corrupt heap found. Address = " + ((CorruptData)potential).getAddress(),null);
+ _numberOfErrors++;
+ } else {
+ _numberOfErrors++;
+ reportError("Unexpected type " + potential.getClass().getName() + " found in heap iterator",null);
+ }
+ }
+
+ if(workingSet.isEmpty()) {
+ return true;
+ } else {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("These specified heaps do not exist:\n");
+
+ Iterator nameIterator = workingSet.iterator();
+
+ while(nameIterator.hasNext()) {
+ buffer.append("\t\t" + nameIterator.next() + "\n");
+ }
+
+ buffer.append("\tUse \"info heap\" to see list of heap names");
+
+ out.error(buffer.toString());
+
+ return false;
+ }
+ }
+
+ /**
+ * Extracts a minimal version string from the full -version output
+ */
+ private String getVersionString(JavaRuntime runtime)
+ {
+ try {
+ String rawVersion = runtime.getVersion();
+
+ Matcher matcher = J9_VERSION_PATTERN.matcher(rawVersion);
+
+ if(matcher.find()) {
+ String minimalVersion = matcher.group(1);
+ return minimalVersion;
+ } else {
+ _numberOfErrors++;
+ reportError("Could not parse version string: " + rawVersion,null);
+ return rawVersion;
+ }
+ }
+ catch (CorruptDataException e) {
+ _numberOfErrors++;
+ out.error("Could not read version string from dump: data corrupted at "
+ + e.getCorruptData().getAddress());
+ return "*Corrupt*";
+ }
+ }
+
+ private JavaRuntime getRuntime(ImageAddressSpace addressSpace)
+ {
+ ImageProcess process = addressSpace.getCurrentProcess();
+
+ if(process == null) {
+ out.error("Couldn't get handle on current process");
+ return null;
+ }
+
+ Iterator runtimeIterator = process.getRuntimes().iterator();
+
+ if(! runtimeIterator.hasNext()) {
+ out.error("Cannot find a runtime");
+ return null;
+ }
+
+ Object potential = runtimeIterator.next();
+
+ if(potential instanceof CorruptData) {
+ out.error("Runtime data is corrupt");
+ return null;
+ }
+
+ return (JavaRuntime) potential;
+ }
+
+ private void dumpMultipleHeapsInOneFile(JavaRuntime runtime,
+ String version, boolean is64Bit, boolean phdFormat, String filename, Set heapsToDump) throws IOException
+ {
+ Iterator heapIterator = runtime.getHeaps().iterator();
+
+ HeapDumpFormatter formatter = getFormatter(filename, version, is64Bit, phdFormat);
+
+ out.print("Writing " + ( phdFormat ? "PHD" : "Classic") + " format heapdump into " + filename);
+
+ dumpClasses(formatter,runtime);
+
+ while (heapIterator.hasNext()) {
+ Object thisHeapObj = heapIterator.next();
+
+ if (thisHeapObj instanceof CorruptData) {
+ out.error("Corrupt heap data found at: "
+ + ((CorruptData) thisHeapObj).getAddress());
+ _numberOfErrors++;
+ continue;
+ }
+
+ JavaHeap thisHeap = (JavaHeap) thisHeapObj;
+
+ if(heapsToDump.size() > 0 && ! heapsToDump.contains(thisHeap.getName())) {
+ continue;
+ }
+
+ dumpHeap(formatter, thisHeap);
+ }
+
+ formatter.close();
+ }
+
+ private void dumpMultipleHeapsInSeparateFiles(JavaRuntime runtime,String version, boolean is64Bit, boolean phdFormat,String baseFileName, Set heapsToDump) throws IOException
+ {
+ Iterator heapIterator = runtime.getHeaps().iterator();
+
+ HeapDumpFormatter formatter = null;
+
+ while (heapIterator.hasNext()) {
+ Object thisHeapObj = heapIterator.next();
+
+ if (thisHeapObj instanceof CorruptData) {
+ out.error("Heap corrupted at: "
+ + ((CorruptData) thisHeapObj).getAddress());
+ _numberOfErrors++;
+ continue;
+ }
+
+ JavaHeap thisHeap = (JavaHeap) thisHeapObj;
+
+ // Create a new heapdump formatter for every heap we find
+ if (formatter != null) {
+ formatter.close();
+ }
+
+ if(heapsToDump.size() > 0 && ! heapsToDump.contains(thisHeap.getName())) {
+ continue;
+ }
+
+ String fileName = getFileNameForHeap(thisHeap,baseFileName);
+
+ out.print("Writing "
+ + ( phdFormat ? "PHD" : "Classic")
+ + " format heapdump for heap "
+ + thisHeap.getName()
+ + " into "
+ + fileName + "\n");
+
+ formatter = getFormatter(fileName, version, is64Bit, phdFormat);
+
+ //We have to dump classes in every heapdump
+ dumpClasses(formatter,runtime);
+
+ dumpHeap(formatter, thisHeap);
+ }
+
+ if(formatter != null) {
+ formatter.close();
+ }
+ }
+
+ /**
+ * Walks the runtime classes and passes them through the formatter interface
+ */
+ private void dumpClasses(HeapDumpFormatter formatter, JavaRuntime runtime) throws IOException
+ {
+ Iterator classLoaderIt = runtime.getJavaClassLoaders().iterator();
+
+ int numberOfClasses = 0;
+
+ITERATING_LOADERS:while(classLoaderIt.hasNext()) {
+ Object potential = classLoaderIt.next();
+
+ if(potential instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("CorruptData found in classloader list at address: " + ((CorruptData)potential).getAddress(), null);
+ continue ITERATING_LOADERS;
+ }
+
+ JavaClassLoader thisClassLoader = (JavaClassLoader)potential;
+
+ Iterator classesIt = thisClassLoader.getDefinedClasses().iterator();
+
+ITERATING_CLASSES:while(classesIt.hasNext()) {
+ potential = classesIt.next();
+
+ numberOfClasses++;
+
+ try {
+
+ if(potential instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("CorruptData found in class list for classloader "
+ + Long.toHexString(thisClassLoader.getObject().getID().getAddress())
+ + " at address: " + ((CorruptData)potential).getAddress(), null);
+ continue ITERATING_CLASSES;
+ }
+
+ JavaClass thisJavaClass = (JavaClass)potential;
+
+ JavaClass superClass = thisJavaClass.getSuperclass();
+
+ JavaObject classObject = thisJavaClass.getObject();
+
+ int instanceSize = 0;
+
+ if(thisJavaClass.isArray()) {
+ instanceSize = 0;
+ } else {
+ // we need to figure out a way of determining the instance size for a class
+ }
+
+ formatter.addClass(thisJavaClass.getID().getAddress(),
+ thisJavaClass.getName(),
+ superClass != null ? superClass.getID().getAddress() : 0,
+ classObject != null ? (int)classObject.getSize() : 0,
+ instanceSize,
+ classObject != null ? (int)classObject.getPersistentHashcode() : 0,
+ getClassReferences(thisJavaClass) );
+ } catch(DiagnosticException ex) {
+ //Handle CorruptDataException and DataUnavailableException the same way
+ _numberOfErrors++;
+ reportError(null,ex);
+ continue ITERATING_CLASSES;
+ }
+ }
+ }
+
+ _numberOfClasses = numberOfClasses;
+ }
+
+ /**
+ * Walks the supplied heap and passes the artifacts through the formatter
+ */
+ private void dumpHeap(HeapDumpFormatter formatter, JavaHeap thisHeap)
+ throws IOException
+ {
+ Iterator objectIterator = thisHeap.getObjects().iterator();
+
+ while (objectIterator.hasNext()) {
+ Object next = objectIterator.next();
+ _numberOfObjects++;
+
+ if (next instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("Corrupt object data found at " + ((CorruptData)next).getAddress() + " while walking heap " + thisHeap.getName(),null);
+ continue;
+ }
+
+ try {
+ JavaObject thisObject = (JavaObject) next;
+ JavaClass thisClass = thisObject.getJavaClass();
+
+ int hashcode = 0;
+
+ try {
+ hashcode = (int) thisObject.getHashcode();
+ }
+ catch (DataUnavailable ex) {
+ _numberOfErrors++;
+ reportError("Failed to get hashcode for object: " + thisObject.getID(),ex);
+ }
+
+ if (thisObject.isArray()) {
+ if (isPrimitive(thisClass.getComponentType())) {
+ formatter.addPrimitiveArray(thisObject.getID().getAddress(),
+ thisClass.getID().getAddress(),
+ getPrimitiveTypeCode(thisClass.getComponentType()),
+ (int) thisObject.getSize(),
+ hashcode,
+ thisObject.getArraySize());
+ }
+ else {
+
+ formatter.addObjectArray(thisObject.getID().getAddress(),
+ thisClass.getID().getAddress(),
+ thisClass.getName(),
+ thisClass.getComponentType().getID().getAddress(),
+ thisClass.getComponentType().getName(),
+ (int) thisObject.getSize(),
+ thisObject.getArraySize(),
+ hashcode,
+ getObjectReferences(thisObject));
+ }
+ }
+ else {
+ formatter.addObject(thisObject.getID().getAddress(),
+ thisClass.getID().getAddress(),
+ thisClass.getName(),
+ (int)thisObject.getSize(),
+ hashcode,
+ getObjectReferences(thisObject));
+ }
+ }
+ catch (CorruptDataException ex) {
+ _numberOfErrors++;
+ reportError(null,ex);
+ continue;
+ }
+ }
+ }
+
+ /* Reference code reimplemented (rather than using the Kato getReferences() API)
+ * because we are trying to match the behaviour of the runtime heapdump rather than
+ * the GC spec. The set of references we're trying to create is different.
+ */
+
+ /**
+ * Gets the references for the supplied class
+ *
+ * @param thisJavaClass Class being examined
+ */
+ private ReferenceIterator getClassReferences(JavaClass thisJavaClass)
+ {
+ List references = new LinkedList();
+
+ try {
+ //Statics
+ addStaticReferences(thisJavaClass, references);
+
+ addProtectionDomainReference(thisJavaClass,references);
+
+ //Classloader
+ JavaClassLoader loader = thisJavaClass.getClassLoader();
+
+ if(loader != null) {
+ JavaObject loaderObject = loader.getObject();
+ if(loaderObject != null) {
+ references.add(new Long(loaderObject.getID().getAddress()));
+ } else {
+ reportError("Null loader object returned for class: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null);
+ _numberOfErrors++;
+ }
+ } else {
+ reportError("Null classloader returned for class: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null);
+ _numberOfErrors++;
+ }
+
+ //Heap object
+ JavaObject classObject = thisJavaClass.getObject();
+ if(classObject != null) {
+ references.add(new Long(classObject.getID().getAddress()));
+ } else {
+ _numberOfErrors++;
+ reportError("Couldn't get Java class loader for: " + thisJavaClass.getName() + "(" + thisJavaClass.getID() + ")",null);
+ }
+
+ } catch(DiagnosticException ex) {
+ reportError(null,ex);
+ _numberOfErrors++;
+ }
+
+ return new LongListReferenceIterator(references);
+ }
+
+ private JavaField _protectionDomainField;
+
+ private void addProtectionDomainReference(JavaClass thisJavaClass,
+ List references) throws CorruptDataException, MemoryAccessException
+
+ {
+ JavaObject classObject = thisJavaClass.getObject();
+
+ //Protection domain hangs off the protectionDomain field on the class object
+ if(_protectionDomainField == null) {
+ JavaClass javaLangClassObject = classObject.getJavaClass();
+ if(javaLangClassObject == null) {
+ _numberOfErrors++;
+ reportError("Couldn't find java.lang.Class class",null);
+ return;
+ }
+ Iterator fieldsIt = javaLangClassObject.getDeclaredFields().iterator();
+
+ while(fieldsIt.hasNext()) {
+ Object potential = fieldsIt.next();
+
+ if(potential instanceof JavaField) {
+ JavaField field = (JavaField) potential;
+
+ if(field.getName().equals(PROTECTION_DOMAIN_FIELD_NAME)) {
+ _protectionDomainField = field;
+ }
+ } else if(potential instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("CorruptData found walking fields for java.lang.Class. Bad address = "
+ + ((CorruptData)potential).getAddress()
+ ,null);
+ } else {
+ _numberOfErrors++;
+ reportError("Unexpected type "
+ + potential.getClass()
+ + " returned from fields iterator."
+ ,null);
+ }
+ }
+
+ if(_protectionDomainField == null) {
+ _numberOfErrors++;
+ reportError("Couldn't find protection domain field.",null);
+ return;
+ }
+ }
+
+ Object potential = _protectionDomainField.get(classObject);
+
+ if(potential instanceof JavaObject) {
+ JavaObject protectionDomain = (JavaObject)potential;
+
+ references.add(new Long(protectionDomain.getID().getAddress()));
+ } else if (potential instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("Corrupt data found in protectionDomainField of "
+ + thisJavaClass.getName()
+ + " at address "
+ + ((CorruptData)potential).getAddress()
+ ,null);
+ } else if (potential == null) {
+ //Do nothing
+ } else {
+ reportError("Unexpected type: "
+ + potential.getClass().getName()
+ + " found in protectionDomain field of "
+ + thisJavaClass.getName()
+ ,null);
+ _numberOfErrors++;
+ }
+ }
+
+ /**
+ * Extracts static references from class
+ * @param thisClass Class being examined
+ * @param references List to add references to
+ */
+ private void addStaticReferences(JavaClass thisClass, List references)
+ throws CorruptDataException, MemoryAccessException
+ {
+ Iterator fieldsIt = thisClass.getDeclaredFields().iterator();
+
+ while(fieldsIt.hasNext()) {
+ Object potential = fieldsIt.next();
+
+ if(potential instanceof CorruptData) {
+ reportError("Corrupt field found in class "
+ + thisClass.getName()
+ + "(" + thisClass.getID() + ") at "
+ + ((CorruptData)potential).getAddress()
+ ,null);
+ _numberOfErrors++;
+ continue;
+ }
+
+ JavaField field = (JavaField) potential;
+
+ if(! Modifier.isStatic(field.getModifiers())) {
+ continue;
+ }
+
+ Object referent = field.get(thisClass.getObject());
+
+ if(referent instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("Corrupt referent found in class "
+ + thisClass.getName()
+ + "(" + thisClass.getID() + ") from field "
+ + field.getName()
+ + " at address "
+ + ((CorruptData)potential).getAddress()
+ ,null);
+ } else if (referent instanceof JavaObject) {
+ JavaObject referredObject = (JavaObject) referent;
+
+ references.add(new Long(referredObject.getID().getAddress()));
+ } else if (referent == null) {
+ references.add(new Long(0));
+ } else if (referent instanceof Number || referent instanceof Boolean || referent instanceof Character) {
+ //Ignore
+ } else {
+ reportError("Unexpected type: "
+ + referent.getClass().getName()
+ + " returned from field "
+ + field.getName()
+ + " from class "
+ + thisClass.getName()
+ + "(" + thisClass.getID()+ ")"
+ ,null);
+ _numberOfErrors++;
+ }
+ }
+ }
+
+ /**
+ * Gets instance references for objects
+ * @param thisObject Object being examined
+ * @return Iterator of references
+ */
+ private ReferenceIterator getObjectReferences(JavaObject thisObject)
+ {
+ List references = new LinkedList();
+
+ try {
+ JavaClass thisClass = thisObject.getJavaClass();
+
+ if(thisClass.isArray()) {
+ addArrayReferences(thisObject, references);
+ } else {
+ addRegularObjectReferences(thisObject, references,thisClass);
+ }
+ } catch(DiagnosticException ex) {
+ _numberOfErrors++;
+ reportError(null,ex);
+ }
+
+ return new LongListReferenceIterator(references);
+ }
+
+ /**
+ * Extracts the instance references from object arrays
+ * @param arrayObject Array
+ * @param references List to add references to
+ */
+ private void addArrayReferences(JavaObject arrayObject, List references)
+ throws CorruptDataException, MemoryAccessException
+ {
+ JavaObject[] localArray = new JavaObject[arrayObject.getArraySize()];
+ arrayObject.arraycopy(0, localArray, 0, arrayObject.getArraySize());
+
+ for(int i=0;i!=localArray.length;i++) {
+ if(localArray[i] != null) {
+ references.add(new Long(localArray[i].getID().getAddress()));
+ } else {
+ references.add(new Long(0));
+ }
+ }
+ }
+
+ /**
+ * Extracts the instance references from a regular (non-array) object
+ * @param object Object being walked
+ * @param references List to add references to
+ * @param thisClass Class of object
+ */
+ private void addRegularObjectReferences(JavaObject object,
+ List references, JavaClass thisClass) throws CorruptDataException,
+ MemoryAccessException
+ {
+ while(thisClass != null) {
+
+ Iterator fieldsIt = thisClass.getDeclaredFields().iterator();
+
+WALKING_FIELDS: while(fieldsIt.hasNext()) {
+ Object potential = fieldsIt.next();
+
+ if(potential instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("Corrupt data found at address "
+ + ((CorruptData)potential).getAddress()
+ + " walking fields of class: "
+ + thisClass.getName()
+ + "(" + thisClass.getID() + ")"
+ ,null);
+ continue WALKING_FIELDS;
+ }
+
+ JavaField field = (JavaField) potential;
+
+ if(Modifier.isStatic(field.getModifiers())) {
+ continue WALKING_FIELDS;
+ }
+
+ Object referent = field.get(object);
+
+ if(referent instanceof CorruptData) {
+ _numberOfErrors++;
+ reportError("Corrupt data found in referent at address "
+ + ((CorruptData)referent).getAddress()
+ + " walking field "
+ + field.getName()
+ + " of class: "
+ + thisClass.getName()
+ + "(" + thisClass.getID() + ")"
+ ,null);
+ continue WALKING_FIELDS;
+ } else if (referent instanceof JavaObject) {
+ JavaObject referredObject = (JavaObject) referent;
+
+ references.add(new Long(referredObject.getID().getAddress()));
+ } else if (referent == null) {
+ references.add(new Long(0));
+ } else if (referent instanceof Number || referent instanceof Boolean || referent instanceof Character) {
+ //Ignore
+ } else {
+ reportError("Unexpected type: " + referent.getClass().getName() + " found in referent",null);
+ _numberOfErrors++;
+ }
+ }
+
+ thisClass = thisClass.getSuperclass();
+ }
+ }
+
+ /**
+ * Checks if class is primitive
+ *
+ * @param clazz
+ * Class under test
+ * @return True if clazz represents a primitive type, false otherwise
+ */
+ private static boolean isPrimitive(JavaClass clazz)
+ throws CorruptDataException
+ {
+ String name = clazz.getName();
+
+ /* Fastpath, anything containing a / cannot be primitive */
+ if (name.indexOf("/") != -1) {
+ return false;
+ }
+
+ for (int i = 0; i != PRIMITIVE_TYPES.length; i++) {
+ if (PRIMITIVE_TYPES[i].equals(name)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Converts a class into a primitive type code (as used by the HeapdumpFormatter interface).
+ * @param clazz
+ * @return
+ */
+ private int getPrimitiveTypeCode(JavaClass clazz)
+ throws CorruptDataException
+ {
+ String name = clazz.getName();
+
+ for (int i = 0; i != PRIMITIVE_TYPES.length; i++) {
+ if (PRIMITIVE_TYPES[i].equals(name)) {
+ return i;
+ }
+ }
+
+ throw new IllegalArgumentException("Class: " + name
+ + " is not primitive");
+ }
+
+ /**
+ * Factory method for HeapDumpFormatters
+ * @param fileName File name for output file
+ * @param version Version string
+ * @param is64Bit True if 64 bit
+ * @param phdFormat True if using PhD format
+ */
+ private HeapDumpFormatter getFormatter(String fileName, String version,
+ boolean is64Bit, boolean phdFormat) throws IOException
+ {
+ return new ClassicHeapDumpFormatter(new FileWriter(fileName),version,is64Bit);
+ }
+
+ /**
+ * Modifies the base file name to include the heap name, whilst maintaining
+ * the suffix
+ */
+ private String getFileNameForHeap(JavaHeap thisHeap, String baseFileName)
+ {
+ int pointIndex = baseFileName.lastIndexOf(".");
+
+ if(pointIndex != -1) {
+ return baseFileName.substring(0,pointIndex) + "." + thisHeap.getName() + baseFileName.substring(pointIndex);
+ } else {
+ return baseFileName + "." + thisHeap.getName();
+ }
+ }
+
+ /**
+ * Internal error handling routine that only reports the supplied message if verbose was supplied on the command line.
+ */
+ private void reportError(String msg,Throwable t)
+ {
+ //Property set in Session.imageFromCommandLine when -verbose specified on command line
+ if(!_verbose) {
+ return;
+ }
+
+ if(msg != null) {
+ out.error(msg);
+ }
+
+ if(t != null) {
+ StringWriter writer = new StringWriter();
+
+ t.printStackTrace(new PrintWriter(writer));
+
+ out.error(writer.toString());
+ }
+ }
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HeapdumpCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HelpCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HelpCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HelpCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HelpCommand.java Mon Nov 23 15:53:48 2009
@@ -1,48 +1,48 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.util.HashMap;
-import java.util.Stack;
-
-import javax.tools.diagnostics.image.Image;
-
-import org.apache.kato.katoview.Output;
-
-
-public class HelpCommand extends Command {
-
- private RootCommand rootCommand;
-
- public HelpCommand(Output o, RootCommand r){
- super(o, "help", "displays list of commands or help for a specific command",
- "parameters: none, <command_name>\n\n" +
- "With no parameters, \"help\" displays the complete list of commands " +
- "currently supported. When a <command_name> is specified, \"help\" " +
- "will list that command's sub-commands if it has sub-commands; " +
- "otherwise, the command's complete description will be displayed.\n\n" +
- "To view help on a command's sub-command, specify both the command " +
- "name and the sub-command name. For example, \"help info thread\" " +
- "will display \"info thread\"'s description."
- );
- child_commands = null;
-
- rootCommand = r;
- }
-
- public void doCommand(Stack args, Image loadedImage, HashMap properties)
- {
- rootCommand.printHelp("\t", 11, args, new Stack());
- }
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import javax.tools.diagnostics.image.Image;
+
+import org.apache.kato.katoview.Output;
+
+
+public class HelpCommand extends Command {
+
+ private RootCommand rootCommand;
+
+ public HelpCommand(Output o, RootCommand r){
+ super(o, "help", "displays list of commands or help for a specific command",
+ "parameters: none, <command_name>\n\n" +
+ "With no parameters, \"help\" displays the complete list of commands " +
+ "currently supported. When a <command_name> is specified, \"help\" " +
+ "will list that command's sub-commands if it has sub-commands; " +
+ "otherwise, the command's complete description will be displayed.\n\n" +
+ "To view help on a command's sub-command, specify both the command " +
+ "name and the sub-command name. For example, \"help info thread\" " +
+ "will display \"info thread\"'s description."
+ );
+ child_commands = null;
+
+ rootCommand = r;
+ }
+
+ public void doCommand(Stack args, Image loadedImage, HashMap properties)
+ {
+ rootCommand.printHelp("\t", 11, args, new Stack());
+ }
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HelpCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HexdumpCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HexdumpCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HexdumpCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HexdumpCommand.java Mon Nov 23 15:53:48 2009
@@ -1,153 +1,153 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.util.HashMap;
-import java.util.Stack;
-
-import javax.tools.diagnostics.image.CorruptDataException;
-import javax.tools.diagnostics.image.Image;
-import javax.tools.diagnostics.image.ImageAddressSpace;
-import javax.tools.diagnostics.image.ImagePointer;
-import javax.tools.diagnostics.image.MemoryAccessException;
-
-import org.apache.kato.katoview.Output;
-import org.apache.kato.katoview.commands.helpers.Utils;
-
-
-public class HexdumpCommand extends Command {
-
- public HexdumpCommand(Output o){
- super(o, "hexdump", "outputs a section of memory in a hexdump-like format",
- "parameters: <hex_address> <bytes_to_print>\n\n" +
- "outputs <bytes_to_print> bytes of memory contents " +
- "starting from <hex_address>"
- );
- child_commands = null;
- }
-
- public void doCommand(Stack args, Image loadedImage, HashMap properties){
- StringBuffer stringBuffer = new StringBuffer();
- ImageAddressSpace imageAddressSpace = Utils._extractAddressSpace(loadedImage);
- long addressInDecimal = 0;
- int numBytesToPrint = 16*16; //dump 256 bytes by default
- int asciiIndex = 0;
-
- if (!args.isEmpty()){
- Long address = Utils.longFromString((String)args.pop());
- if(null == address){
- out.error("Specified address is invalid");
- return;
- }
- addressInDecimal = address.longValue();
- }
- else
- {
- out.error("\"hexdump\" requires at least an address parameter");
- return;
- }
-
- if (!args.isEmpty()){
- try{
- numBytesToPrint = Integer.parseInt((String)args.pop());
- }catch(NumberFormatException nfe){
- out.error("Specified length is invalid");
- return;
- }
- }
-
- ImagePointer imagePointerBase = imageAddressSpace.getPointer(addressInDecimal);
-
- String asciiChars = "";
-
- long i;
- for (i = 0; i < numBytesToPrint; i++){
- ImagePointer imagePointer = imagePointerBase.add(i);
- //stringBuffer.append(Long.toHexString(addressInDecimal+i)+":\t");
- //stringBuffer.append(Long.toHexString(imagePointer.getAddress())+":\t");
- try {
- Byte byteValue = new Byte(imagePointer.getByteAt(0));
- asciiIndex = (int) byteValue.byteValue();
- if (asciiIndex < 0) {
- asciiIndex += 256;
- }
-
- String rawHexString = Integer.toHexString(byteValue.intValue());
- String fixedHexString = fixHexStringLength(rawHexString);
-
- String hexText = fixedHexString;
- if (0 == i%4){
- hexText = " "+hexText;
- }
-
- if (0 == i%16){
- hexText = "\n"+Long.toHexString(imagePointer.getAddress())+":"+hexText;
- asciiChars = " |";
- }
-
- stringBuffer.append(hexText);
-
- asciiChars += Utils.byteToAscii.substring(asciiIndex,asciiIndex+1);
- if (15 == i%16 && i != 0){
- asciiChars += "|";
- //System.out.println("****"+asciiChars);
- stringBuffer.append(asciiChars);
- }
- }catch (MemoryAccessException e) {
- out.error("Address not in memory - 0x"
- + Long.toHexString(imagePointer.getAddress()));
- return;
- }catch (CorruptDataException e) {
- out.error("Dump data is corrupted");
- return;
- }
- }
-
- long undisplayedBytes = 16 - i%16;
- if (16 != undisplayedBytes){
- stringBuffer.append(padSpace(undisplayedBytes, asciiChars));
- }
- stringBuffer.append("\n");
- out.println(new String(stringBuffer));
-
- /*properties.put(Utils.CURRENT_MEM_ADDRESS,
- Long.toHexString(addressInDecimal+numBytesToPrint));*/
- properties.put(Utils.CURRENT_MEM_ADDRESS, new Long(addressInDecimal));
- properties.put(Utils.CURRENT_NUM_BYTES_TO_PRINT, new Integer(numBytesToPrint));
- }
-
- private String padSpace(long undisplayedBytes, String asciiChars){
- for (int i = 0; i < 2*undisplayedBytes + undisplayedBytes/4; i++){
- asciiChars = " " + asciiChars;
- }
- return asciiChars;
- }
-
- private String fixHexStringLength(String rawHexString){
- int length = rawHexString.length();
- if (1 == length){
- return ("0" + rawHexString);
- }
- else if (2 == length){
- return rawHexString;
- }
- else if (8 == length){
- return rawHexString.substring(6, 8);
- }
- else{
- return "ERROR fixHexStringLength";
- }
- }
-
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import javax.tools.diagnostics.image.CorruptDataException;
+import javax.tools.diagnostics.image.Image;
+import javax.tools.diagnostics.image.ImageAddressSpace;
+import javax.tools.diagnostics.image.ImagePointer;
+import javax.tools.diagnostics.image.MemoryAccessException;
+
+import org.apache.kato.katoview.Output;
+import org.apache.kato.katoview.commands.helpers.Utils;
+
+
+public class HexdumpCommand extends Command {
+
+ public HexdumpCommand(Output o){
+ super(o, "hexdump", "outputs a section of memory in a hexdump-like format",
+ "parameters: <hex_address> <bytes_to_print>\n\n" +
+ "outputs <bytes_to_print> bytes of memory contents " +
+ "starting from <hex_address>"
+ );
+ child_commands = null;
+ }
+
+ public void doCommand(Stack args, Image loadedImage, HashMap properties){
+ StringBuffer stringBuffer = new StringBuffer();
+ ImageAddressSpace imageAddressSpace = Utils._extractAddressSpace(loadedImage);
+ long addressInDecimal = 0;
+ int numBytesToPrint = 16*16; //dump 256 bytes by default
+ int asciiIndex = 0;
+
+ if (!args.isEmpty()){
+ Long address = Utils.longFromString((String)args.pop());
+ if(null == address){
+ out.error("Specified address is invalid");
+ return;
+ }
+ addressInDecimal = address.longValue();
+ }
+ else
+ {
+ out.error("\"hexdump\" requires at least an address parameter");
+ return;
+ }
+
+ if (!args.isEmpty()){
+ try{
+ numBytesToPrint = Integer.parseInt((String)args.pop());
+ }catch(NumberFormatException nfe){
+ out.error("Specified length is invalid");
+ return;
+ }
+ }
+
+ ImagePointer imagePointerBase = imageAddressSpace.getPointer(addressInDecimal);
+
+ String asciiChars = "";
+
+ long i;
+ for (i = 0; i < numBytesToPrint; i++){
+ ImagePointer imagePointer = imagePointerBase.add(i);
+ //stringBuffer.append(Long.toHexString(addressInDecimal+i)+":\t");
+ //stringBuffer.append(Long.toHexString(imagePointer.getAddress())+":\t");
+ try {
+ Byte byteValue = new Byte(imagePointer.getByteAt(0));
+ asciiIndex = (int) byteValue.byteValue();
+ if (asciiIndex < 0) {
+ asciiIndex += 256;
+ }
+
+ String rawHexString = Integer.toHexString(byteValue.intValue());
+ String fixedHexString = fixHexStringLength(rawHexString);
+
+ String hexText = fixedHexString;
+ if (0 == i%4){
+ hexText = " "+hexText;
+ }
+
+ if (0 == i%16){
+ hexText = "\n"+Long.toHexString(imagePointer.getAddress())+":"+hexText;
+ asciiChars = " |";
+ }
+
+ stringBuffer.append(hexText);
+
+ asciiChars += Utils.byteToAscii.substring(asciiIndex,asciiIndex+1);
+ if (15 == i%16 && i != 0){
+ asciiChars += "|";
+ //System.out.println("****"+asciiChars);
+ stringBuffer.append(asciiChars);
+ }
+ }catch (MemoryAccessException e) {
+ out.error("Address not in memory - 0x"
+ + Long.toHexString(imagePointer.getAddress()));
+ return;
+ }catch (CorruptDataException e) {
+ out.error("Dump data is corrupted");
+ return;
+ }
+ }
+
+ long undisplayedBytes = 16 - i%16;
+ if (16 != undisplayedBytes){
+ stringBuffer.append(padSpace(undisplayedBytes, asciiChars));
+ }
+ stringBuffer.append("\n");
+ out.println(new String(stringBuffer));
+
+ /*properties.put(Utils.CURRENT_MEM_ADDRESS,
+ Long.toHexString(addressInDecimal+numBytesToPrint));*/
+ properties.put(Utils.CURRENT_MEM_ADDRESS, new Long(addressInDecimal));
+ properties.put(Utils.CURRENT_NUM_BYTES_TO_PRINT, new Integer(numBytesToPrint));
+ }
+
+ private String padSpace(long undisplayedBytes, String asciiChars){
+ for (int i = 0; i < 2*undisplayedBytes + undisplayedBytes/4; i++){
+ asciiChars = " " + asciiChars;
+ }
+ return asciiChars;
+ }
+
+ private String fixHexStringLength(String rawHexString){
+ int length = rawHexString.length();
+ if (1 == length){
+ return ("0" + rawHexString);
+ }
+ else if (2 == length){
+ return rawHexString;
+ }
+ else if (8 == length){
+ return rawHexString.substring(6, 8);
+ }
+ else{
+ return "ERROR fixHexStringLength";
+ }
+ }
+
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/HexdumpCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/InfoCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/InfoCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/InfoCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/InfoCommand.java Mon Nov 23 15:53:48 2009
@@ -1,48 +1,48 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.util.Vector;
-
-import org.apache.kato.katoview.Output;
-import org.apache.kato.katoview.commands.infocommands.InfoClassCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoHeapCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoJitmCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoLockCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoMmapCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoProcCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoPropertyCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoSymCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoSystemCommand;
-import org.apache.kato.katoview.commands.infocommands.InfoThreadCommand;
-
-
-public class InfoCommand extends Command{
-
- public InfoCommand(Output o){
- super(o, "info", "", "");
-
- child_commands = new Vector();
- child_commands.add(new InfoThreadCommand(o));
- child_commands.add(new InfoSystemCommand(o));
- child_commands.add(new InfoClassCommand(o));
- child_commands.add(new InfoProcCommand(o));
- child_commands.add(new InfoJitmCommand(o));
- child_commands.add(new InfoLockCommand(o));
- child_commands.add(new InfoSymCommand(o));
- child_commands.add(new InfoMmapCommand(o));
- child_commands.add(new InfoHeapCommand(o));
- child_commands.add(new InfoPropertyCommand(o));
- }
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.util.Vector;
+
+import org.apache.kato.katoview.Output;
+import org.apache.kato.katoview.commands.infocommands.InfoClassCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoHeapCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoJitmCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoLockCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoMmapCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoProcCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoPropertyCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoSymCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoSystemCommand;
+import org.apache.kato.katoview.commands.infocommands.InfoThreadCommand;
+
+
+public class InfoCommand extends Command{
+
+ public InfoCommand(Output o){
+ super(o, "info", "", "");
+
+ child_commands = new Vector();
+ child_commands.add(new InfoThreadCommand(o));
+ child_commands.add(new InfoSystemCommand(o));
+ child_commands.add(new InfoClassCommand(o));
+ child_commands.add(new InfoProcCommand(o));
+ child_commands.add(new InfoJitmCommand(o));
+ child_commands.add(new InfoLockCommand(o));
+ child_commands.add(new InfoSymCommand(o));
+ child_commands.add(new InfoMmapCommand(o));
+ child_commands.add(new InfoHeapCommand(o));
+ child_commands.add(new InfoPropertyCommand(o));
+ }
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/InfoCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/MinusCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/MinusCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/MinusCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/MinusCommand.java Mon Nov 23 15:53:48 2009
@@ -1,40 +1,40 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.util.HashMap;
-import java.util.Stack;
-
-import javax.tools.diagnostics.image.Image;
-
-import org.apache.kato.katoview.Output;
-
-
-public class MinusCommand extends Command{
-
- public MinusCommand(Output o){
- super(o, "-", "displays the previous section of memory in hexdump-like format",
- "parameters: none\n\n" +
- "The - command is used in conjunction with the hexdump command " +
- "to allow easy scrolling backwards through memory. It repeats " +
- "the previous hexdump command starting from a position " +
- "before the previous one."
- );
- child_commands = null;
- }
-
- public void doCommand(Stack args, Image loadedImage, HashMap properties){
- doScrollCommand(loadedImage, properties, false);
- }
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import javax.tools.diagnostics.image.Image;
+
+import org.apache.kato.katoview.Output;
+
+
+public class MinusCommand extends Command{
+
+ public MinusCommand(Output o){
+ super(o, "-", "displays the previous section of memory in hexdump-like format",
+ "parameters: none\n\n" +
+ "The - command is used in conjunction with the hexdump command " +
+ "to allow easy scrolling backwards through memory. It repeats " +
+ "the previous hexdump command starting from a position " +
+ "before the previous one."
+ );
+ child_commands = null;
+ }
+
+ public void doCommand(Stack args, Image loadedImage, HashMap properties){
+ doScrollCommand(loadedImage, properties, false);
+ }
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/MinusCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PlusCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PlusCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PlusCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PlusCommand.java Mon Nov 23 15:53:48 2009
@@ -1,40 +1,40 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.util.HashMap;
-import java.util.Stack;
-
-import javax.tools.diagnostics.image.Image;
-
-import org.apache.kato.katoview.Output;
-
-
-public class PlusCommand extends Command{
-
- public PlusCommand(Output o){
- super(o, "+", "displays the next section of memory in hexdump-like format",
- "parameters: none\n\n" +
- "The + command is used in conjunction with the hexdump command " +
- "to allow easy scrolling forwards through memory. It repeats the " +
- "previous hexdump command starting from the end of the previous one."
- );
- child_commands = null;
- }
-
- public void doCommand(Stack args, Image loadedImage, HashMap properties){
- doScrollCommand(loadedImage, properties, true);
- }
-
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.util.HashMap;
+import java.util.Stack;
+
+import javax.tools.diagnostics.image.Image;
+
+import org.apache.kato.katoview.Output;
+
+
+public class PlusCommand extends Command{
+
+ public PlusCommand(Output o){
+ super(o, "+", "displays the next section of memory in hexdump-like format",
+ "parameters: none\n\n" +
+ "The + command is used in conjunction with the hexdump command " +
+ "to allow easy scrolling forwards through memory. It repeats the " +
+ "previous hexdump command starting from the end of the previous one."
+ );
+ child_commands = null;
+ }
+
+ public void doCommand(Stack args, Image loadedImage, HashMap properties){
+ doScrollCommand(loadedImage, properties, true);
+ }
+
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PlusCommand.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PwdCommand.java
URL: http://svn.apache.org/viewvc/incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PwdCommand.java?rev=883384&r1=883383&r2=883384&view=diff
==============================================================================
--- incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PwdCommand.java (original)
+++ incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PwdCommand.java Mon Nov 23 15:53:48 2009
@@ -1,50 +1,50 @@
-/*******************************************************************************
- * 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 org.apache.kato.katoview.commands;
-
-import java.util.HashMap;
-import java.util.Stack;
-import java.io.File;
-
-import javax.tools.diagnostics.image.Image;
-
-import org.apache.kato.katoview.Output;
-
-
-public class PwdCommand extends Command {
-
- public PwdCommand(Output o){
- super(o, "pwd", "displays the current working directory",
- "parameters: none\n\n" +
- "displays the current working directory, which is the directory " +
- "where log files are stored; see the help for \"cd\" for more " +
- "information\n"
- );
- child_commands = null;
- }
-
- public void doCommand(Stack args, Image loadedImage, HashMap properties){
- if (!args.isEmpty())
- {
- out.error("\"pwd\" does not take any parameters");
- return;
- }
-
- File pwd = (File)properties.get("pwd");
-
- out.print("\n");
- out.print("\t" + pwd.getPath());
- out.print("\n\n");
- }
-}
+/*******************************************************************************
+ * 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 org.apache.kato.katoview.commands;
+
+import java.util.HashMap;
+import java.util.Stack;
+import java.io.File;
+
+import javax.tools.diagnostics.image.Image;
+
+import org.apache.kato.katoview.Output;
+
+
+public class PwdCommand extends Command {
+
+ public PwdCommand(Output o){
+ super(o, "pwd", "displays the current working directory",
+ "parameters: none\n\n" +
+ "displays the current working directory, which is the directory " +
+ "where log files are stored; see the help for \"cd\" for more " +
+ "information\n"
+ );
+ child_commands = null;
+ }
+
+ public void doCommand(Stack args, Image loadedImage, HashMap properties){
+ if (!args.isEmpty())
+ {
+ out.error("\"pwd\" does not take any parameters");
+ return;
+ }
+
+ File pwd = (File)properties.get("pwd");
+
+ out.print("\n");
+ out.print("\t" + pwd.getPath());
+ out.print("\n\n");
+ }
+}
Propchange: incubator/kato/trunk/org.apache.kato/kato.tools.katoview/src/main/java/org/apache/kato/katoview/commands/PwdCommand.java
------------------------------------------------------------------------------
svn:eol-style = native