aboutsummaryrefslogtreecommitdiff
path: root/agent
diff options
context:
space:
mode:
authortrims <none@none>2011-01-07 22:56:35 -0800
committertrims <none@none>2011-01-07 22:56:35 -0800
commit4ec94652362c578c5b0f65ec673bea30842f9ee0 (patch)
tree87a7faced2c948cdad3f7c02883700f89e0ed9d2 /agent
parente6f787b355b119b61693e6f2675dd8c8ddc26b3b (diff)
parentc901cd9d2fade8eada21e5e137fc47e9344edd76 (diff)
Diffstat (limited to 'agent')
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java21
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java59
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java57
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java6
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java191
-rw-r--r--agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java3
6 files changed, 222 insertions, 115 deletions
diff --git a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java
index 967f8a4f1..9cf6122c7 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotTypeDataBase.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -99,15 +99,8 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
long typeEntrySizeOffset;
long typeEntryArrayStride;
- typeEntryTypeNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntryTypeNameOffset");
- typeEntrySuperclassNameOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySuperclassNameOffset");
- typeEntryIsOopTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsOopTypeOffset");
- typeEntryIsIntegerTypeOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsIntegerTypeOffset");
- typeEntryIsUnsignedOffset = getLongValueFromProcess("gHotSpotVMTypeEntryIsUnsignedOffset");
- typeEntrySizeOffset = getLongValueFromProcess("gHotSpotVMTypeEntrySizeOffset");
- typeEntryArrayStride = getLongValueFromProcess("gHotSpotVMTypeEntryArrayStride");
-
- // Fetch the address of the VMTypeEntry*
+ // Fetch the address of the VMTypeEntry*. We get this symbol first
+ // and try to use it to make sure that symbol lookup is working.
Address entryAddr = lookupInProcess("gHotSpotVMTypes");
// System.err.println("gHotSpotVMTypes address = " + entryAddr);
// Dereference this once to get the pointer to the first VMTypeEntry
@@ -118,6 +111,14 @@ public class HotSpotTypeDataBase extends BasicTypeDataBase {
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
Address typeNameAddr = null;
do {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java
index b2c988224..d29a62659 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/COFFFileParser.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -122,10 +122,14 @@ public class COFFFileParser {
private MemoizedObject[] sectionHeaders;
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() {
public Object computeValue() {
+ // the String Table follows the Symbol Table
int ptr = getPointerToSymbolTable();
if (ptr == 0) {
+ // no Symbol Table so no String Table
return new StringTable(0);
} else {
return new StringTable(ptr + SYMBOL_SIZE * getNumberOfSymbols());
@@ -140,6 +144,8 @@ public class COFFFileParser {
timeDateStamp = readInt();
pointerToSymbolTable = readInt();
numberOfSymbols = readInt();
+ // String Table can be accessed at this point because
+ // pointerToSymbolTable and numberOfSymbols fields are set.
sizeOfOptionalHeader = readShort();
characteristics = readShort();
@@ -222,6 +228,8 @@ public class COFFFileParser {
private MemoizedObject windowsSpecificFields;
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 PE32_WINDOWS_SPECIFIC_FIELDS_OFFSET = 28;
private static final int PE32_DATA_DIRECTORIES_OFFSET = 96;
@@ -288,7 +296,7 @@ public class COFFFileParser {
private int sizeOfUninitializedData;
private int addressOfEntryPoint;
private int baseOfCode;
- private int baseOfData;
+ private int baseOfData; // only set in PE32
OptionalHeaderStandardFieldsImpl(int offset,
boolean isPE32Plus) {
@@ -301,7 +309,8 @@ public class COFFFileParser {
sizeOfUninitializedData = readInt();
addressOfEntryPoint = readInt();
baseOfCode = readInt();
- if (isPE32Plus) {
+ if (!isPE32Plus) {
+ // only available in PE32
baseOfData = readInt();
}
}
@@ -433,7 +442,10 @@ public class COFFFileParser {
if (dir.getRVA() == 0 || dir.getSize() == 0) {
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 {
}
class ExportDirectoryTableImpl implements ExportDirectoryTable {
+ private int exportDataDirRVA;
private int offset;
private int size;
@@ -548,8 +561,9 @@ public class COFFFileParser {
private MemoizedObject exportOrdinalTable;
private MemoizedObject exportAddressTable;
- ExportDirectoryTableImpl(int offset, int size) {
- this.offset = offset;
+ ExportDirectoryTableImpl(int exportDataDirRVA, int size) {
+ this.exportDataDirRVA = exportDataDirRVA;
+ offset = rvaToFileOffset(exportDataDirRVA);
this.size = size;
seek(offset);
exportFlags = readInt();
@@ -595,6 +609,7 @@ public class COFFFileParser {
exportOrdinalTable = new MemoizedObject() {
public Object computeValue() {
+ // number of ordinals is same as the number of name pointers
short[] ordinals = new short[getNumberOfNamePointers()];
seek(rvaToFileOffset(getOrdinalTableRVA()));
for (int i = 0; i < ordinals.length; i++) {
@@ -608,14 +623,18 @@ public class COFFFileParser {
public Object computeValue() {
int[] addresses = new int[getNumberOfAddressTableEntries()];
seek(rvaToFileOffset(getExportAddressTableRVA()));
- // Must make two passes to avoid rvaToFileOffset
- // destroying seek() position
+ // The Export Address Table values are a union of two
+ // 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++) {
addresses[i] = readInt();
}
- for (int i = 0; i < addresses.length; i++) {
- addresses[i] = rvaToFileOffset(addresses[i]);
- }
return addresses;
}
};
@@ -648,11 +667,12 @@ public class COFFFileParser {
public boolean isExportAddressForwarder(short ordinal) {
int addr = getExportAddress(ordinal);
- return ((offset <= addr) && (addr < (offset + size)));
+ return ((exportDataDirRVA <= addr) &&
+ (addr < (exportDataDirRVA + size)));
}
public String getExportAddressForwarder(short ordinal) {
- seek(getExportAddress(ordinal));
+ seek(rvaToFileOffset(getExportAddress(ordinal)));
return readCString();
}
@@ -3371,10 +3391,17 @@ public class COFFFileParser {
throw new COFFException(e);
}
// Look up in string table
+ // FIXME: this index value is assumed to be in the valid range
name = getStringTable().get(index);
} else {
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) {
throw new COFFException(e);
}
@@ -3487,6 +3514,7 @@ public class COFFFileParser {
tmpName[5] << 16 |
tmpName[6] << 8 |
tmpName[7]);
+ // FIXME: stringOffset is assumed to be in the valid range
name = getStringTable().getAtOffset(stringOffset);
}
@@ -3698,12 +3726,13 @@ public class COFFFileParser {
StringTable(int offset) {
if (offset == 0) {
+ // no String Table
strings = new COFFString[0];
return;
}
seek(offset);
- int length = readInt();
+ int length = readInt(); // length includes itself
byte[] data = new byte[length - 4];
int numBytesRead = readBytes(data);
if (numBytesRead != data.length) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java
index ec563f1d6..fd9d39aa5 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/DumpExports.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -37,35 +37,48 @@ public class DumpExports {
String filename = args[0];
COFFFile file = COFFFileParser.getParser().parse(filename);
- ExportDirectoryTable exports =
- file.getHeader().
- getOptionalHeader().
- getDataDirectories().
- getExportDirectoryTable();
+
+ // get common point for both things we want to dump
+ OptionalHeaderDataDirectories dataDirs = file.getHeader().getOptionalHeader().
+ getDataDirectories();
+
+ // dump the header data directory for the Export Table:
+ DataDirectory dir = dataDirs.getExportTable();
+ 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");
+ for (int i = 1; i <= file.getHeader().getNumberOfSections(); i++) {
+ 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()));
+ }
+
+ ExportDirectoryTable exports = dataDirs.getExportDirectoryTable();
if (exports == null) {
System.out.println("No exports found.");
} else {
- System.out.println(file.getHeader().getNumberOfSections() + " sections in file");
- for (int i = 0; i < file.getHeader().getNumberOfSections(); i++) {
- System.out.println(" Section " + i + ": " + file.getHeader().getSectionHeader(1 + i).getName());
- }
-
- DataDirectory dir = file.getHeader().getOptionalHeader().getDataDirectories().getExportTable();
- System.out.println("Export table: RVA = 0x" + Integer.toHexString(dir.getRVA()) +
- ", size = 0x" + Integer.toHexString(dir.getSize()));
-
System.out.println("DLL name: " + exports.getDLLName());
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("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++) {
- System.out.println(" 0x" +
- Integer.toHexString(exports.getExportAddress(exports.getExportOrdinal(i))) +
- " " +
- (exports.isExportAddressForwarder(exports.getExportOrdinal(i)) ?
- ("Forwarded to " + exports.getExportAddressForwarder(exports.getExportOrdinal(i))) :
- exports.getExportName(i)));
+ short ordinal = exports.getExportOrdinal(i);
+ System.out.print("[" + i + "] '" + exports.getExportName(i) + "': [" +
+ ordinal + "] = 0x" + Integer.toHexString(exports.getExportAddress(ordinal)));
+ System.out.println(exports.isExportAddressForwarder(ordinal)
+ ? " Forwarded to '" + exports.getExportAddressForwarder(ordinal) + "'"
+ : "");
}
}
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java
index 6f026838d..e6f42df3a 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/win32/coff/TestParser.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -42,8 +42,8 @@ public class TestParser {
COFFHeader header = file.getHeader();
int numSections = header.getNumberOfSections();
System.out.println(numSections + " sections detected.");
- for (int i = 0; i < numSections; i++) {
- SectionHeader secHeader = header.getSectionHeader(1 + i);
+ for (int i = 1; i <= numSections; i++) {
+ SectionHeader secHeader = header.getSectionHeader(i);
System.out.println(secHeader.getName());
}
diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
index 53141a6d2..3e5a6aa96 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java
@@ -1,5 +1,5 @@
/*
- * 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.
*
* This code is free software; you can redistribute it and/or modify it
@@ -506,7 +506,6 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger
throw new DebuggerException("Unimplemented");
}
- private static String DTFWHome;
private static String imagePath;
private static String symbolPath;
private static boolean useNativeLookup;
@@ -514,81 +513,143 @@ public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger
static {
/*
- * sawindbg.dll depends on dbgeng.dll which
- * itself depends on dbghelp.dll. dbgeng.dll and dbghelp.dll.
- * On systems newer than Windows 2000, these two .dlls are
- * in the standard system directory so we will find them there.
- * On Windows 2000 and earlier, these files do not exist.
- * The user must download Debugging Tools For Windows (DTFW)
- * and install it in order to use SA.
+ * sawindbg.dll depends on dbgeng.dll which itself depends on
+ * dbghelp.dll. We have to make sure that the dbgeng.dll and
+ * dbghelp.dll that we load are compatible with each other. We
+ * load both of those libraries from the same directory based
+ * on the theory that co-located libraries are compatible.
*
- * We have to make sure we use the two files from the same directory
- * in case there are more than one copy on the system because
- * one version of dbgeng.dll might not be compatible with a
- * different version of dbghelp.dll.
- * We first look for them in the directory pointed at by
- * env. var. DEBUGGINGTOOLSFORWINDOWS, next in the default
- * installation dir for DTFW, and lastly in the standard
- * system directory. We expect that that we will find
- * them in the standard system directory on all systems
- * newer than Windows 2000.
+ * On Windows 2000 and earlier, dbgeng.dll and dbghelp.dll were
+ * not included as part of the standard system directory. On
+ * systems newer than Windows 2000, dbgeng.dll and dbghelp.dll
+ * are included in the standard system directory. However, the
+ * versions included in the standard system directory may not
+ * be able to handle symbol information for the newer compilers.
+ *
+ * We search for and explicitly load the libraries using the
+ * following directory search order:
+ *
+ * - 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) {
- // See if we have the files in the default location.
+ String dbgengPath = null;
+ 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");
- DTFWHome = sysRoot + File.separator +
- ".." + File.separator + "Program Files" +
- File.separator + "Debugging Tools For Windows";
+ DTFWHome = sysRoot + File.separator + ".." + File.separator +
+ "Program Files" + 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");
}
- {
- 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
- // first, then the dependency - dbghelp.dll - will be loaded
- // from usual DLL search thereby defeating the purpose!
- System.load(dbghelp);
- System.load(dbgeng);
- } 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);
+ 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 (DTFWHome == null) {
- // 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");
- if (!feng.exists()) {
- throw new UnsatisfiedLinkError("File dbgeng.dll does not exist in " +
- 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.");
+
+ 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.");
}
+ // NOTE: The order of loads is important! If we load dbgeng.dll
+ // first, then the dependency - dbghelp.dll - will be loaded
+ // from usual DLL search thereby defeating the purpose!
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: loading '" + dbghelpPath + "'.");
+ }
+ System.load(dbghelpPath);
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: loading '" + dbgengPath + "'.");
+ }
+ System.load(dbgengPath);
+
// Now, load sawindbg.dll
- System.loadLibrary("sawindbg");
+ if (loadLibraryDEBUG) {
+ System.err.println("DEBUG: loading '" + sawindbgPath + "'.");
+ }
+ System.load(sawindbgPath);
+
// where do I find '.exe', '.dll' files?
imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath");
if (imagePath == null) {
diff --git a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
index d7101696c..979d80b30 100644
--- a/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
+++ b/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java
@@ -30,6 +30,7 @@ import sun.jvm.hotspot.asm.*;
import sun.jvm.hotspot.asm.sparc.*;
import sun.jvm.hotspot.asm.x86.*;
import sun.jvm.hotspot.asm.ia64.*;
+import sun.jvm.hotspot.asm.amd64.*;
import sun.jvm.hotspot.code.*;
import sun.jvm.hotspot.compiler.*;
import sun.jvm.hotspot.debugger.*;
@@ -198,6 +199,8 @@ public class HTMLGenerator implements /* imports */ ClassConstants {
cpuHelper = new SPARCHelper();
} else if (cpu.equals("x86")) {
cpuHelper = new X86Helper();
+ } else if (cpu.equals("amd64")) {
+ cpuHelper = new AMD64Helper();
} else if (cpu.equals("ia64")) {
cpuHelper = new IA64Helper();
} else {