diff --git a/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java b/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java index 5071235fa3e978ffaf0b948e07d8ea0c35fb5645..9e8d016dcc2e1f19eecb8b2ea7e7b685d5263610 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java +++ b/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java @@ -31,13 +31,19 @@ import java.io.*; import java.util.*; public class CLHSDB { + + public CLHSDB(JVMDebugger d) { + jvmDebugger = d; + } + public static void main(String[] args) { new CLHSDB(args).run(); } - private void run() { - // At this point, if pidText != null we are supposed to attach to it. - // Else, if execPath != null, it is the path of a jdk/bin/java + public void run() { + // If jvmDebugger is already set, we have been given a JVMDebugger. + // Otherwise, if pidText != null we are supposed to attach to it. + // Finally, if execPath != null, it is the path of a jdk/bin/java // and coreFilename is the pathname of a core file we are // supposed to attach to. @@ -49,7 +55,9 @@ public class CLHSDB { } }); - if (pidText != null) { + if (jvmDebugger != null) { + attachDebugger(jvmDebugger); + } else if (pidText != null) { attachDebugger(pidText); } else if (execPath != null) { attachDebugger(execPath, coreFilename); @@ -96,6 +104,7 @@ public class CLHSDB { // Internals only below this point // private HotSpotAgent agent; + private JVMDebugger jvmDebugger; private boolean attached; // These had to be made data members because they are referenced in inner classes. private String pidText; @@ -120,7 +129,7 @@ public class CLHSDB { case (1): if (args[0].equals("help") || args[0].equals("-help")) { doUsage(); - System.exit(0); + return; } // If all numbers, it is a PID to attach to // Else, it is a pathname to a .../bin/java for a core file. @@ -142,10 +151,15 @@ public class CLHSDB { default: System.out.println("HSDB Error: Too many options specified"); doUsage(); - System.exit(1); + return; } } + private void attachDebugger(JVMDebugger d) { + agent.attach(d); + attached = true; + } + /** NOTE we are in a different thread here than either the main thread or the Swing/AWT event handler thread, so we must be very careful when creating or removing widgets */ diff --git a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java index 2233844267c6d6f36127c1ff758943f99bba86e7..1840caf9313dba56a4cb02a5d4be275dcef4c4c2 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java +++ b/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java @@ -101,6 +101,9 @@ import sun.jvm.hotspot.utilities.soql.JSJavaFactoryImpl; import sun.jvm.hotspot.utilities.soql.JSJavaScriptEngine; public class CommandProcessor { + + volatile boolean quit; + public abstract static class DebuggerInterface { public abstract HotSpotAgent getAgent(); public abstract boolean isAttached(); @@ -1135,7 +1138,7 @@ public class CommandProcessor { usage(); } else { debugger.detach(); - System.exit(0); + quit = true; } } }, @@ -1714,7 +1717,7 @@ public class CommandProcessor { } protected void quit() { debugger.detach(); - System.exit(0); + quit = true; } protected BufferedReader getInputReader() { return in; @@ -1781,7 +1784,7 @@ public class CommandProcessor { public void run(boolean prompt) { // Process interactive commands. - while (true) { + while (!quit) { if (prompt) printPrompt(); String ln = null; try { diff --git a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java index 5143408c68758e3ae650e69b5f08eb1ebcae48ef..d50cbaa5140bfb4e039984437250f6ab6226227c 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/HSDB.java +++ b/agent/src/share/classes/sun/jvm/hotspot/HSDB.java @@ -59,8 +59,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { // Internals only below this point // private HotSpotAgent agent; + private JVMDebugger jvmDebugger; private JDesktopPane desktop; private boolean attached; + private boolean argError; + private JFrame frame; /** List */ private java.util.List attachMenuItems; /** List */ @@ -85,6 +88,11 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { System.out.println(" path-to-corefile: Debug this corefile. The default is 'core'"); System.out.println(" If no arguments are specified, you can select what to do from the GUI.\n"); HotSpotAgent.showUsage(); + argError = true; + } + + public HSDB(JVMDebugger d) { + jvmDebugger = d; } private HSDB(String[] args) { @@ -95,7 +103,6 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { case (1): if (args[0].equals("help") || args[0].equals("-help")) { doUsage(); - System.exit(0); } // If all numbers, it is a PID to attach to // Else, it is a pathname to a .../bin/java for a core file. @@ -117,24 +124,29 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { default: System.out.println("HSDB Error: Too many options specified"); doUsage(); - System.exit(1); } } - private void run() { - // At this point, if pidText != null we are supposed to attach to it. - // Else, if execPath != null, it is the path of a jdk/bin/java - // and coreFilename is the pathname of a core file we are - // supposed to attach to. + // close this tool without calling System.exit + protected void closeUI() { + workerThread.shutdown(); + frame.dispose(); + } + + public void run() { + // Don't start the UI if there were bad arguments. + if (argError) { + return; + } agent = new HotSpotAgent(); workerThread = new WorkerThread(); attachMenuItems = new java.util.ArrayList(); detachMenuItems = new java.util.ArrayList(); - JFrame frame = new JFrame("HSDB - HotSpot Debugger"); + frame = new JFrame("HSDB - HotSpot Debugger"); frame.setSize(800, 600); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); JMenuBar menuBar = new JMenuBar(); @@ -197,7 +209,7 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { item = createMenuItem("Exit", new ActionListener() { public void actionPerformed(ActionEvent e) { - System.exit(0); + closeUI(); } }); item.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X, ActionEvent.ALT_MASK)); @@ -406,7 +418,15 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { } }); - if (pidText != null) { + // If jvmDebugger is already set, we have been given a JVMDebugger. + // Otherwise, if pidText != null we are supposed to attach to it. + // Finally, if execPath != null, it is the path of a jdk/bin/java + // and coreFilename is the pathname of a core file we are + // supposed to attach to. + + if (jvmDebugger != null) { + attach(jvmDebugger); + } else if (pidText != null) { attach(pidText); } else if (execPath != null) { attach(execPath, coreFilename); @@ -1113,6 +1133,12 @@ public class HSDB implements ObjectHistogramPanel.Listener, SAListener { }); } + // Attach to existing JVMDebugger, which should be already attached to a core/process. + private void attach(JVMDebugger d) { + attached = true; + showThreadsDialog(); + } + /** NOTE we are in a different thread here than either the main thread or the Swing/AWT event handler thread, so we must be very careful when creating or removing widgets */ diff --git a/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java b/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java index bdf9bd369e62c7d2aa85b285129f22001325e1ee..c963350591da2066db6201364eeb1207ded186ab 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java +++ b/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java @@ -25,6 +25,8 @@ package sun.jvm.hotspot; import java.rmi.RemoteException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; import sun.jvm.hotspot.debugger.Debugger; import sun.jvm.hotspot.debugger.DebuggerException; @@ -63,7 +65,6 @@ public class HotSpotAgent { private String os; private String cpu; - private String fileSep; // The system can work in several ways: // - Attaching to local process @@ -155,6 +156,14 @@ public class HotSpotAgent { go(); } + /** This uses a JVMDebugger that is already attached to the core or process */ + public synchronized void attach(JVMDebugger d) + throws DebuggerException { + debugger = d; + isServer = false; + go(); + } + /** This attaches to a "debug server" on a remote machine; this remote server has already attached to a process or opened a core file and is waiting for RMI calls on the Debugger object to @@ -303,28 +312,37 @@ public class HotSpotAgent { // server, but not client attaching to server) // - try { - os = PlatformInfo.getOS(); - cpu = PlatformInfo.getCPU(); - } - catch (UnsupportedPlatformException e) { - throw new DebuggerException(e); - } - fileSep = System.getProperty("file.separator"); + // Handle existing or alternate JVMDebugger: + // these will set os, cpu independently of our PlatformInfo implementation. + String alternateDebugger = System.getProperty("sa.altDebugger"); + if (debugger != null) { + setupDebuggerExisting(); + + } else if (alternateDebugger != null) { + setupDebuggerAlternate(alternateDebugger); - if (os.equals("solaris")) { - setupDebuggerSolaris(); - } else if (os.equals("win32")) { - setupDebuggerWin32(); - } else if (os.equals("linux")) { - setupDebuggerLinux(); - } else if (os.equals("bsd")) { - setupDebuggerBsd(); - } else if (os.equals("darwin")) { - setupDebuggerDarwin(); } else { - // Add support for more operating systems here - throw new DebuggerException("Operating system " + os + " not yet supported"); + // Otherwise, os, cpu are those of our current platform: + try { + os = PlatformInfo.getOS(); + cpu = PlatformInfo.getCPU(); + } catch (UnsupportedPlatformException e) { + throw new DebuggerException(e); + } + if (os.equals("solaris")) { + setupDebuggerSolaris(); + } else if (os.equals("win32")) { + setupDebuggerWin32(); + } else if (os.equals("linux")) { + setupDebuggerLinux(); + } else if (os.equals("bsd")) { + setupDebuggerBsd(); + } else if (os.equals("darwin")) { + setupDebuggerDarwin(); + } else { + // Add support for more operating systems here + throw new DebuggerException("Operating system " + os + " not yet supported"); + } } if (isServer) { @@ -423,6 +441,41 @@ public class HotSpotAgent { // OS-specific debugger setup/connect routines // + // Use the existing JVMDebugger, as passed to our constructor. + // Retrieve os and cpu from that debugger, not the current platform. + private void setupDebuggerExisting() { + + os = debugger.getOS(); + cpu = debugger.getCPU(); + setupJVMLibNames(os); + machDesc = debugger.getMachineDescription(); + } + + // Given a classname, load an alternate implementation of JVMDebugger. + private void setupDebuggerAlternate(String alternateName) { + + try { + Class c = Class.forName(alternateName); + Constructor cons = c.getConstructor(); + debugger = (JVMDebugger) cons.newInstance(); + attachDebugger(); + setupDebuggerExisting(); + + } catch (ClassNotFoundException cnfe) { + throw new DebuggerException("Cannot find alternate SA Debugger: '" + alternateName + "'"); + } catch (NoSuchMethodException nsme) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' has missing constructor."); + } catch (InstantiationException ie) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", ie); + } catch (IllegalAccessException iae) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae); + } catch (InvocationTargetException iae) { + throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae); + } + + System.err.println("Loaded alternate HotSpot SA Debugger: " + alternateName); + } + // // Solaris // @@ -466,6 +519,11 @@ public class HotSpotAgent { debugger = new RemoteDebuggerClient(remote); machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); os = debugger.getOS(); + setupJVMLibNames(os); + cpu = debugger.getCPU(); + } + + private void setupJVMLibNames(String os) { if (os.equals("solaris")) { setupJVMLibNamesSolaris(); } else if (os.equals("win32")) { @@ -479,8 +537,6 @@ public class HotSpotAgent { } else { throw new RuntimeException("Unknown OS type"); } - - cpu = debugger.getCPU(); } private void setupJVMLibNamesSolaris() { diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java index 9e85e133b3a537c083a1249a0617ca1ba17e04ed..cff29ce8edc37e3f9ffa9ebe6ab578b4121512e1 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java @@ -26,11 +26,11 @@ package sun.jvm.hotspot.debugger.linux; import sun.jvm.hotspot.debugger.*; -class LinuxAddress implements Address { +public class LinuxAddress implements Address { protected LinuxDebugger debugger; protected long addr; - LinuxAddress(LinuxDebugger debugger, long addr) { + public LinuxAddress(LinuxDebugger debugger, long addr) { this.debugger = debugger; this.addr = addr; } diff --git a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java index 310acb88ac768b2fefe8b7c0571954a4a4b6d98a..99291aada294829c54735fd8ee54926f572a873e 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java +++ b/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java @@ -26,8 +26,8 @@ package sun.jvm.hotspot.debugger.linux; import sun.jvm.hotspot.debugger.*; -class LinuxOopHandle extends LinuxAddress implements OopHandle { - LinuxOopHandle(LinuxDebugger debugger, long addr) { +public class LinuxOopHandle extends LinuxAddress implements OopHandle { + public LinuxOopHandle(LinuxDebugger debugger, long addr) { super(debugger, addr); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java index 0a9d94368783a395b70c1d6405e9f66b6e8ff9c2..f84da894ac2de30064b42e4465a21e3678a6053f 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java +++ b/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java @@ -246,7 +246,7 @@ public class VM { } } - private static final boolean disableDerivedPrinterTableCheck; + private static final boolean disableDerivedPointerTableCheck; private static final Properties saProps; static { @@ -256,12 +256,12 @@ public class VM { url = VM.class.getClassLoader().getResource("sa.properties"); saProps.load(new BufferedInputStream(url.openStream())); } catch (Exception e) { - throw new RuntimeException("Unable to load properties " + + System.err.println("Unable to load properties " + (url == null ? "null" : url.toString()) + ": " + e.getMessage()); } - disableDerivedPrinterTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null; + disableDerivedPointerTableCheck = System.getProperty("sun.jvm.hotspot.runtime.VM.disableDerivedPointerTableCheck") != null; } private VM(TypeDataBase db, JVMDebugger debugger, boolean isBigEndian) { @@ -371,7 +371,8 @@ public class VM { /** This is used by the debugging system */ public static void initialize(TypeDataBase db, JVMDebugger debugger) { if (soleInstance != null) { - throw new RuntimeException("Attempt to initialize VM twice"); + // Using multiple SA Tool classes in the same process creates a call here. + return; } soleInstance = new VM(db, debugger, debugger.getMachineDescription().isBigEndian()); @@ -683,7 +684,7 @@ public class VM { /** Returns true if C2 derived pointer table should be used, false otherwise */ public boolean useDerivedPointerTable() { - return !disableDerivedPrinterTableCheck; + return !disableDerivedPointerTableCheck; } /** Returns the code cache; should not be used if is core build */ diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java b/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java index 77f0f800445b8c1260c37905772fef43acc2f7ed..eeda376b1d65d3cc57418b9e62f1db07480064d2 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java @@ -41,6 +41,14 @@ import sun.jvm.hotspot.utilities.*; public class ClassLoaderStats extends Tool { boolean verbose = true; + public ClassLoaderStats() { + super(); + } + + public ClassLoaderStats(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { ClassLoaderStats cls = new ClassLoaderStats(); cls.start(args); diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java b/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java index 79e6784a63e6569e7e56b5cc1674f9293ebf86a0..ed707b9ee8a424e996cabc3095259dd1f2215b2d 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java @@ -24,6 +24,7 @@ package sun.jvm.hotspot.tools; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.tools.*; import sun.jvm.hotspot.oops.*; @@ -42,6 +43,15 @@ import java.util.Comparator; * summary of these objects in the form of a histogram. */ public class FinalizerInfo extends Tool { + + public FinalizerInfo() { + super(); + } + + public FinalizerInfo(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { FinalizerInfo finfo = new FinalizerInfo(); finfo.start(args); diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java b/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java index effeabb582afd0ab169ed6c26987e4127095ec12..c8db6d6b044b7e04ac633e412621aa70acd94ee6 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java @@ -25,10 +25,19 @@ package sun.jvm.hotspot.tools; import java.io.PrintStream; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.runtime.*; public class FlagDumper extends Tool { + public FlagDumper() { + super(); + } + + public FlagDumper(JVMDebugger d) { + super(d); + } + public void run() { VM.Flag[] flags = VM.getVM().getCommandLineFlags(); PrintStream out = System.out; diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java index 5a7c06618b9644b6813f8c00bfadee32338ea3df..c5af0ed005dae2885b5c087386489d6ee5d704ae 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.tools; import sun.jvm.hotspot.utilities.HeapHprofBinWriter; +import sun.jvm.hotspot.debugger.JVMDebugger; import java.io.IOException; /* @@ -42,6 +43,11 @@ public class HeapDumper extends Tool { this.dumpFile = dumpFile; } + public HeapDumper(String dumpFile, JVMDebugger d) { + super(d); + this.dumpFile = dumpFile; + } + protected void printFlagsUsage() { System.out.println(" \tto dump heap to " + DEFAULT_DUMP_FILE); diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java index 8762165526953c539b7022edb85ce9d49ae87551..a0123dd4c999ded177bda02ae5cf82fe2a3c2975 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java @@ -29,12 +29,21 @@ import sun.jvm.hotspot.gc_interface.*; import sun.jvm.hotspot.gc_implementation.g1.*; import sun.jvm.hotspot.gc_implementation.parallelScavenge.*; import sun.jvm.hotspot.gc_implementation.shared.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.memory.*; import sun.jvm.hotspot.oops.*; import sun.jvm.hotspot.runtime.*; public class HeapSummary extends Tool { + public HeapSummary() { + super(); + } + + public HeapSummary(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { HeapSummary hs = new HeapSummary(); hs.start(args); diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java b/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java index a9f6c0e9c90ac04e6cc06d2af8b923263774d4a3..f2452420744d78f530bc5b3d3a06c84681591f85 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java @@ -25,12 +25,21 @@ package sun.jvm.hotspot.tools; import sun.jvm.hotspot.runtime.*; +import sun.jvm.hotspot.debugger.JVMDebugger; public class JInfo extends Tool { + public JInfo() { + super(); + } + public JInfo(int m) { mode = m; } + public JInfo(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java b/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java index d9ea364edaadaf233f0fb12d67373024555224bc..f6f3c0741c04d0a45a940606da3d3468aad8376e 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.tools; import java.io.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.utilities.*; public class JMap extends Tool { @@ -36,6 +37,10 @@ public class JMap extends Tool { this(MODE_PMAP); } + public JMap(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java b/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java index 95f46445f8a42cd49097e1971dd9eabed6673800..9301f1059fd3a3819003b2466d5a6f6a6b7e0c8c 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java @@ -25,9 +25,19 @@ package sun.jvm.hotspot.tools; import java.io.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.runtime.*; public class JSnap extends Tool { + + public JSnap() { + super(); + } + + public JSnap(JVMDebugger d) { + super(d); + } + public void run() { final PrintStream out = System.out; if (PerfMemory.initialized()) { diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java b/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java index 9e0688cf393239c024b0a568a76a5692b4a98972..7cbe8f4d94540386dbd0cb76327c4e1c56e1779d 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java @@ -24,6 +24,8 @@ package sun.jvm.hotspot.tools; +import sun.jvm.hotspot.debugger.JVMDebugger; + public class JStack extends Tool { public JStack(boolean mixedMode, boolean concurrentLocks) { this.mixedMode = mixedMode; @@ -34,6 +36,10 @@ public class JStack extends Tool { this(true, true); } + public JStack(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java b/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java index f03469e13f1d6bf1eeba11e27d21acd81c8e21d1..168202eec2cef7a92e309443dd5a753e1dd61ea8 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java @@ -33,6 +33,14 @@ import java.io.PrintStream; an object histogram from a remote or crashed VM. */ public class ObjectHistogram extends Tool { + public ObjectHistogram() { + super(); + } + + public ObjectHistogram(JVMDebugger d) { + super(d); + } + public void run() { run(System.out, System.err); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java b/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java index 70bd55513b9d2d60e1b1407e2cdfe1b10807e25d..2a234130991cf204564c744559056617f17929b7 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java @@ -31,6 +31,15 @@ import sun.jvm.hotspot.debugger.cdbg.*; import sun.jvm.hotspot.runtime.*; public class PMap extends Tool { + + public PMap() { + super(); + } + + public PMap(JVMDebugger d) { + super(d); + } + public void run() { run(System.out); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java index 0b3720ff5941e16d3edaade8529091fc6ec93eb0..7f10612b3170fa29e814657e7841d608be04b9db 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java @@ -45,6 +45,10 @@ public class PStack extends Tool { this(true, true); } + public PStack(JVMDebugger d) { + super(d); + } + public void run() { run(System.out); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java b/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java index 83270bfdeff871cebe99c4eda9a5b444a33c1042..eb0cc88d116a071177ea5e514d967f82e0db6e5e 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java @@ -45,6 +45,16 @@ public class StackTrace extends Tool { run(System.out); } + public StackTrace(JVMDebugger d) { + super(d); + } + + public StackTrace(JVMDebugger d, boolean v, boolean concurrentLocks) { + super(d); + this.verbose = v; + this.concurrentLocks = concurrentLocks; + } + public void run(java.io.PrintStream tty) { // Ready to go with the database... try { diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java b/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java index bb4f703c64bf793975ef9df2bf73c34eab98c0d2..d601fef44010a510261395c799616d318dd9cf17 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java @@ -27,10 +27,19 @@ package sun.jvm.hotspot.tools; import java.io.PrintStream; import java.util.*; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.runtime.*; public class SysPropsDumper extends Tool { + public SysPropsDumper() { + super(); + } + + public SysPropsDumper(JVMDebugger d) { + super(d); + } + public void run() { Properties sysProps = VM.getVM().getSystemProperties(); PrintStream out = System.out; diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java index 4279c425bd8383d9ecc54718391fd7f0ea50f6d1..3021801c9ddff28a2e36d5868b61b6d97b948a72 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java @@ -35,6 +35,7 @@ import sun.jvm.hotspot.debugger.*; public abstract class Tool implements Runnable { private HotSpotAgent agent; + private JVMDebugger jvmDebugger; private int debugeeType; // debugeeType is one of constants below @@ -42,6 +43,13 @@ public abstract class Tool implements Runnable { protected static final int DEBUGEE_CORE = 1; protected static final int DEBUGEE_REMOTE = 2; + public Tool() { + } + + public Tool(JVMDebugger d) { + jvmDebugger = d; + } + public String getName() { return getClass().getName(); } @@ -90,7 +98,6 @@ public abstract class Tool implements Runnable { protected void usage() { printUsage(); - System.exit(1); } /* @@ -106,13 +113,13 @@ public abstract class Tool implements Runnable { protected void stop() { if (agent != null) { agent.detach(); - System.exit(0); } } protected void start(String[] args) { if ((args.length < 1) || (args.length > 2)) { usage(); + return; } // Attempt to handle -h or -help or some invalid flag @@ -185,13 +192,31 @@ public abstract class Tool implements Runnable { } if (e.getMessage() != null) { err.print(e.getMessage()); + e.printStackTrace(); } err.println(); - System.exit(1); + return; } err.println("Debugger attached successfully."); + startInternal(); + } + + // When using an existing JVMDebugger. + public void start() { + if (jvmDebugger == null) { + throw new RuntimeException("Tool.start() called with no JVMDebugger set."); + } + agent = new HotSpotAgent(); + agent.attach(jvmDebugger); + startInternal(); + } + + // Remains of the start mechanism, common to both start methods. + private void startInternal() { + + PrintStream err = System.err; VM vm = VM.getVM(); if (vm.isCore()) { err.println("Core build detected."); diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java index 34ccc102acbb7cdbef8e5d8652b7594866ca68af..96817b262261afd544cd5282642f2a7e337ce3e9 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java @@ -25,6 +25,7 @@ package sun.jvm.hotspot.tools.jcore; import java.io.*; +import java.lang.reflect.Constructor; import java.util.jar.JarOutputStream; import java.util.jar.JarEntry; import java.util.jar.Manifest; @@ -38,6 +39,16 @@ public class ClassDump extends Tool { private ClassFilter classFilter; private String outputDirectory; private JarOutputStream jarStream; + private String pkgList; + + public ClassDump() { + super(); + } + + public ClassDump(JVMDebugger d, String pkgList) { + super(d); + this.pkgList = pkgList; + } public void setClassFilter(ClassFilter cf) { classFilter = cf; @@ -63,6 +74,25 @@ public class ClassDump extends Tool { public void run() { // Ready to go with the database... try { + // The name of the filter always comes from a System property. + // If we have a pkgList, pass it, otherwise let the filter read + // its own System property for the list of classes. + String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter", + "sun.jvm.hotspot.tools.jcore.PackageNameFilter"); + try { + Class filterClass = Class.forName(filterClassName); + if (pkgList == null) { + classFilter = (ClassFilter) filterClass.newInstance(); + } else { + Constructor con = filterClass.getConstructor(String.class); + classFilter = (ClassFilter) con.newInstance(pkgList); + } + } catch(Exception exp) { + System.err.println("Warning: Can not create class filter!"); + } + + String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir", "."); + setOutputDirectory(outputDirectory); // walk through the system dictionary SystemDictionary dict = VM.getVM().getSystemDictionary(); @@ -139,26 +169,8 @@ public class ClassDump extends Tool { } public static void main(String[] args) { - // load class filters - ClassFilter classFilter = null; - String filterClassName = System.getProperty("sun.jvm.hotspot.tools.jcore.filter"); - if (filterClassName != null) { - try { - Class filterClass = Class.forName(filterClassName); - classFilter = (ClassFilter) filterClass.newInstance(); - } catch(Exception exp) { - System.err.println("Warning: Can not create class filter!"); - } - } - - String outputDirectory = System.getProperty("sun.jvm.hotspot.tools.jcore.outputDir"); - if (outputDirectory == null) - outputDirectory = "."; - ClassDump cd = new ClassDump(); - cd.setClassFilter(classFilter); - cd.setOutputDirectory(outputDirectory); cd.start(args); cd.stop(); } diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java b/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java index e46de0194d79b5b6b9974e024072bab5064dc62d..09874af178ef9c46a6a677fe5e24aa2c92bbdbdc 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java @@ -24,12 +24,22 @@ package sun.jvm.hotspot.tools.soql; +import sun.jvm.hotspot.debugger.JVMDebugger; import sun.jvm.hotspot.tools.*; import sun.jvm.hotspot.utilities.*; import sun.jvm.hotspot.utilities.soql.*; /** This is command line JavaScript debugger console */ public class JSDB extends Tool { + + public JSDB() { + super(); + } + + public JSDB(JVMDebugger d) { + super(d); + } + public static void main(String[] args) { JSDB jsdb = new JSDB(); jsdb.start(args); diff --git a/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java b/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java index 3a4c2470b1b5ecbbd48a093bd9e1cbc56e525387..b3054b90bd05ab58f90f0fb89a92ab71d47edf2a 100644 --- a/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java @@ -44,6 +44,14 @@ public class SOQL extends Tool { soql.stop(); } + public SOQL() { + super(); + } + + public SOQL(JVMDebugger d) { + super(d); + } + protected SOQLEngine soqlEngine; protected BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); protected PrintStream out = System.out;