# HG changeset patch # User nloodin # Date 1372421127 -7200 # Node ID e15204f64e5dfe828ad02b4a4f1dc209f7ddfc56 # Parent ce52e6a87aed11b79c212587a841dd87db4cf4d2# Parent c021907fa0a707102c176221f35f7f26c5ef5a18 Merge diff -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CLHSDB.java Fri Jun 28 14:05:27 2013 +0200 @@ -31,13 +31,19 @@ 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 @@ } }); - 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 @@ // 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 @@ 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 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/CommandProcessor.java Fri Jun 28 14:05:27 2013 +0200 @@ -101,6 +101,9 @@ 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 @@ usage(); } else { debugger.detach(); - System.exit(0); + quit = true; } } }, @@ -1714,7 +1717,7 @@ } protected void quit() { debugger.detach(); - System.exit(0); + quit = true; } protected BufferedReader getInputReader() { return in; @@ -1781,7 +1784,7 @@ public void run(boolean prompt) { // Process interactive commands. - while (true) { + while (!quit) { if (prompt) printPrompt(); String ln = null; try { diff -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HSDB.java Fri Jun 28 14:05:27 2013 +0200 @@ -59,8 +59,11 @@ // 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ } }); - 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 @@ }); } + // 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 @@ private String os; private String cpu; - private String fileSep; // The system can work in several ways: // - Attaching to local process @@ -155,6 +156,14 @@ 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 @@ // 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 @@ // 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 @@ 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 @@ } else { throw new RuntimeException("Unknown OS type"); } - - cpu = debugger.getCPU(); } private void setupJVMLibNamesSolaris() { diff -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxAddress.java Fri Jun 28 14:05:27 2013 +0200 @@ -26,11 +26,11 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/debugger/linux/LinuxOopHandle.java Fri Jun 28 14:05:27 2013 +0200 @@ -26,8 +26,8 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Fri Jun 28 14:05:27 2013 +0200 @@ -246,7 +246,7 @@ } } - private static final boolean disableDerivedPrinterTableCheck; + private static final boolean disableDerivedPointerTableCheck; private static final Properties saProps; static { @@ -256,12 +256,12 @@ 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 @@ /** 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 @@ /** 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ClassLoaderStats.java Fri Jun 28 14:05:27 2013 +0200 @@ -41,6 +41,14 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FinalizerInfo.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 @@ * 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/FlagDumper.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapDumper.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/HeapSummary.java Fri Jun 28 14:05:27 2013 +0200 @@ -29,12 +29,21 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JInfo.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JMap.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 @@ this(MODE_PMAP); } + public JMap(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JSnap.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/JStack.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 @@ this(true, true); } + public JStack(JVMDebugger d) { + super(d); + } + protected boolean needsJavaPrefix() { return false; } diff -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/ObjectHistogram.java Fri Jun 28 14:05:27 2013 +0200 @@ -33,6 +33,14 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Fri Jun 28 14:05:27 2013 +0200 @@ -31,6 +31,15 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Fri Jun 28 14:05:27 2013 +0200 @@ -45,6 +45,10 @@ this(true, true); } + public PStack(JVMDebugger d) { + super(d); + } + public void run() { run(System.out); } diff -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/StackTrace.java Fri Jun 28 14:05:27 2013 +0200 @@ -45,6 +45,16 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/SysPropsDumper.java Fri Jun 28 14:05:27 2013 +0200 @@ -27,10 +27,19 @@ 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Fri Jun 28 14:05:27 2013 +0200 @@ -35,6 +35,7 @@ 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 @@ 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 @@ protected void usage() { printUsage(); - System.exit(1); } /* @@ -106,13 +113,13 @@ 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 @@ } 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/jcore/ClassDump.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 @@ 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 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 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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/JSDB.java Fri Jun 28 14:05:27 2013 +0200 @@ -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 -r ce52e6a87aed -r e15204f64e5d hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java --- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/tools/soql/SOQL.java Fri Jun 28 14:05:27 2013 +0200 @@ -44,6 +44,14 @@ 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; diff -r ce52e6a87aed -r e15204f64e5d hotspot/src/share/vm/memory/filemap.cpp --- a/hotspot/src/share/vm/memory/filemap.cpp Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/src/share/vm/memory/filemap.cpp Fri Jun 28 14:05:27 2013 +0200 @@ -549,3 +549,13 @@ return false; } + +void FileMapInfo::print_shared_spaces() { + gclog_or_tty->print_cr("Shared Spaces:"); + for (int i = 0; i < MetaspaceShared::n_regions; i++) { + struct FileMapInfo::FileMapHeader::space_info* si = &_header._space[i]; + gclog_or_tty->print(" %s " INTPTR_FORMAT "-" INTPTR_FORMAT, + shared_region_name[i], + si->_base, si->_base + si->_used); + } +} diff -r ce52e6a87aed -r e15204f64e5d hotspot/src/share/vm/memory/filemap.hpp --- a/hotspot/src/share/vm/memory/filemap.hpp Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/src/share/vm/memory/filemap.hpp Fri Jun 28 14:05:27 2013 +0200 @@ -149,6 +149,7 @@ // Return true if given address is in the mapped shared space. bool is_in_shared_space(const void* p) NOT_CDS_RETURN_(false); + void print_shared_spaces() NOT_CDS_RETURN; }; #endif // SHARE_VM_MEMORY_FILEMAP_HPP diff -r ce52e6a87aed -r e15204f64e5d hotspot/src/share/vm/memory/metaspaceShared.cpp --- a/hotspot/src/share/vm/memory/metaspaceShared.cpp Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/src/share/vm/memory/metaspaceShared.cpp Fri Jun 28 14:05:27 2013 +0200 @@ -826,35 +826,15 @@ bool reading() const { return true; } }; - -// Save bounds of shared spaces mapped in. -static char* _ro_base = NULL; -static char* _rw_base = NULL; -static char* _md_base = NULL; -static char* _mc_base = NULL; - // Return true if given address is in the mapped shared space. bool MetaspaceShared::is_in_shared_space(const void* p) { - if (_ro_base == NULL || _rw_base == NULL) { - return false; - } else { - return ((p >= _ro_base && p < (_ro_base + SharedReadOnlySize)) || - (p >= _rw_base && p < (_rw_base + SharedReadWriteSize))); - } + return UseSharedSpaces && FileMapInfo::current_info()->is_in_shared_space(p); } void MetaspaceShared::print_shared_spaces() { - gclog_or_tty->print_cr("Shared Spaces:"); - gclog_or_tty->print(" read-only " INTPTR_FORMAT "-" INTPTR_FORMAT, - _ro_base, _ro_base + SharedReadOnlySize); - gclog_or_tty->print(" read-write " INTPTR_FORMAT "-" INTPTR_FORMAT, - _rw_base, _rw_base + SharedReadWriteSize); - gclog_or_tty->cr(); - gclog_or_tty->print(" misc-data " INTPTR_FORMAT "-" INTPTR_FORMAT, - _md_base, _md_base + SharedMiscDataSize); - gclog_or_tty->print(" misc-code " INTPTR_FORMAT "-" INTPTR_FORMAT, - _mc_base, _mc_base + SharedMiscCodeSize); - gclog_or_tty->cr(); + if (UseSharedSpaces) { + FileMapInfo::current_info()->print_shared_spaces(); + } } @@ -874,6 +854,11 @@ assert(!DumpSharedSpaces, "Should not be called with DumpSharedSpaces"); + char* _ro_base = NULL; + char* _rw_base = NULL; + char* _md_base = NULL; + char* _mc_base = NULL; + // Map each shared region if ((_ro_base = mapinfo->map_region(ro)) != NULL && (_rw_base = mapinfo->map_region(rw)) != NULL && diff -r ce52e6a87aed -r e15204f64e5d hotspot/src/share/vm/services/memReporter.cpp --- a/hotspot/src/share/vm/services/memReporter.cpp Thu Jun 27 11:12:19 2013 -0700 +++ b/hotspot/src/share/vm/services/memReporter.cpp Fri Jun 28 14:05:27 2013 +0200 @@ -188,8 +188,8 @@ (MallocCallsitePointer*)prev_malloc_itr.current(); while (cur_malloc_callsite != NULL || prev_malloc_callsite != NULL) { - if (prev_malloc_callsite == NULL || - cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) { + if (prev_malloc_callsite == NULL) { + assert(cur_malloc_callsite != NULL, "sanity check"); // this is a new callsite _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), amount_in_current_scale(cur_malloc_callsite->amount()), @@ -197,22 +197,42 @@ diff_in_current_scale(cur_malloc_callsite->amount(), 0), diff(cur_malloc_callsite->count(), 0)); cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); - } else if (cur_malloc_callsite == NULL || - cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) { + } else if (cur_malloc_callsite == NULL) { + assert(prev_malloc_callsite != NULL, "Sanity check"); // this callsite is already gone _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), - amount_in_current_scale(0), 0, + 0, 0, diff_in_current_scale(0, prev_malloc_callsite->amount()), diff(0, prev_malloc_callsite->count())); prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); - } else { // the same callsite - _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), - amount_in_current_scale(cur_malloc_callsite->amount()), - cur_malloc_callsite->count(), - diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()), - diff(cur_malloc_callsite->count(), prev_malloc_callsite->count())); - cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); - prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); + } else { + assert(cur_malloc_callsite != NULL, "Sanity check"); + assert(prev_malloc_callsite != NULL, "Sanity check"); + if (cur_malloc_callsite->addr() < prev_malloc_callsite->addr()) { + // this is a new callsite + _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), + amount_in_current_scale(cur_malloc_callsite->amount()), + cur_malloc_callsite->count(), + diff_in_current_scale(cur_malloc_callsite->amount(), 0), + diff(cur_malloc_callsite->count(), 0)); + cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); + } else if (cur_malloc_callsite->addr() > prev_malloc_callsite->addr()) { + // this callsite is already gone + _outputer.diff_malloc_callsite(prev_malloc_callsite->addr(), + 0, 0, + diff_in_current_scale(0, prev_malloc_callsite->amount()), + diff(0, prev_malloc_callsite->count())); + prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); + } else { + // the same callsite + _outputer.diff_malloc_callsite(cur_malloc_callsite->addr(), + amount_in_current_scale(cur_malloc_callsite->amount()), + cur_malloc_callsite->count(), + diff_in_current_scale(cur_malloc_callsite->amount(), prev_malloc_callsite->amount()), + diff(cur_malloc_callsite->count(), prev_malloc_callsite->count())); + cur_malloc_callsite = (MallocCallsitePointer*)cur_malloc_itr.next(); + prev_malloc_callsite = (MallocCallsitePointer*)prev_malloc_itr.next(); + } } }