Search in sources :

Example 1 with MemoryFault

use of com.ibm.j9ddr.corereaders.memory.MemoryFault in project openj9 by eclipse.

the class VMDataFactory method getStructureDataFileFromRASEyecatcher.

private static ImageInputStream getStructureDataFileFromRASEyecatcher(IProcess process, long start) throws IOException {
    try {
        long address = process.findPattern(eyecatcher, 1, start);
        while (address != -1) {
            long bitPattern = process.getLongAt(address + BIT_PATTERNS_OFFSET);
            if (bitPattern == integrityCheck) {
                return foundRAS(process, address);
            }
            address = process.findPattern(eyecatcher, 1, address + eyecatcher.length);
        }
        // Can't find RAS structure, bail out
        throw new JVMNotFoundException(process, "Could not find J9RAS structure. No Java in process?");
    } catch (MemoryFault e) {
        // put the stack trace to the log
        Logger logger = Logger.getLogger(LoggerNames.LOGGER_STRUCTURE_READER);
        StringWriter sw = new StringWriter();
        PrintWriter pw = new PrintWriter(sw);
        e.printStackTrace(pw);
        logger.logp(FINE, null, null, sw.toString());
        throw new IOException(e.getMessage());
    }
}
Also used : JVMNotFoundException(com.ibm.j9ddr.exceptions.JVMNotFoundException) MemoryFault(com.ibm.j9ddr.corereaders.memory.MemoryFault) StringWriter(java.io.StringWriter) IOException(java.io.IOException) Logger(java.util.logging.Logger) PrintWriter(java.io.PrintWriter)

Example 2 with MemoryFault

use of com.ibm.j9ddr.corereaders.memory.MemoryFault in project openj9 by eclipse.

the class AIXDumpReader method getCommandLine.

String getCommandLine() throws CorruptDataException {
    try {
        loadUserInfo();
    } catch (IOException e1) {
        throw new CorruptDataException(e1);
    }
    IProcess memory = getProcess();
    int pointerSize = pointerSize() / 8;
    if (_argc > 100) {
        throw new CorruptDataException("Argc too high. Likely corrupt data. Argc=" + _argc + " structTopOfStackVirtualAddress = 0x" + Long.toHexString(_structTopOfStackVirtualAddress));
    }
    long[] addresses = new long[_argc];
    for (int i = 0; i < _argc; i++) {
        addresses[i] = memory.getPointerAt(_argv + (i * pointerSize));
    }
    StringBuffer commandLine = new StringBuffer();
    for (int i = 0; i < _argc; i++) {
        try {
            long startingAddress = addresses[i];
            long workingAddress = startingAddress;
            while (memory.getByteAt(workingAddress) != 0) {
                workingAddress++;
            }
            int stringLength = (int) (workingAddress - startingAddress);
            byte[] buffer = new byte[stringLength];
            memory.getBytesAt(startingAddress, buffer);
            commandLine.append(new String(buffer, "ASCII"));
            commandLine.append(" ");
        } catch (MemoryFault e) {
            commandLine.append(" <Fault reading argv[" + i + "] at 0x" + Long.toHexString(addresses[i]) + ">");
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }
    return commandLine.toString();
}
Also used : MemoryFault(com.ibm.j9ddr.corereaders.memory.MemoryFault) UnsupportedEncodingException(java.io.UnsupportedEncodingException) IOException(java.io.IOException) CorruptDataException(com.ibm.j9ddr.CorruptDataException) IProcess(com.ibm.j9ddr.corereaders.memory.IProcess)

Example 3 with MemoryFault

use of com.ibm.j9ddr.corereaders.memory.MemoryFault in project openj9 by eclipse.

the class ELFDumpReader method createModuleFromElfReader.

/**
 * Given an ELF reader, read the symbols, memory ranges and properties from the module
 * and construct a Module object. The ELF reader may point to a segment within the core file
 * or may point to a copy of the module on disk or appended to the core file.
 *
 * @param loadedBaseAddress of the module
 * @param name of the module
 * @param elfReader to the module
 *
 * @return IModule
 * @throws IOException
 */
private IModule createModuleFromElfReader(final long loadedBaseAddress, String name, ELFFileReader inCoreReader, ELFFileReader diskReader) {
    if (name == null) {
        return null;
    }
    if (inCoreReader == null) {
        return new MissingFileModule(_process, name, Collections.<IMemoryRange>emptyList());
    }
    List<? extends ISymbol> symbols = null;
    Map<Long, String> sectionHeaderStringTable = null;
    List<SectionHeaderEntry> sectionHeaderEntries = null;
    Properties properties;
    Collection<? extends IMemorySource> declaredRanges;
    ProgramHeaderEntry ehFrameEntry = null;
    // so don't raise an error if it isn't present.
    for (ProgramHeaderEntry ph : inCoreReader.getProgramHeaderEntries()) {
        if (ph.isEhFrame()) {
            ehFrameEntry = ph;
        }
    }
    try {
        if (ehFrameEntry != null) {
            unwinder.addCallFrameInformation(loadedBaseAddress, ehFrameEntry, name);
        }
    } catch (MemoryFault mf) {
        // We get known memory faults for ld-linux-x86-64.so.2 in AMD64 dumps (at the first address it's loaded at)
        // and linux-vdso.so.1. The first of these turns up again at a location that works, the second is
        // "magic" so we don't worry about them. We want this code to be as resilient as possible.
        logger.log(Level.FINER, "MemoryFault reading GNU_EH_FRAME data for module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
    } catch (CorruptDataException cde) {
        logger.log(Level.FINER, "CorruptDataException reading GNU_EH_FRAME data for module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
    } catch (IOException e) {
        logger.log(Level.FINER, "IOException reading GNU_EH_FRAME data for module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
    }
    try {
        if (diskReader != null) {
            symbols = diskReader.getSymbols(loadedBaseAddress, true);
            sectionHeaderStringTable = diskReader.getSectionHeaderStringTable();
            sectionHeaderEntries = diskReader.getSectionHeaderEntries();
        } else {
            symbols = inCoreReader.getSymbols(loadedBaseAddress, false);
            sectionHeaderStringTable = inCoreReader.getSectionHeaderStringTable();
            sectionHeaderEntries = inCoreReader.getSectionHeaderEntries();
        }
        properties = inCoreReader.getProperties();
        // Only ever get memory ranges from the data loaded into the core file!
        // But we can use the section headers and string table from the disk or zipped library
        // to navigate. (Section headers are redundant once the library is loaded so may not
        // be in memory.)
        declaredRanges = inCoreReader.getMemoryRanges(loadedBaseAddress, sectionHeaderEntries, sectionHeaderStringTable);
    } catch (IOException e) {
        logger.log(Level.FINER, "Error generating module with name " + name + " and base address " + Long.toHexString(loadedBaseAddress));
        return null;
    }
    // Of the declared memory ranges, some will already be in core (i.e. .data) others will have been declared
    // in the core, but not backed.
    List<IMemoryRange> ranges = new ArrayList<IMemoryRange>(declaredRanges.size());
    for (IMemorySource source : declaredRanges) {
        IMemorySource coreSource = _process.getRangeForAddress(source.getBaseAddress());
        /**
         * The following test skips sections that originally had an address of 0
         * the section header table.
         *
         * Explanation follows - see also the example section header table at the top
         * of SectionHeaderEntry.java
         *
         * Some of the later sections in the section header table have an address field
         * 0. That is a relative address, relative to the base address of the module.
         * They are usually the sections from .comment onwards.
         *
         * When the entry is constructed the code that creates the entry creates it with
         * address (base address of the module) + (address field in the SHT) hence those
         * that had an address of 0 will have an address == base address of the module.
         * These entries are precisely those that are often not in the core file so it is
         * not safe to create them as sections - they were there in the on-disk version of
         * the library but often not in memory. The code above that called elfReader.getMemoryRanges
         * may have been reading the version of the module from disk (which is good, it means
         * you get a good section header string table so you get good names for all the
         * sections) but not all the sections exist in memory. The danger of adding them
         * as memory ranges is that they start to overlay the segments in the core file
         * that come immediately afterwards; that is, they cause jdmpview, for example, to
         * believe that the contents of these later areas of memory are backed by the
         * contents of the library on disk when they are not.
         * See CMVC 185753
         *
         * So, don't add sections that originally had address 0.
         */
        if (source.getBaseAddress() == loadedBaseAddress) {
            // must have originally had address 0 in the section header table
            continue;
        }
        if (null != coreSource) {
            if (coreSource.isBacked()) {
            // Range already exists
            } else {
                // from the library
                if (source.getSize() > 0) {
                    _process.removeMemorySource(coreSource);
                    _process.addMemorySource(source);
                }
            }
        } else {
            if (source.getSize() > 0) {
                _process.addMemorySource(source);
            }
        }
        ranges.add(source);
    }
    return new Module(_process, name, symbols, ranges, loadedBaseAddress, properties);
}
Also used : IMemorySource(com.ibm.j9ddr.corereaders.memory.IMemorySource) ArrayList(java.util.ArrayList) CorruptDataException(com.ibm.j9ddr.CorruptDataException) IOException(java.io.IOException) Properties(java.util.Properties) MissingFileModule(com.ibm.j9ddr.corereaders.memory.MissingFileModule) IMemoryRange(com.ibm.j9ddr.corereaders.memory.IMemoryRange) MemoryFault(com.ibm.j9ddr.corereaders.memory.MemoryFault) MissingFileModule(com.ibm.j9ddr.corereaders.memory.MissingFileModule) IModule(com.ibm.j9ddr.corereaders.memory.IModule) Module(com.ibm.j9ddr.corereaders.memory.Module)

Example 4 with MemoryFault

use of com.ibm.j9ddr.corereaders.memory.MemoryFault in project openj9 by eclipse.

the class Unwind method parseCallFrameInformation.

/*
	 * Parse the call frame information from a module into CIE and FDE entries.
	 * See: http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
	 */
// private void parseCallFrameInformation(IMemoryRange r) throws CorruptDataException, IOException {
private void parseCallFrameInformation(long cfiAddress, String libName) throws CorruptDataException, IOException {
    boolean dumpData = false;
    Map<Long, CIE> cieTable = new HashMap<Long, CIE>();
    if (dumpData) {
        System.err.printf("Dumping data for %s!\n", libName);
    }
    try {
        if (dumpData) {
            System.err.printf("Reading cfi info from 0x%x\n", cfiAddress);
        }
        ImageInputStream cfiStream = new IMemoryImageInputStream(process, cfiAddress);
        // Each CFI within the .eh_frame section contains multiple CIE's each followed by one or more FDE
        while (true) {
            if (dumpData) {
                System.err.printf("Reading length at position %d\n", cfiStream.getStreamPosition());
            }
            long cieAddress = cfiStream.getStreamPosition();
            long length = (long) cfiStream.readInt() & 0x00000000ffffffffl;
            // if( (length != 0xffffffff) && (length + cieAddress > cfiBytes.length) ) {
            // throw new CorruptDataException(String.format("CFI record contained length that exceeded available data, length: 0x%x, start pos 0x%x, data size: 0x%x",  length, cieAddress, r.getSize()));
            // }
            long startPos = cfiStream.getStreamPosition();
            if (dumpData) {
                System.err.printf("Got length: %x (%1$d)\n", length);
            }
            if (length == 0) {
                if (dumpData) {
                    System.err.printf("Length = 0, end of cfi.\n");
                }
                break;
            }
            if (length == 0xffffffff) {
                length = cfiStream.readLong();
                if (dumpData) {
                    System.err.printf("Got extended length: %x\n", length);
                }
                // (The length would have to be >4Gb!)
                throw new CorruptDataException("CFI record contained unhandled extended length field.");
            }
            if (dumpData) {
                System.err.printf("Reading ciePointer at position %d\n", cfiStream.getStreamPosition());
            }
            int ciePointer = cfiStream.readInt();
            if (dumpData) {
                System.err.printf("Got ciePointer: %x\n", ciePointer);
            }
            // we can skip bad records. (Or ones we just don't know how to parse.)
            if (ciePointer == 0) {
                if (dumpData) {
                    System.err.printf("CIE!\n");
                }
                // This is a CIE.
                CIE cie = new CIE(this, cfiStream, startPos, length);
                cieTable.put(cieAddress, cie);
                if (dumpData) {
                    cie.dump(System.err);
                    System.err.printf("--- End CIE\n");
                }
            } else {
                // This is an FDE.
                if (dumpData) {
                    System.err.printf("FDE!\n");
                }
                // The parent cie is not always the last one we read.
                // The cie pointer is a relative offset (backwards)
                CIE cie = cieTable.get(startPos - ciePointer);
                if (cie == null) {
                    throw new IOException(String.format("Missing CIE record @0x%x (0x%x - 0x%x) for FDE@0x%x", ciePointer - startPos, ciePointer, startPos, startPos));
                }
                FDE fde = new FDE(this, cfiStream, cie, startPos, length);
                frameDescriptionEntries.add(fde);
                if (dumpData) {
                    fde.dump(System.err);
                    System.err.printf("--- End FDE\n");
                }
            }
        }
    } catch (MemoryFault e) {
        logger.log(Level.FINER, "MemoryFault in parseCallFrameInformation for " + libName, e);
    } catch (IOException e) {
        logger.log(Level.FINER, "IOException in parseCallFrameInformation for " + libName, e);
    } catch (CorruptDataException e) {
        logger.log(Level.FINER, "CorruptDataException in parseCallFrameInformation for " + libName, e);
    }
}
Also used : HashMap(java.util.HashMap) ImageInputStream(javax.imageio.stream.ImageInputStream) IMemoryImageInputStream(com.ibm.j9ddr.corereaders.memory.IMemoryImageInputStream) CorruptDataException(com.ibm.j9ddr.CorruptDataException) IOException(java.io.IOException) IMemoryImageInputStream(com.ibm.j9ddr.corereaders.memory.IMemoryImageInputStream) MemoryFault(com.ibm.j9ddr.corereaders.memory.MemoryFault)

Example 5 with MemoryFault

use of com.ibm.j9ddr.corereaders.memory.MemoryFault in project openj9 by eclipse.

the class Command method dbgFindPatternInRange.

/*
	 * pattern: a pointer to the eyecatcher pattern to search for
	 * patternAlignment: guaranteed minimum alignment of the pattern (must be a
	 * power of 2) startSearchFrom: minimum address to search at (useful for
	 * multiple occurrences of the pattern) bytesToSearch: maximum number of
	 * bytes to search
	 * 
	 * Returns: The address of the eyecatcher in TARGET memory space or 0 if it
	 * was not found.
	 * 
	 * NOTES: Currently, this may fail to find the pattern if patternLength >
	 * patternAlignment Generally, dbgFindPattern should be called instead of
	 * dbgFindPatternInRange. It can be more clever about not searching ranges
	 * which aren't in use.
	 * 
	 * @param context Current context. 
	 * @param pattern Pattern to be searched.
	 * @param patternAlignment	Pattern alignment number. 
	 * @param startSearchFrom	Where to start the search.
	 * @param bytesToSearch		number of bytes to search.
	 * @return First memory address where pattern is found.
	 * @throws MemoryFault
	 * 
	 */
protected long dbgFindPatternInRange(Context context, byte[] pattern, int patternAlignment, long startSearchFrom, BigInteger bytesToSearch) throws MemoryFault {
    long page = startSearchFrom;
    BigInteger startSearchFrom2 = new BigInteger(Long.toBinaryString(startSearchFrom), CommandUtils.RADIX_BINARY);
    BigInteger udataMax;
    if (context.process.bytesPerPointer() == 4) {
        udataMax = CommandUtils.UDATA_MAX_32BIT;
    } else {
        udataMax = CommandUtils.UDATA_MAX_64BIT;
    }
    /* if bytes to be searched exceeds the allowed max pointer value on this platform, than adjust the value */
    if (startSearchFrom2.add(bytesToSearch).compareTo(udataMax) == 1) {
        bytesToSearch = udataMax.subtract(startSearchFrom2);
    }
    /* round to a page */
    while ((page & 4095) != 0) {
        page--;
        bytesToSearch = bytesToSearch.add(BigInteger.ONE);
    }
    BigInteger bytesSearched = BigInteger.ZERO;
    for (; ; ) {
        byte[] data = new byte[4096];
        try {
            int bytesRead = context.process.getBytesAt(page, data);
            bytesSearched = bytesSearched.add(new BigInteger(Integer.toString(bytesRead)));
            for (int i = 0; i < bytesRead - pattern.length; i += patternAlignment) {
                if (compare(data, pattern, i)) {
                    /* in case the page started before startSearchFrom */
                    if (page + i >= startSearchFrom) {
                        return page + i;
                    }
                }
            }
        } catch (MemoryFault e) {
        }
        if (bytesToSearch.compareTo(new BigInteger("4096")) == -1) {
            break;
        }
        page += 4096;
        bytesToSearch = bytesToSearch.subtract(new BigInteger("4096"));
    }
    return 0;
}
Also used : MemoryFault(com.ibm.j9ddr.corereaders.memory.MemoryFault) BigInteger(java.math.BigInteger)

Aggregations

MemoryFault (com.ibm.j9ddr.corereaders.memory.MemoryFault)15 IOException (java.io.IOException)10 CorruptDataException (com.ibm.j9ddr.CorruptDataException)6 UnsupportedEncodingException (java.io.UnsupportedEncodingException)3 IMemoryImageInputStream (com.ibm.j9ddr.corereaders.memory.IMemoryImageInputStream)2 IMemoryRange (com.ibm.j9ddr.corereaders.memory.IMemoryRange)2 IModule (com.ibm.j9ddr.corereaders.memory.IModule)2 Module (com.ibm.j9ddr.corereaders.memory.Module)2 J9ClassPointer (com.ibm.j9ddr.vm29.pointer.generated.J9ClassPointer)2 FileNotFoundException (java.io.FileNotFoundException)2 PrintWriter (java.io.PrintWriter)2 StringWriter (java.io.StringWriter)2 Properties (java.util.Properties)2 Logger (java.util.logging.Logger)2 ImageInputStream (javax.imageio.stream.ImageInputStream)2 CorruptCoreException (com.ibm.j9ddr.corereaders.CorruptCoreException)1 IMemorySource (com.ibm.j9ddr.corereaders.memory.IMemorySource)1 IProcess (com.ibm.j9ddr.corereaders.memory.IProcess)1 ISymbol (com.ibm.j9ddr.corereaders.memory.ISymbol)1 MissingFileModule (com.ibm.j9ddr.corereaders.memory.MissingFileModule)1