Search in sources :

Example 11 with MemoryAccessException

use of com.ibm.dtfj.image.MemoryAccessException in project openj9 by eclipse.

the class JavaObject method getArraySize.

/* (non-Javadoc)
	 * @see com.ibm.dtfj.java.JavaObject#getArraySize()
	 */
public int getArraySize() throws CorruptDataException {
    JavaClass isa = getJavaClass();
    if (isa instanceof JavaArrayClass) {
        JavaArrayClass blueprint = (JavaArrayClass) isa;
        int offset = blueprint.getSizeOffset();
        int numberOfSizeBytes = blueprint.getNumberOfSizeBytes();
        try {
            int numberOfElements = 0;
            if (4 == numberOfSizeBytes) {
                // read an int
                numberOfElements = _basePointer.getIntAt(offset);
            } else if (8 == numberOfSizeBytes) {
                // read a long
                long longCount = _basePointer.getLongAt(offset);
                // the spec says to return an int here so we just truncate, for now
                numberOfElements = (int) longCount;
                if (((long) numberOfElements) != longCount) {
                    System.err.println("Error:  Array element count overflow or underflow.");
                }
            } else {
                // not sure what this is (this could be done generically but that would require exposing endian-conversion differently.  Besides, stopping this at a strange number is probably a good idea since it is more likely an error)
                System.err.println("Error:  unable to read array size as we weren't expecting to read " + numberOfSizeBytes + " bytes.");
            }
            return numberOfElements;
        } catch (MemoryAccessException e) {
            throw new CorruptDataException(new CorruptData("unable to read the number of elements", _basePointer.add(offset)));
        }
    } else {
        throw new IllegalArgumentException();
    }
}
Also used : JavaClass(com.ibm.dtfj.java.JavaClass) CorruptData(com.ibm.dtfj.image.j9.CorruptData) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException)

Example 12 with MemoryAccessException

use of com.ibm.dtfj.image.MemoryAccessException in project openj9 by eclipse.

the class JavaObject method getJavaClass.

/* (non-Javadoc)
	 * @see com.ibm.dtfj.java.JavaObject#getJavaClass()
	 */
public JavaClass getJavaClass() throws CorruptDataException {
    if (0 != _basePointer.getAddress()) {
        ImagePointer classPointer;
        if (_containingHeap == null)
            throw new CorruptDataException(new CorruptData("unable to access class pointer as containing heap is null", _basePointer));
        try {
            classPointer = _containingHeap.readClassPointerRelativeTo(_basePointer);
        } catch (MemoryAccessException e) {
            throw new CorruptDataException(new CorruptData("unable to access class pointer", _basePointer));
        }
        long classID = classPointer.getAddress();
        /* CMVC 167379: Lowest few bits of the class id are used as flags, and should be 
			 * masked with ~(J9_REQUIRED_CLASS_ALIGNMENT - 1) to find real class id. 
			 */
        long classAlignment = _containingHeap.getClassAlignment();
        long alignedClassID = classID;
        if (classAlignment > 0) {
            alignedClassID &= (~(classAlignment - 1L));
        }
        JavaClass ret = _javaVM.getClassForID(alignedClassID);
        if (ret == null) {
            throw new CorruptDataException(new CorruptData("Unknown class ID " + Long.toHexString(alignedClassID) + " for object " + Long.toHexString(_basePointer.getAddress()) + " (read class ID from " + Long.toHexString(classPointer.getAddress()) + ", in memory value was " + Long.toHexString(classID) + ")", _basePointer));
        }
        return ret;
    } else {
        throw new NullPointerException();
    }
}
Also used : ImagePointer(com.ibm.dtfj.image.ImagePointer) JavaClass(com.ibm.dtfj.java.JavaClass) CorruptData(com.ibm.dtfj.image.j9.CorruptData) CorruptDataException(com.ibm.dtfj.image.CorruptDataException) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException)

Example 13 with MemoryAccessException

use of com.ibm.dtfj.image.MemoryAccessException in project openj9 by eclipse.

the class JavaObject method getSections.

/* (non-Javadoc)
	 * @see com.ibm.dtfj.java.JavaObject#getSections()
	 */
public Iterator getSections() {
    // (not initialized so that code paths will be compiler-validated)
    List sections;
    // arraylets have a more complicated scheme so handle them differently
    if (isArraylet()) {
        try {
            JavaArrayClass arrayForm = (JavaArrayClass) getJavaClass();
            // the first element comes immediately after the header so the offset to it is the size of the header
            // NOTE:  this header size does NOT count arraylet leaves
            int objectHeaderSize = arrayForm.getFirstElementOffset();
            // we require the pointer size in order to walk the leaf pointers in the spine
            int bytesPerPointer = _javaVM.bytesPerPointer();
            try {
                int instanceSize = arrayForm.getInstanceSize(this);
                // the instance size will include the header and the actual data inside the array so seperate them
                long contentDataSize = (long) (instanceSize - objectHeaderSize);
                // get the number of leaves, excluding the tail leaf (the tail leaf is the final leaf which points back into the spine).  There won't be one if there is isn't a remainder in this calculation since it would be empty
                int fullSizeLeaves = (int) (contentDataSize / _arrayletLeafSize);
                // find out how big the tail leaf would be
                long tailLeafSize = contentDataSize % _arrayletLeafSize;
                // if it is non-zero, we know that there must be one (bear in mind the fact that all arraylets have at least 1 leaf pointer - consider empty arrays)
                int totalLeafCount = (0 == tailLeafSize) ? fullSizeLeaves : (fullSizeLeaves + 1);
                // CMVC 153943 : DTFJ fix for zero-length arraylets - remove code to add 1 to the leaf count in the event that it is 0.
                // by always assuming there is a leaf means that when the image sections are determined it will cause an error as there
                // is no space allocated in this instace beyond the size of the spine.
                String nestedType = arrayForm.getLeafClass().getName();
                // 4-byte object alignment in realtime requires the long and double arraylets have padding which may need to be placed before the array data or after, depending on if the alignment succeeded at a natural boundary or not
                boolean alignmentCandidate = (4 == _objectAlignment) && ("double".equals(nestedType) || "long".equals(nestedType));
                // we will need a size for the section which includes the spine (and potentially the tail leaf or even all the leaves (in immortal))
                // start with the object header and the leaves
                long headerAndLeafPointers = objectHeaderSize + (totalLeafCount * bytesPerPointer);
                long spineSectionSize = headerAndLeafPointers;
                // we will now walk the leaves to see if this is an inline arraylet
                // first off, see if we would need padding to align the first inline data element
                long nextExpectedInteriorLeafAddress = _basePointer.getAddress() + headerAndLeafPointers;
                boolean doesHaveTailPadding = false;
                if (alignmentCandidate && (totalLeafCount > 0)) {
                    // alignment candidates need to have at least 1 leaf otherwise there is nothing to align
                    if (0 == (nextExpectedInteriorLeafAddress % 8)) {
                        // no need to add extra space here so the extra slot will be at the tail
                        doesHaveTailPadding = true;
                    } else {
                        // we need to bump up our expected location for alignment
                        nextExpectedInteriorLeafAddress += 4;
                        spineSectionSize += 4;
                        if (0 != (nextExpectedInteriorLeafAddress % 8)) {
                            // this can't happen so the core is corrupt
                            throw new CorruptDataException(new CorruptData("Arraylet leaf pointer misaligned for object", _basePointer));
                        }
                    }
                }
                Vector externalSections = null;
                for (int i = 0; i < totalLeafCount; i++) {
                    ImagePointer leafPointer = _basePointer.getPointerAt(objectHeaderSize + (i * bytesPerPointer));
                    if (leafPointer.getAddress() == nextExpectedInteriorLeafAddress) {
                        // this pointer is interior so add it to the spine section
                        long internalLeafSize = _arrayletLeafSize;
                        if (fullSizeLeaves == i) {
                            // this is the last leaf so get the tail leaf size
                            internalLeafSize = tailLeafSize;
                        }
                        spineSectionSize += internalLeafSize;
                        nextExpectedInteriorLeafAddress += internalLeafSize;
                    } else {
                        // this pointer is exterior so make it its own section
                        if (null == externalSections) {
                            externalSections = new Vector();
                        }
                        externalSections.add(new JavaObjectImageSection(leafPointer, _arrayletLeafSize));
                    }
                }
                if (doesHaveTailPadding) {
                    // now, add the extra 4 bytes to the end
                    spineSectionSize += 4;
                }
                // ensure that we are at least the minimum object size
                spineSectionSize = Math.max(spineSectionSize, _arrayletSpineSize);
                JavaObjectImageSection spineSection = new JavaObjectImageSection(_basePointer, spineSectionSize);
                if (null == externalSections) {
                    // create the section list, with the spine first (other parts of our implementation use the knowledge that the spine is first to reduce logic duplication)
                    sections = Collections.singletonList(spineSection);
                } else {
                    sections = new Vector();
                    sections.add(spineSection);
                    sections.addAll(externalSections);
                }
            } catch (MemoryAccessException e) {
                // if we had a memory access exception, the spine must be corrupt, or something
                sections = Collections.singletonList(new CorruptData("failed to walk arraylet spine", e.getPointer()));
            }
        } catch (CorruptDataException e) {
            sections = Collections.singletonList(e.getCorruptData());
        }
    } else {
        // currently J9 objects are atomic extents of memory but that changes with metronome and that will probably extend to other VM configurations, as well
        long size = 0;
        try {
            size = ((com.ibm.dtfj.java.j9.JavaAbstractClass) getJavaClass()).getInstanceSize(this);
            JavaObjectImageSection section = new JavaObjectImageSection(_basePointer, size);
            sections = Collections.singletonList(section);
        } catch (CorruptDataException e) {
            sections = Collections.singletonList(e.getCorruptData());
        }
    // XXX - handle the case of this corrupt data better (may require API change)
    }
    return sections.iterator();
}
Also used : CorruptDataException(com.ibm.dtfj.image.CorruptDataException) ImagePointer(com.ibm.dtfj.image.ImagePointer) ArrayList(java.util.ArrayList) List(java.util.List) CorruptData(com.ibm.dtfj.image.j9.CorruptData) Vector(java.util.Vector) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException)

Example 14 with MemoryAccessException

use of com.ibm.dtfj.image.MemoryAccessException in project openj9 by eclipse.

the class DTFJMethod method handleException.

/**
 * Handle an exception thrown by the DTFJ API.
 *
 * @param cmd the command current executing the API. This is required to provide access to context information.
 * @param cause exception to be handled
 * @return textual data to be written out
 */
public static String handleException(BaseJdmpviewCommand cmd, Throwable cause) {
    ctx = cmd.ctx;
    StringBuffer sb = new StringBuffer();
    // Try and determine the artifact type
    StackTraceElement[] myStack = cause.getStackTrace();
    ArtifactType artifactType = cmd.getArtifactType();
    String artifactTypeName = null;
    switch(artifactType) {
        case core:
            artifactTypeName = "core";
            break;
        case javacore:
            artifactTypeName = "javacore";
            break;
        case phd:
            artifactTypeName = "phd";
            break;
        default:
            artifactTypeName = "Unknown artifact type";
            break;
    }
    // Let's find out which DTFJ Class/Method was being used
    DTFJMethod dMethod = getDTFJMethod(myStack, cmd);
    if (cause instanceof DataUnavailable) {
        if (dMethod == null) {
            sb.append("Could not determine DTFJ class/method that caused this exception: ");
            sb.append(cause.getLocalizedMessage());
        } else if (dMethod.isSupported(artifactType) == WORKS) {
            sb.append(dMethod.getClassName());
            sb.append(".");
            sb.append(dMethod.getMethodname());
            sb.append(" should have worked for a ");
            sb.append(artifactTypeName);
            sb.append(" but returned: ");
            sb.append(cause.getLocalizedMessage());
        } else if (dMethod.isSupported(artifactType) == CAN_FAIL) {
            sb.append(dMethod.getClassName());
            sb.append(".");
            sb.append(dMethod.getMethodname());
            sb.append(" can fail for a ");
            sb.append(artifactTypeName);
            sb.append(" which is why it returned: ");
            sb.append(cause.getLocalizedMessage());
        } else if (dMethod.isSupported(artifactType) == FAILS) {
            sb.append(dMethod.getClassName());
            sb.append(".");
            sb.append(dMethod.getMethodname());
            sb.append(" is not supported for a ");
            sb.append(artifactTypeName);
            String s = cause.getLocalizedMessage();
            if (s != null) {
                sb.append(" causing: ");
                sb.append(s);
            }
        }
    } else if (cause instanceof CorruptDataException) {
        CorruptData corruptData = ((CorruptDataException) cause).getCorruptData();
        ImagePointer ip = corruptData.getAddress();
        if (ip == null) {
            sb.append("CorruptData found in dump at unknown address executing ");
            if (dMethod == null) {
                sb.append("an unknown class/method that caused this exception: ");
                sb.append(cause.getLocalizedMessage());
            } else {
                sb.append(dMethod.getClassName());
                sb.append(".");
                sb.append(dMethod.getMethodname());
            }
        } else {
            String addr = cmd.toHexStringAddr(ip.getAddress());
            sb.append("CorruptData found in dump at address: ");
            sb.append(addr);
            sb.append(" causing: ");
            sb.append(cause.getLocalizedMessage());
            if (dMethod != null) {
                sb.append(" executing ");
                sb.append(dMethod.getClassName());
                sb.append(".");
                sb.append(dMethod.getMethodname());
            }
        }
    } else if (cause instanceof MemoryAccessException) {
        sb.append(cause.getLocalizedMessage());
    } else if (cause instanceof IllegalArgumentException) {
        sb.append(cause.getLocalizedMessage());
    } else {
        // If we are here then something bad has really happened
        // This is just debug code to help determine other problems this
        // method has to deal with
        sb.append("==========> Unexpected exception " + cause.getClass().getName() + " thrown: " + cause.getLocalizedMessage());
        StringWriter st = new StringWriter();
        cause.printStackTrace(new PrintWriter(st));
        sb.append(st.toString());
    }
    return sb.toString();
}
Also used : CorruptDataException(com.ibm.dtfj.image.CorruptDataException) ImagePointer(com.ibm.dtfj.image.ImagePointer) StringWriter(java.io.StringWriter) ArtifactType(com.ibm.jvm.dtfjview.commands.BaseJdmpviewCommand.ArtifactType) DataUnavailable(com.ibm.dtfj.image.DataUnavailable) CorruptData(com.ibm.dtfj.image.CorruptData) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException) PrintWriter(java.io.PrintWriter)

Example 15 with MemoryAccessException

use of com.ibm.dtfj.image.MemoryAccessException in project openj9 by eclipse.

the class JavaClass method getReferences.

/* (non-Javadoc)
	 * @see com.ibm.dtfj.java.JavaClass#getReferences()
	 */
public Iterator getReferences() {
    // need to build a list of references from this class.
    Vector references = new Vector();
    JavaReference jRef = null;
    // get the Constant Pool references from this class.
    Iterator constantPoolIt = getConstantPoolReferences();
    while (constantPoolIt.hasNext()) {
        // get each reference in turn, note that the iterator can return JavaClass
        // JavaObject and CorruptData. The CorruptData objects are ignored.
        Object cpObject = constantPoolIt.next();
        if (cpObject instanceof JavaObject) {
            // add the reference to the container.
            jRef = new JavaReference(_javaVM, this, cpObject, "Constant Pool Object", JavaReference.REFERENCE_CONSTANT_POOL, JavaReference.HEAP_ROOT_UNKNOWN, JavaReference.REACHABILITY_STRONG);
        } else if (cpObject instanceof JavaClass) {
            // got a JavaClass
            JavaClass jClass = (JavaClass) cpObject;
            // add the reference to the container.
            jRef = new JavaReference(_javaVM, this, jClass, "Constant Pool Class", JavaReference.REFERENCE_CONSTANT_POOL, JavaReference.HEAP_ROOT_UNKNOWN, JavaReference.REACHABILITY_STRONG);
        }
        if (null != jRef) {
            references.add(jRef);
        }
    }
    // get the static field references from this class.
    Iterator declaredFieldIt = getDeclaredFields();
    while (declaredFieldIt.hasNext()) {
        JavaField jField = (JavaField) declaredFieldIt.next();
        // got a field, now test it to see if it is a static reference.
        if (jField instanceof JavaStaticField) {
            JavaStaticField sField = (JavaStaticField) jField;
            try {
                Object obj = sField.getReferenceType(null);
                if (null != obj) {
                    if (obj instanceof JavaObject) {
                        // build a JavaReference type and add the reference to the container.
                        String fieldName = sField.getName();
                        String description = "Static field";
                        if (null != fieldName) {
                            description = description + " [field name:" + fieldName + "]";
                        }
                        JavaObject jObject = (JavaObject) obj;
                        jRef = new JavaReference(_javaVM, this, jObject, description, JavaReference.REFERENCE_STATIC_FIELD, JavaReference.HEAP_ROOT_UNKNOWN, JavaReference.REACHABILITY_STRONG);
                        references.add(jRef);
                    }
                }
            } catch (CorruptDataException e) {
                // Corrupt data, so add it to the container.
                references.add(e.getCorruptData());
            } catch (MemoryAccessException e) {
                // Memory access problems, so create a CorruptData object
                // to describe the problem and add it to the container.
                ImagePointer ptrInError = e.getPointer();
                String message = e.getMessage();
                references.add(new CorruptData(message, ptrInError));
            } catch (IllegalArgumentException e) {
            // No static data, so ignore.
            }
        }
    }
    addSuperclassReference(references);
    addClassLoaderReference(references);
    addClassObjectReference(references);
    return references.iterator();
}
Also used : CorruptDataException(com.ibm.dtfj.image.CorruptDataException) ImagePointer(com.ibm.dtfj.image.ImagePointer) JavaObject(com.ibm.dtfj.java.JavaObject) Iterator(java.util.Iterator) JavaObject(com.ibm.dtfj.java.JavaObject) CorruptData(com.ibm.dtfj.image.j9.CorruptData) Vector(java.util.Vector) MemoryAccessException(com.ibm.dtfj.image.MemoryAccessException)

Aggregations

MemoryAccessException (com.ibm.dtfj.image.MemoryAccessException)25 CorruptDataException (com.ibm.dtfj.image.CorruptDataException)24 JavaObject (com.ibm.dtfj.java.JavaObject)13 ImagePointer (com.ibm.dtfj.image.ImagePointer)11 CorruptData (com.ibm.dtfj.image.j9.CorruptData)9 JavaClass (com.ibm.dtfj.java.JavaClass)9 DataUnavailable (com.ibm.dtfj.image.DataUnavailable)8 Iterator (java.util.Iterator)8 ImageAddressSpace (com.ibm.dtfj.image.ImageAddressSpace)4 JavaThread (com.ibm.dtfj.java.JavaThread)4 JavaField (com.ibm.dtfj.java.JavaField)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 Vector (java.util.Vector)3 CorruptData (com.ibm.dtfj.image.CorruptData)2 ImageThread (com.ibm.dtfj.image.ImageThread)2 JavaRuntime (com.ibm.dtfj.java.JavaRuntime)2 HashMap (java.util.HashMap)2 JavaClassLoader (com.ibm.dtfj.java.JavaClassLoader)1 JavaMethod (com.ibm.dtfj.java.JavaMethod)1