use of com.ibm.j9ddr.corereaders.memory.IMemoryImageInputStream 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.IMemoryImageInputStream in project openj9 by eclipse.
the class Unwind method getCFIAddress.
/* Find the offset to the eh_frame table and return the address.
*/
private long getCFIAddress(long libraryBaseAddress, ProgramHeaderEntry ph, String libName) throws IOException, MemoryFault {
// System.err.printf("Reading data for %s @0x%x (0x%x, + 0x%x\n", libName, libraryBaseAddress + ph.fileOffset, libraryBaseAddress, ph.fileOffset);
ImageInputStream headerStream = new IMemoryImageInputStream(process, libraryBaseAddress + ph.fileOffset);
long startPos = headerStream.getStreamPosition();
byte version = headerStream.readByte();
if (version != 1) {
headerStream.close();
throw new IOException(String.format("Invalid version number for .eh_frame_hdr @ 0x%x in library %s, was %d not 1", libraryBaseAddress, libName, version));
}
byte ptrEncoding = headerStream.readByte();
byte countEncoding = headerStream.readByte();
byte tableEncoding = headerStream.readByte();
long ehFramePtrPos = headerStream.getStreamPosition() - startPos;
long ehFramePtr = readEncodedPC(headerStream, ptrEncoding);
long cfiAddress = 0;
long cfiOffset = 0;
if ((ptrEncoding & DW_EH_PE.pcrel) == DW_EH_PE.pcrel) {
// The pointer is relative to the eh_frame_ptr field address.
cfiOffset = ehFramePtrPos + ehFramePtr;
}
// The cfiOffset is relative to the file offset, once loaded that's relative to the baseAddress of this
// module.
cfiAddress = libraryBaseAddress + ph.fileOffset + cfiOffset;
return cfiAddress;
}
use of com.ibm.j9ddr.corereaders.memory.IMemoryImageInputStream in project openj9 by eclipse.
the class VMDataFactory method foundRAS.
private static ImageInputStream foundRAS(IProcess addressSpace, long candidateAddress) throws IOException {
try {
j9RASAddress = candidateAddress;
String structureFileName = System.getProperty(STRUCTUREFILE_PROPERTY);
if (structureFileName != null) {
// for it in the blob archive
try {
return getStructureDataFromFile(structureFileName, addressSpace);
} catch (FileNotFoundException e) {
return getBlobFromArchive(structureFileName, addressSpace);
}
}
int j9RASVersion = addressSpace.getIntAt(candidateAddress + J9RAS_VERSION_OFFSET);
short j9RASMajorVersion = (short) (j9RASVersion >> 16);
if (j9RASMajorVersion < MINIMUM_J9RAS_MAJOR_VERSION) {
return locateInServiceVMStructure(addressSpace);
}
long ddrDataStart = addressSpace.getPointerAt(candidateAddress + DDR_DATA_POINTER_OFFSET);
if (0 == ddrDataStart) {
// CMVC 172446 : no valid address to DDR blob, so see if we can locate it via the blob archive
try {
return locateInServiceVMStructure(addressSpace);
} catch (IOException e) {
// failed to locate a blob
MissingDDRStructuresException ioe = new MissingDDRStructuresException(addressSpace, "System dump was generated by a DDR-enabled JVM, but did not contain embedded DDR structures. This dump cannot be analyzed by DDR. " + "You can specify the location of a DDR structure file to use with the " + STRUCTUREFILE_PROPERTY + " system property");
ioe.initCause(e);
throw ioe;
}
}
// the address may be a marker to treat it in a special way, rather than as an actual address
// -1 = the blob is located directly after this structure
// -2 = there is only a blob descriptor loaded
long marker = (addressSpace.bytesPerPointer() == 4) ? 0xFFFFFFFF00000000L | ddrDataStart : ddrDataStart;
if (marker == -2) {
StructureHeader header = new StructureHeader((byte) 1);
ddrDataStart = candidateAddress + DDR_DATA_POINTER_OFFSET + (addressSpace.bytesPerPointer() * 2);
ImageInputStream stream = new IMemoryImageInputStream(addressSpace, ddrDataStart);
header.readBlobVersion(stream);
return getBlobFromLibrary(addressSpace, header);
}
if (marker == -1) {
if (j9RASVersion == 0x100000) {
// there is one pointer in the way that needs to be skipped over
ddrDataStart = candidateAddress + DDR_DATA_POINTER_OFFSET + (addressSpace.bytesPerPointer() * 2);
} else {
MissingDDRStructuresException ioe = new MissingDDRStructuresException(addressSpace, "System dump was generated by a DDR-enabled JVM, but did not contain embedded DDR structures. This dump cannot be analyzed by DDR. " + "You can specify the location of a DDR structure file to use with the " + STRUCTUREFILE_PROPERTY + " system property");
throw ioe;
}
}
return new IMemoryImageInputStream(addressSpace, ddrDataStart);
} 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.IMemoryImageInputStream in project openj9 by eclipse.
the class VMDataFactory method getAllVMData.
// TODO - fix this for z/OS which will require noting which RAS symbols have already been found in the core
/**
* Finds all of the blobs in a given process and wraps them in a IVMData structure.
*
* @param process process to scan
* @return all located blobs
* @throws IOException re-throws IOExceptions
*/
public static synchronized List<IVMData> getAllVMData(IProcess process) throws IOException {
List<IVMData> cachedVMData = vmDataCache.get(process);
if (cachedVMData != null) {
return cachedVMData;
}
// nothing in the cache for this process, so need to scan
// Get an ImageInputStream on the Structure Offset Data. This may or may not be in the core file itself.
List<IVMData> data = new ArrayList<IVMData>();
ImageInputStream in = null;
// End Of Memory
boolean EOM = false;
long address = 0;
j9RASAddress = 0;
while (!EOM) {
try {
address = j9RASAddress + 1;
in = getStructureDataFile(process, address);
if (in != null) {
EOM = !(in instanceof IMemoryImageInputStream);
IVMData vmdata = getVMData(process, in);
data.add(vmdata);
if (vmdata.getClassLoader().getHeader().getCoreVersion() == 1) {
// version 1 does not support multiple blobs
EOM = true;
break;
}
} else {
EOM = true;
}
} catch (JVMNotFoundException e) {
// no more JVMs were found
EOM = true;
} catch (JVMNotDDREnabledException e) {
// an older JVM was found, so ignore that and carry on looking
// on z/OS a failure with the j9ras symbol resolution aborts the scan
EOM = EOM | (process.getPlatform() == Platform.ZOS);
continue;
} catch (MissingDDRStructuresException e) {
// cannot process as the structures are missing
// on z/OS a failure with the j9ras symbol resolution aborts the scan
EOM = EOM | (process.getPlatform() == Platform.ZOS);
continue;
} catch (CorruptStructuresException e) {
// cannot process as the structures are corrupt and cannot be read
// on z/OS a failure with the j9ras symbol resolution aborts the scan
EOM = EOM | (process.getPlatform() == Platform.ZOS);
continue;
} catch (IOException e) {
continue;
}
}
// scan is switched off for Java-only applications (specifically jdmpview) via a system property.
if ((System.getProperty(NOEXTRASEARCHFORNODE_PROPERTY) == null) && (data.size() == 0)) {
StructureHeader header = null;
try {
header = findNodeVersion(process);
} catch (Exception e) {
if (e instanceof IOException) {
throw (IOException) e;
} else {
IOException ioe = new IOException();
// avoid use of IOException(throwable) to be compatible with J5
ioe.initCause(e);
throw ioe;
}
}
if (header != null) {
in = getBlobFromLibrary(process, header);
if (in != null) {
IVMData vmdata = getVMData(process, in);
data.add(vmdata);
}
}
}
vmDataCache.put(process, data);
return data;
}
Aggregations