提交 9bc8a1c8 编写于 作者: D dcubed

6987812: 2/3 SAJDI: "gHotSpotVMTypes was not initialized properly in the remote process"

Summary: Change ExportDirectoryTableImpl to return the 'Export RVA' field without modification. Read 'Base Of Data' field in optional header when PE32 format COFF file is read. Refine search for dbgeng.dll and dbghelp.dll. Other cleanups.
Reviewed-by: swamyv, poonam
上级 7df202b7
/* /*
* Copyright (c) 2000, 2009, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -99,15 +99,8 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -99,15 +99,8 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
long typeEntrySizeOffset; long typeEntrySizeOffset;
long typeEntryArrayStride; long typeEntryArrayStride;
typeEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset"); // Fetch the address of the VMTypeEntry*. We get this symbol first
typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset"); // and try to use it to make sure that symbol lookup is working.
typeEntryIsOopTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
typeEntryIsIntegerTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
typeEntryIsUnsignedOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
// Fetch the address of the VMTypeEntry*
Address entryAddr = lookupInProcess("gHotSpotVMTypes"); Address entryAddr = lookupInProcess("gHotSpotVMTypes");
// System.err.println("gHotSpotVMTypes address = " + entryAddr); // System.err.println("gHotSpotVMTypes address = " + entryAddr);
// Dereference this once to get the pointer to the first VMTypeEntry // Dereference this once to get the pointer to the first VMTypeEntry
...@@ -118,6 +111,14 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase { ...@@ -118,6 +111,14 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
throw new RuntimeException("gHotSpotVMTypes was not initialized properly in the remote process; can not continue"); throw new RuntimeException("gHotSpotVMTypes was not initialized properly in the remote process; can not continue");
} }
typeEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
typeEntryIsOopTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
typeEntryIsIntegerTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
typeEntryIsUnsignedOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
// Start iterating down it until we find an entry with no name // Start iterating down it until we find an entry with no name
Address typeNameAddr = null; Address typeNameAddr = null;
do { do {
......
/* /*
* Copyright (c) 2000, 2004, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -122,10 +122,14 @@ public class COFFFileParser { ...@@ -122,10 +122,14 @@ public class COFFFileParser {
private MemoizedObject[] sectionHeaders; private MemoizedObject[] sectionHeaders;
private MemoizedObject[] symbols; private MemoizedObject[] symbols;
// Init stringTable at decl time since other fields init'ed in the
// constructor need the String Table.
private MemoizedObject stringTable = new MemoizedObject() { private MemoizedObject stringTable = new MemoizedObject() {
public Object computeValue() { public Object computeValue() {
// the String Table follows the Symbol Table
int ptr = getPointerToSymbolTable(); int ptr = getPointerToSymbolTable();
if (ptr == 0) { if (ptr == 0) {
// no Symbol Table so no String Table
return new StringTable(0); return new StringTable(0);
} else { } else {
return new StringTable(ptr + SYMBOL_SIZE * getNumberOfSymbols()); return new StringTable(ptr + SYMBOL_SIZE * getNumberOfSymbols());
...@@ -140,6 +144,8 @@ public class COFFFileParser { ...@@ -140,6 +144,8 @@ public class COFFFileParser {
timeDateStamp = readInt(); timeDateStamp = readInt();
pointerToSymbolTable = readInt(); pointerToSymbolTable = readInt();
numberOfSymbols = readInt(); numberOfSymbols = readInt();
// String Table can be accessed at this point because
// pointerToSymbolTable and numberOfSymbols fields are set.
sizeOfOptionalHeader = readShort(); sizeOfOptionalHeader = readShort();
characteristics = readShort(); characteristics = readShort();
...@@ -222,6 +228,8 @@ public class COFFFileParser { ...@@ -222,6 +228,8 @@ public class COFFFileParser {
private MemoizedObject windowsSpecificFields; private MemoizedObject windowsSpecificFields;
private MemoizedObject dataDirectories; private MemoizedObject dataDirectories;
// We use an offset of 2 because OptionalHeaderStandardFieldsImpl doesn't
// include the 'magic' field.
private static final int STANDARD_FIELDS_OFFSET = 2; private static final int STANDARD_FIELDS_OFFSET = 2;
private static final int PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET = 28; private static final int PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET = 28;
private static final int PE32_DATA_DIRECTORIES_OFFSET = 96; private static final int PE32_DATA_DIRECTORIES_OFFSET = 96;
...@@ -288,7 +296,7 @@ public class COFFFileParser { ...@@ -288,7 +296,7 @@ public class COFFFileParser {
private int sizeOfUninitializedData; private int sizeOfUninitializedData;
private int addressOfEntryPoint; private int addressOfEntryPoint;
private int baseOfCode; private int baseOfCode;
private int baseOfData; private int baseOfData; // only set in PE32
OptionalHeaderStandardFieldsImpl(int offset, OptionalHeaderStandardFieldsImpl(int offset,
boolean isPE32Plus) { boolean isPE32Plus) {
...@@ -301,7 +309,8 @@ public class COFFFileParser { ...@@ -301,7 +309,8 @@ public class COFFFileParser {
sizeOfUninitializedData = readInt(); sizeOfUninitializedData = readInt();
addressOfEntryPoint = readInt(); addressOfEntryPoint = readInt();
baseOfCode = readInt(); baseOfCode = readInt();
if (isPE32Plus) { if (!isPE32Plus) {
// only available in PE32
baseOfData = readInt(); baseOfData = readInt();
} }
} }
...@@ -433,7 +442,10 @@ public class COFFFileParser { ...@@ -433,7 +442,10 @@ public class COFFFileParser {
if (dir.getRVA() == 0 || dir.getSize() == 0) { if (dir.getRVA() == 0 || dir.getSize() == 0) {
return null; return null;
} }
return new ExportDirectoryTableImpl(rvaToFileOffset(dir.getRVA()), dir.getSize()); // ExportDirectoryTableImpl needs both the RVA and the
// RVA converted to a file offset.
return new
ExportDirectoryTableImpl(dir.getRVA(), dir.getSize());
} }
}; };
...@@ -526,6 +538,7 @@ public class COFFFileParser { ...@@ -526,6 +538,7 @@ public class COFFFileParser {
} }
class ExportDirectoryTableImpl implements ExportDirectoryTable { class ExportDirectoryTableImpl implements ExportDirectoryTable {
private int exportDataDirRVA;
private int offset; private int offset;
private int size; private int size;
...@@ -548,8 +561,9 @@ public class COFFFileParser { ...@@ -548,8 +561,9 @@ public class COFFFileParser {
private MemoizedObject exportOrdinalTable; private MemoizedObject exportOrdinalTable;
private MemoizedObject exportAddressTable; private MemoizedObject exportAddressTable;
ExportDirectoryTableImpl(int offset, int size) { ExportDirectoryTableImpl(int exportDataDirRVA, int size) {
this.offset = offset; this.exportDataDirRVA = exportDataDirRVA;
offset = rvaToFileOffset(exportDataDirRVA);
this.size = size; this.size = size;
seek(offset); seek(offset);
exportFlags = readInt(); exportFlags = readInt();
...@@ -595,6 +609,7 @@ public class COFFFileParser { ...@@ -595,6 +609,7 @@ public class COFFFileParser {
exportOrdinalTable = new MemoizedObject() { exportOrdinalTable = new MemoizedObject() {
public Object computeValue() { public Object computeValue() {
// number of ordinals is same as the number of name pointers
short[] ordinals = new short[getNumberOfNamePointers()]; short[] ordinals = new short[getNumberOfNamePointers()];
seek(rvaToFileOffset(getOrdinalTableRVA())); seek(rvaToFileOffset(getOrdinalTableRVA()));
for (int i = 0; i < ordinals.length; i++) { for (int i = 0; i < ordinals.length; i++) {
...@@ -608,14 +623,18 @@ public class COFFFileParser { ...@@ -608,14 +623,18 @@ public class COFFFileParser {
public Object computeValue() { public Object computeValue() {
int[] addresses = new int[getNumberOfAddressTableEntries()]; int[] addresses = new int[getNumberOfAddressTableEntries()];
seek(rvaToFileOffset(getExportAddressTableRVA())); seek(rvaToFileOffset(getExportAddressTableRVA()));
// Must make two passes to avoid rvaToFileOffset // The Export Address Table values are a union of two
// destroying seek() position // possible values:
// Export RVA - The address of the exported symbol when
// loaded into memory, relative to the image base.
// This value doesn't get converted into a file offset.
// Forwarder RVA - The pointer to a null-terminated ASCII
// string in the export section. This value gets
// converted into a file offset because we have to
// fetch the string.
for (int i = 0; i < addresses.length; i++) { for (int i = 0; i < addresses.length; i++) {
addresses[i] = readInt(); addresses[i] = readInt();
} }
for (int i = 0; i < addresses.length; i++) {
addresses[i] = rvaToFileOffset(addresses[i]);
}
return addresses; return addresses;
} }
}; };
...@@ -648,11 +667,12 @@ public class COFFFileParser { ...@@ -648,11 +667,12 @@ public class COFFFileParser {
public boolean isExportAddressForwarder(short ordinal) { public boolean isExportAddressForwarder(short ordinal) {
int addr = getExportAddress(ordinal); int addr = getExportAddress(ordinal);
return ((offset <= addr) && (addr < (offset + size))); return ((exportDataDirRVA <= addr) &&
(addr < (exportDataDirRVA + size)));
} }
public String getExportAddressForwarder(short ordinal) { public String getExportAddressForwarder(short ordinal) {
seek(getExportAddress(ordinal)); seek(rvaToFileOffset(getExportAddress(ordinal)));
return readCString(); return readCString();
} }
...@@ -3371,10 +3391,17 @@ public class COFFFileParser { ...@@ -3371,10 +3391,17 @@ public class COFFFileParser {
throw new COFFException(e); throw new COFFException(e);
} }
// Look up in string table // Look up in string table
// FIXME: this index value is assumed to be in the valid range
name = getStringTable().get(index); name = getStringTable().get(index);
} else { } else {
try { try {
name = new String(tmpName, US_ASCII); int length = 0;
// find last non-NULL
for (; length < tmpName.length && tmpName[length] != '\0';) {
length++;
}
// don't include NULL chars in returned name String
name = new String(tmpName, 0, length, US_ASCII);
} catch (UnsupportedEncodingException e) { } catch (UnsupportedEncodingException e) {
throw new COFFException(e); throw new COFFException(e);
} }
...@@ -3487,6 +3514,7 @@ public class COFFFileParser { ...@@ -3487,6 +3514,7 @@ public class COFFFileParser {
tmpName[5] << 16 | tmpName[5] << 16 |
tmpName[6] << 8 | tmpName[6] << 8 |
tmpName[7]); tmpName[7]);
// FIXME: stringOffset is assumed to be in the valid range
name = getStringTable().getAtOffset(stringOffset); name = getStringTable().getAtOffset(stringOffset);
} }
...@@ -3698,12 +3726,13 @@ public class COFFFileParser { ...@@ -3698,12 +3726,13 @@ public class COFFFileParser {
StringTable(int offset) { StringTable(int offset) {
if (offset == 0) { if (offset == 0) {
// no String Table
strings = new COFFString[0]; strings = new COFFString[0];
return; return;
} }
seek(offset); seek(offset);
int length = readInt(); int length = readInt(); // length includes itself
byte[] data = new byte[length - 4]; byte[] data = new byte[length - 4];
int numBytesRead = readBytes(data); int numBytesRead = readBytes(data);
if (numBytesRead != data.length) { if (numBytesRead != data.length) {
......
/* /*
* Copyright (c) 2001, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2001, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -37,35 +37,48 @@ public class DumpExports { ...@@ -37,35 +37,48 @@ public class DumpExports {
String filename = args[0]; String filename = args[0];
COFFFile file = COFFFileParser.getParser().parse(filename); COFFFile file = COFFFileParser.getParser().parse(filename);
ExportDirectoryTable exports =
file.getHeader(). // get common point for both things we want to dump
getOptionalHeader(). OptionalHeaderDataDirectories dataDirs = file.getHeader().getOptionalHeader().
getDataDirectories(). getDataDirectories();
getExportDirectoryTable();
if (exports == null) { // dump the header data directory for the Export Table:
System.out.println("No exports found."); DataDirectory dir = dataDirs.getExportTable();
} else { System.out.println("Export table: RVA = " + dir.getRVA() + "/0x" +
Integer.toHexString(dir.getRVA()) + ", size = " + dir.getSize() + "/0x" +
Integer.toHexString(dir.getSize()));
System.out.println(file.getHeader().getNumberOfSections() + " sections in file"); System.out.println(file.getHeader().getNumberOfSections() + " sections in file");
for (int i = 0; i < file.getHeader().getNumberOfSections(); i++) { for (int i = 1; i <= file.getHeader().getNumberOfSections(); i++) {
System.out.println(" Section " + i + ": " + file.getHeader().getSectionHeader(1 + i).getName()); SectionHeader sec = file.getHeader().getSectionHeader(i);
System.out.println(" Section " + i + ":");
System.out.println(" Name = '" + sec.getName() + "'");
System.out.println(" VirtualSize = " + sec.getSize() + "/0x" +
Integer.toHexString(sec.getSize()));
System.out.println(" VirtualAddress = " + sec.getVirtualAddress() + "/0x" +
Integer.toHexString(sec.getVirtualAddress()));
System.out.println(" SizeOfRawData = " + sec.getSizeOfRawData() + "/0x" +
Integer.toHexString(sec.getSizeOfRawData()));
System.out.println(" PointerToRawData = " + sec.getPointerToRawData() + "/0x" +
Integer.toHexString(sec.getPointerToRawData()));
} }
DataDirectory dir = file.getHeader().getOptionalHeader().getDataDirectories().getExportTable(); ExportDirectoryTable exports = dataDirs.getExportDirectoryTable();
System.out.println("Export table: RVA = 0x" + Integer.toHexString(dir.getRVA()) + if (exports == null) {
", size = 0x" + Integer.toHexString(dir.getSize())); System.out.println("No exports found.");
} else {
System.out.println("DLL name: " + exports.getDLLName()); System.out.println("DLL name: " + exports.getDLLName());
System.out.println("Time/date stamp 0x" + Integer.toHexString(exports.getTimeDateStamp())); System.out.println("Time/date stamp 0x" + Integer.toHexString(exports.getTimeDateStamp()));
System.out.println("Major version 0x" + Integer.toHexString(exports.getMajorVersion() & 0xFFFF)); System.out.println("Major version 0x" + Integer.toHexString(exports.getMajorVersion() & 0xFFFF));
System.out.println("Minor version 0x" + Integer.toHexString(exports.getMinorVersion() & 0xFFFF)); System.out.println("Minor version 0x" + Integer.toHexString(exports.getMinorVersion() & 0xFFFF));
System.out.println(exports.getNumberOfNamePointers() + " functions found"); System.out.println(exports.getNumberOfNamePointers() + " exports found");
for (int i = 0; i < exports.getNumberOfNamePointers(); i++) { for (int i = 0; i < exports.getNumberOfNamePointers(); i++) {
System.out.println(" 0x" + short ordinal = exports.getExportOrdinal(i);
Integer.toHexString(exports.getExportAddress(exports.getExportOrdinal(i))) + System.out.print("[" + i + "] '" + exports.getExportName(i) + "': [" +
" " + ordinal + "] = 0x" + Integer.toHexString(exports.getExportAddress(ordinal)));
(exports.isExportAddressForwarder(exports.getExportOrdinal(i)) ? System.out.println(exports.isExportAddressForwarder(ordinal)
("Forwarded to " + exports.getExportAddressForwarder(exports.getExportOrdinal(i))) : ? " Forwarded to '" + exports.getExportAddressForwarder(ordinal) + "'"
exports.getExportName(i))); : "");
} }
} }
} }
......
/* /*
* Copyright (c) 2000, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -42,8 +42,8 @@ public class TestParser { ...@@ -42,8 +42,8 @@ public class TestParser {
COFFHeader header = file.getHeader(); COFFHeader header = file.getHeader();
int numSections = header.getNumberOfSections(); int numSections = header.getNumberOfSections();
System.out.println(numSections + " sections detected."); System.out.println(numSections + " sections detected.");
for (int i = 0; i < numSections; i++) { for (int i = 1; i <= numSections; i++) {
SectionHeader secHeader = header.getSectionHeader(1 + i); SectionHeader secHeader = header.getSectionHeader(i);
System.out.println(secHeader.getName()); System.out.println(secHeader.getName());
} }
......
/* /*
* Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -506,7 +506,6 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger ...@@ -506,7 +506,6 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger
throw new DebuggerException("Unimplemented"); throw new DebuggerException("Unimplemented");
} }
private static String DTFWHome;
private static String imagePath; private static String imagePath;
private static String symbolPath; private static String symbolPath;
private static boolean useNativeLookup; private static boolean useNativeLookup;
...@@ -514,81 +513,143 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger ...@@ -514,81 +513,143 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger
static { static {
/* /*
* sawindbg.dll depends on dbgeng.dll which * sawindbg.dll depends on dbgeng.dll which itself depends on
* itself depends on dbghelp.dll. dbgeng.dll and dbghelp.dll. * dbghelp.dll. We have to make sure that the dbgeng.dll and
* On systems newer than Windows 2000, these two .dlls are * dbghelp.dll that we load are compatible with each other. We
* in the standard system directory so we will find them there. * load both of those libraries from the same directory based
* On Windows 2000 and earlier, these files do not exist. * on the theory that co-located libraries are compatible.
* The user must download Debugging Tools For Windows (DTFW)
* and install it in order to use SA.
* *
* We have to make sure we use the two files from the same directory * On Windows 2000 and earlier, dbgeng.dll and dbghelp.dll were
* in case there are more than one copy on the system because * not included as part of the standard system directory. On
* one version of dbgeng.dll might not be compatible with a * systems newer than Windows 2000, dbgeng.dll and dbghelp.dll
* different version of dbghelp.dll. * are included in the standard system directory. However, the
* We first look for them in the directory pointed at by * versions included in the standard system directory may not
* env. var. DEBUGGINGTOOLSFORWINDOWS, next in the default * be able to handle symbol information for the newer compilers.
* installation dir for DTFW, and lastly in the standard *
* system directory. We expect that that we will find * We search for and explicitly load the libraries using the
* them in the standard system directory on all systems * following directory search order:
* newer than Windows 2000. *
* - java.home/bin (same as $JAVA_HOME/jre/bin)
* - dir named by DEBUGGINGTOOLSFORWINDOWS environment variable
* - various "Debugging Tools For Windows" program directories
* - the system directory ($SYSROOT/system32)
*
* If SA is invoked with -Dsun.jvm.hotspot.loadLibrary.DEBUG=1,
* then debug messages about library loading are printed to
* System.err.
*/ */
String dirName = null;
DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
if (DTFWHome == null) { String dbgengPath = null;
// See if we have the files in the default location. String dbghelpPath = null;
String sawindbgPath = null;
List searchList = new ArrayList();
boolean loadLibraryDEBUG =
System.getProperty("sun.jvm.hotspot.loadLibrary.DEBUG") != null;
{
// First place to search is co-located with sawindbg.dll in
// $JAVA_HOME/jre/bin (java.home property is set to $JAVA_HOME/jre):
searchList.add(System.getProperty("java.home") + File.separator + "bin");
sawindbgPath = (String) searchList.get(0) + File.separator +
"sawindbg.dll";
// second place to search is specified by an environment variable:
String DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS");
if (DTFWHome != null) {
searchList.add(DTFWHome);
}
// The third place to search is the install directory for the
// "Debugging Tools For Windows" package; so far there are three
// name variations that we know of:
String sysRoot = System.getenv("SYSTEMROOT"); String sysRoot = System.getenv("SYSTEMROOT");
DTFWHome = sysRoot + File.separator + DTFWHome = sysRoot + File.separator + ".." + File.separator +
".." + File.separator + "Program Files" + "Program Files" + File.separator + "Debugging Tools For Windows";
File.separator + "Debugging Tools For Windows"; searchList.add(DTFWHome);
searchList.add(DTFWHome + " (x86)");
searchList.add(DTFWHome + " (x64)");
// The last place to search is the system directory:
searchList.add(sysRoot + File.separator + "system32");
}
for (int i = 0; i < searchList.size(); i++) {
File dir = new File((String) searchList.get(i));
if (!dir.exists()) {
if (loadLibraryDEBUG) {
System.err.println("DEBUG: '" + searchList.get(i) +
"': directory does not exist.");
}
// this search directory doesn't exist so skip it
continue;
}
dbgengPath = (String) searchList.get(i) + File.separator + "dbgeng.dll";
dbghelpPath = (String) searchList.get(i) + File.separator + "dbghelp.dll";
File feng = new File(dbgengPath);
File fhelp = new File(dbghelpPath);
if (feng.exists() && fhelp.exists()) {
// both files exist so we have a match
break;
}
// At least one of the files does not exist; no warning if both
// don't exist. If just one doesn't exist then we don't check
// loadLibraryDEBUG because we have a mis-configured system.
if (feng.exists()) {
System.err.println("WARNING: found '" + dbgengPath +
"' but did not find '" + dbghelpPath + "'; ignoring '" +
dbgengPath + "'.");
} else if (fhelp.exists()) {
System.err.println("WARNING: found '" + dbghelpPath +
"' but did not find '" + dbgengPath + "'; ignoring '" +
dbghelpPath + "'.");
} else if (loadLibraryDEBUG) {
System.err.println("DEBUG: searched '" + searchList.get(i) +
"': dbgeng.dll and dbghelp.dll were not found.");
}
dbgengPath = null;
dbghelpPath = null;
}
if (dbgengPath == null || dbghelpPath == null) {
// at least one of the files wasn't found anywhere we searched
String mesg = null;
if (dbgengPath == null && dbghelpPath == null) {
mesg = "dbgeng.dll and dbghelp.dll cannot be found. ";
} else if (dbgengPath == null) {
mesg = "dbgeng.dll cannot be found (dbghelp.dll was found). ";
} else {
mesg = "dbghelp.dll cannot be found (dbgeng.dll was found). ";
}
throw new UnsatisfiedLinkError(mesg +
"Please search microsoft.com for 'Debugging Tools For Windows', " +
"and either download it to the default location, or download it " +
"to a custom location and set environment variable " +
"'DEBUGGINGTOOLSFORWINDOWS' to the pathname of that location.");
} }
{
String dbghelp = DTFWHome + File.separator + "dbghelp.dll";
String dbgeng = DTFWHome + File.separator + "dbgeng.dll";
File fhelp = new File(dbghelp);
File feng = new File(dbgeng);
if (fhelp.exists() && feng.exists()) {
// found both, we are happy.
// NOTE: The order of loads is important! If we load dbgeng.dll // NOTE: The order of loads is important! If we load dbgeng.dll
// first, then the dependency - dbghelp.dll - will be loaded // first, then the dependency - dbghelp.dll - will be loaded
// from usual DLL search thereby defeating the purpose! // from usual DLL search thereby defeating the purpose!
System.load(dbghelp); if (loadLibraryDEBUG) {
System.load(dbgeng); System.err.println("DEBUG: loading '" + dbghelpPath + "'.");
} else if (! fhelp.exists() && ! feng.exists()) {
// neither exist. We will ignore this dir and assume
// they are in the system dir.
DTFWHome = null;
} else {
// one exists but not the other
//System.err.println("Error: Both files dbghelp.dll and dbgeng.dll "
// "must exist in directory " + DTFWHome);
throw new UnsatisfiedLinkError("Both files dbghelp.dll and " +
"dbgeng.dll must exist in " +
"directory " + DTFWHome);
} }
System.load(dbghelpPath);
if (loadLibraryDEBUG) {
System.err.println("DEBUG: loading '" + dbgengPath + "'.");
} }
if (DTFWHome == null) { System.load(dbgengPath);
// The files better be in the system dir.
String sysDir = System.getenv("SYSTEMROOT") +
File.separator + "system32";
File feng = new File(sysDir + File.separator + "dbgeng.dll"); // Now, load sawindbg.dll
if (!feng.exists()) { if (loadLibraryDEBUG) {
throw new UnsatisfiedLinkError("File dbgeng.dll does not exist in " + System.err.println("DEBUG: loading '" + sawindbgPath + "'.");
sysDir + ". Please search microsoft.com " +
"for Debugging Tools For Windows, and " +
"either download it to the default " +
"location, or download it to a custom " +
"location and set environment variable " +
" DEBUGGINGTOOLSFORWINDOWS " +
"to the pathname of that location.");
}
} }
System.load(sawindbgPath);
// Now, load sawindbg.dll
System.loadLibrary("sawindbg");
// where do I find '.exe', '.dll' files? // where do I find '.exe', '.dll' files?
imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath"); imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath");
if (imagePath == null) { if (imagePath == null) {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册