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());
}
}
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();
}
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);
}
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);
}
}
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;
}
Aggregations