# HG changeset patch # User sla # Date 1361523782 -3600 # Node ID 5ed317b25e2391438a405ae855c17dc6c7f84084 # Parent fc64254f55794b34116b92fb8b716e4354ea1c6f 7165259: Remove BugSpot Reviewed-by: coleenp, mgronlun diff -r fc64254f5579 -r 5ed317b25e23 agent/make/Makefile --- a/agent/make/Makefile Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/make/Makefile Fri Feb 22 10:03:02 2013 +0100 @@ -19,7 +19,7 @@ # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. -# +# # # This guards against adding broken .java files to the directory @@ -42,8 +42,6 @@ sun.jvm.hotspot \ sun.jvm.hotspot.asm \ sun.jvm.hotspot.asm.sparc \ -sun.jvm.hotspot.bugspot \ -sun.jvm.hotspot.bugspot.tree \ sun.jvm.hotspot.c1 \ sun.jvm.hotspot.ci \ sun.jvm.hotspot.code \ @@ -84,7 +82,6 @@ sun.jvm.hotspot.gc_interface \ sun.jvm.hotspot.interpreter \ sun.jvm.hotspot.jdi \ -sun.jvm.hotspot.livejvm \ sun.jvm.hotspot.memory \ sun.jvm.hotspot.opto \ sun.jvm.hotspot.oops \ @@ -130,8 +127,6 @@ sun/jvm/hotspot/*.java \ sun/jvm/hotspot/asm/*.java \ sun/jvm/hotspot/asm/sparc/*.java \ -sun/jvm/hotspot/bugspot/*.java \ -sun/jvm/hotspot/bugspot/tree/*.java \ sun/jvm/hotspot/c1/*.java \ sun/jvm/hotspot/ci/*.java \ sun/jvm/hotspot/code/*.java \ @@ -168,7 +163,6 @@ sun/jvm/hotspot/gc_implementation/shared/*.java \ sun/jvm/hotspot/interpreter/*.java \ sun/jvm/hotspot/jdi/*.java \ -sun/jvm/hotspot/livejvm/*.java \ sun/jvm/hotspot/memory/*.java \ sun/jvm/hotspot/oops/*.java \ sun/jvm/hotspot/opto/*.java \ @@ -205,7 +199,7 @@ sun/jvm/hotspot/utilities/memo/*.java \ sun/jvm/hotspot/utilities/soql/*.java \ com/sun/java/swing/action/*.java \ -com/sun/java/swing/ui/*.java +com/sun/java/swing/ui/*.java #END FILELIST ifneq "x$(ALT_BOOTDIR)" "x" @@ -231,7 +225,7 @@ OUTPUT_DIR = $(BUILD_DIR)/classes DOC_DIR = $(BUILD_DIR)/doc -# gnumake 3.78.1 does not accept the *s, +# gnumake 3.78.1 does not accept the *s, # so use the shell to expand them ALLFILES := $(patsubst %,$(SRC_DIR)/%,$(FILELIST)) ALLFILES := $(shell /bin/ls $(ALLFILES)) @@ -303,7 +297,7 @@ cscope: $(ALLFILES) rm -f java.files echo $(ALLFILES) > java.files - cscope -b -i java.files -f java.out + cscope -b -i java.files -f java.out rm -f java.files .PHONY: sa.jar diff -r fc64254f5579 -r 5ed317b25e23 agent/make/bugspot.bat --- a/agent/make/bugspot.bat Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,25 +0,0 @@ -REM -REM Copyright (c) 2002, 2008, Oracle and/or its affiliates. All rights reserved. -REM DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -REM -REM This code is free software; you can redistribute it and/or modify it -REM under the terms of the GNU General Public License version 2 only, as -REM published by the Free Software Foundation. -REM -REM This code is distributed in the hope that it will be useful, but WITHOUT -REM ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -REM FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -REM version 2 for more details (a copy is included in the LICENSE file that -REM accompanied this code). -REM -REM You should have received a copy of the GNU General Public License version -REM 2 along with this work; if not, write to the Free Software Foundation, -REM Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -REM -REM Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -REM or visit www.oracle.com if you need additional information or have any -REM questions. -REM -REM - -java -showversion -cp ..\build\classes;..\src\share\lib\js.jar;.\sa.jar;lib\js.jar sun.jvm.hotspot.bugspot.Main diff -r fc64254f5579 -r 5ed317b25e23 agent/make/marks_notes.html --- a/agent/make/marks_notes.html Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/make/marks_notes.html Fri Feb 22 10:03:02 2013 +0100 @@ -26,14 +26,12 @@

Feedback

Refactoring of package hierarchy. All user interface components should be in - the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB and - sun.jvm.hotspot.ui.bugspot.Main for BugSpot. + the ui package. Perhaps: sun.jvm.hotspot.ui.hsdb.Main for the HSDB.

The src\share\vm\agent area seems like a workspace so it should be organized like one. In particular, I'd like to suggest the following directory layout:
@@ -47,7 +45,7 @@

- Seems like there is a lot of redundant functionality. Between the HSDB and BugSpot. Perhaps + Seems like there is a lot of redundant functionality. Perhaps this can be consolidated with a javax.swing.Actions architecture.

Tasklist

@@ -55,11 +53,7 @@

Stack memory pane: It's one of the more useful JVM debugging tools in the SA. However, it - doesn't support any interaction with the text; the Memory Panel in BugSpot - was written afterward (with help from Shannon) and implements proper - selection, scrolling, and drag-and-drop, but no annotations. I'm not sure how - to integrate the annotations with the JTable that's being used for the memory - view; if you have suggestions here please let me know. + doesn't support any interaction with the text.

Integrations with the NetBeans architecture (plug in). See the Netbeans Open APIs homepage diff -r fc64254f5579 -r 5ed317b25e23 agent/src/os/win32/windbg/sawindbg.cpp --- a/agent/src/os/win32/windbg/sawindbg.cpp Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/src/os/win32/windbg/sawindbg.cpp Fri Feb 22 10:03:02 2013 +0100 @@ -372,8 +372,7 @@ We are attaching to a process in 'read-only' mode. i.e., we do not want to put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of - usage this should suffice. We are not intending to use this for full-fledged - ProcessControl implementation to be used with BugSpotAgent. + usage this should suffice. Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h. In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/asm/amd64/AMD64FloatRegister.java --- a/agent/src/share/classes/sun/jvm/hotspot/asm/amd64/AMD64FloatRegister.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2003, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.asm.amd64; - -import sun.jvm.hotspot.asm.Register; -import sun.jvm.hotspot.utilities.Assert; - -public class AMD64FloatRegister extends Register { - - public AMD64FloatRegister(int number) { - super(number); - } - - public int getNumber() { - return number; - } - - public int getNumberOfRegisters() { - return AMD64FloatRegisters.getNumRegisters(); - } - - public boolean isFloat() { - return true; - } - - public boolean isFramePointer() { - return false; - } - - public boolean isStackPointer() { - return false; - } - - public boolean isValid() { - return number >= 0 && number < AMD64FloatRegisters.getNumRegisters(); - } - - public String toString() { - return AMD64FloatRegisters.getRegisterName(number); - } - -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpot.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1536 +0,0 @@ -/* - * Copyright (c) 2001, 2012, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.awt.*; -import java.awt.event.*; -import java.io.*; -import java.net.*; -import java.util.*; -import javax.swing.*; -import javax.swing.filechooser.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.debugger.posix.*; -import sun.jvm.hotspot.debugger.windbg.*; -import sun.jvm.hotspot.livejvm.*; -import sun.jvm.hotspot.memory.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.ui.*; -import sun.jvm.hotspot.utilities.*; - -/** The BugSpot component. This is embeddable in an application by - virtue of its being a JComponent. It (currently) requires the use - of a menu bar which can be fetched via getMenuBar(). This is - intended ultimately to replace HSDB. */ - -public class BugSpot extends JPanel { - public BugSpot() { - super(); - Runtime.getRuntime().addShutdownHook(new java.lang.Thread() { - public void run() { - detachDebugger(); - } - }); - } - - /** Turn on or off MDI (Multiple Document Interface) mode. When MDI - is enabled, the BugSpot component contains a JDesktopPane and all - windows are JInternalFrames. When disabled, only the menu bar is - relevant. */ - public void setMDIMode(boolean onOrOff) { - mdiMode = onOrOff; - } - - /** Indicates whether MDI mode is enabled. */ - public boolean getMDIMode() { - return mdiMode; - } - - /** Build user interface widgets. This must be called before adding - the BugSpot component to its parent. */ - public void build() { - setLayout(new BorderLayout()); - - menuBar = new JMenuBar(); - - attachMenuItems = new java.util.ArrayList(); - detachMenuItems = new java.util.ArrayList(); - debugMenuItems = new java.util.ArrayList(); - suspendDebugMenuItems = new java.util.ArrayList(); - resumeDebugMenuItems = new java.util.ArrayList(); - - // - // File menu - // - - JMenu menu = createMenu("File", 'F', 0); - JMenuItem item; - item = createMenuItem("Open source file...", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - openSourceFile(); - } - }, - KeyEvent.VK_O, InputEvent.CTRL_MASK, - 'O', 0); - menu.add(item); - detachMenuItems.add(item); - - menu.addSeparator(); - - item = createMenuItem("Attach to process...", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - showAttachDialog(); - } - }, - 'A', 0); - menu.add(item); - attachMenuItems.add(item); - - item = createMenuItem("Detach", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - detach(); - } - }, - 'D', 0); - menu.add(item); - detachMenuItems.add(item); - - // Disable detach menu items at first - setMenuItemsEnabled(detachMenuItems, false); - - menu.addSeparator(); - - menu.add(createMenuItem("Exit", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - detach(); - System.exit(0); - } - }, - 'x', 1)); - - menuBar.add(menu); - - // - // Debug menu - // - - debugMenu = createMenu("Debug", 'D', 0); - item = createMenuItem("Go", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (!attached) return; - if (!isSuspended()) return; - resume(); - } - }, - KeyEvent.VK_F5, 0, - 'G', 0); - debugMenu.add(item); - resumeDebugMenuItems.add(item); - - item = createMenuItem("Break", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - if (!attached) { - System.err.println("Not attached"); - return; - } - if (isSuspended()) { - System.err.println("Already suspended"); - return; - } - suspend(); - } - }, - 'B', 0); - debugMenu.add(item); - suspendDebugMenuItems.add(item); - - debugMenu.addSeparator(); - - item = createMenuItem("Threads...", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - showThreadsDialog(); - } - }, - 'T', 0); - debugMenu.add(item); - debugMenuItems.add(item); - // FIXME: belongs under "View -> Debug Windows" - item = createMenuItem("Memory", - new ActionListener() { - public void actionPerformed(ActionEvent e) { - showMemoryDialog(); - } - }, - 'M', 0); - debugMenu.add(item); - debugMenuItems.add(item); - - debugMenu.setEnabled(false); - menuBar.add(debugMenu); - - if (mdiMode) { - desktop = new JDesktopPane(); - add(desktop, BorderLayout.CENTER); - } - - fixedWidthFont = GraphicsUtilities.lookupFont("Courier"); - - debugEventTimer = new javax.swing.Timer(100, new ActionListener() { - public void actionPerformed(ActionEvent e) { - pollForDebugEvent(); - } - }); - } - - public JMenuBar getMenuBar() { - return menuBar; - } - - public void showAttachDialog() { - setMenuItemsEnabled(attachMenuItems, false); - final FrameWrapper attachDialog = newFrame("Attach to process"); - attachDialog.getContentPane().setLayout(new BorderLayout()); - attachDialog.setClosable(true); - attachDialog.setResizable(true); - - JPanel panel = new JPanel(); - panel.setLayout(new BorderLayout()); - panel.setBorder(GraphicsUtilities.newBorder(5)); - attachDialog.setBackground(panel.getBackground()); - - JPanel listPanel = new JPanel(); - listPanel.setLayout(new BorderLayout()); - final ProcessListPanel plist = new ProcessListPanel(getLocalDebugger()); - panel.add(plist, BorderLayout.CENTER); - JCheckBox check = new JCheckBox("Update list continuously"); - check.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - plist.start(); - } else { - plist.stop(); - } - } - }); - listPanel.add(plist, BorderLayout.CENTER); - listPanel.add(check, BorderLayout.SOUTH); - panel.add(listPanel, BorderLayout.CENTER); - attachDialog.getContentPane().add(panel, BorderLayout.CENTER); - attachDialog.setClosingActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plist.stop(); - setMenuItemsEnabled(attachMenuItems, true); - } - }); - - ActionListener attacher = new ActionListener() { - public void actionPerformed(ActionEvent e) { - plist.stop(); - attachDialog.setVisible(false); - removeFrame(attachDialog); - ProcessInfo info = plist.getSelectedProcess(); - if (info != null) { - attach(info.getPid()); - } - } - }; - - Box hbox = Box.createHorizontalBox(); - hbox.add(Box.createGlue()); - JButton button = new JButton("OK"); - button.addActionListener(attacher); - hbox.add(button); - hbox.add(Box.createHorizontalStrut(20)); - button = new JButton("Cancel"); - button.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - plist.stop(); - attachDialog.setVisible(false); - removeFrame(attachDialog); - setMenuItemsEnabled(attachMenuItems, true); - } - }); - hbox.add(button); - hbox.add(Box.createGlue()); - panel = new JPanel(); - panel.setBorder(GraphicsUtilities.newBorder(5)); - panel.add(hbox); - - attachDialog.getContentPane().add(panel, BorderLayout.SOUTH); - - addFrame(attachDialog); - attachDialog.pack(); - attachDialog.setSize(400, 300); - GraphicsUtilities.centerInContainer(attachDialog.getComponent(), - getParentDimension(attachDialog.getComponent())); - attachDialog.setVisible(true); - } - - public void showThreadsDialog() { - final FrameWrapper threadsDialog = newFrame("Threads"); - threadsDialog.getContentPane().setLayout(new BorderLayout()); - threadsDialog.setClosable(true); - threadsDialog.setResizable(true); - - ThreadListPanel threads = new ThreadListPanel(getCDebugger(), getAgent().isJavaMode()); - threads.addListener(new ThreadListPanel.Listener() { - public void setFocus(ThreadProxy thread, JavaThread jthread) { - setCurrentThread(thread); - // FIXME: print this to GUI, bring some windows to foreground - System.err.println("Focus changed to thread " + thread); - } - }); - threads.setBorder(GraphicsUtilities.newBorder(5)); - threadsDialog.getContentPane().add(threads); - addFrame(threadsDialog); - threadsDialog.pack(); - GraphicsUtilities.reshapeToAspectRatio(threadsDialog.getComponent(), - 3.0f, - 0.9f, - getParentDimension(threadsDialog.getComponent())); - GraphicsUtilities.centerInContainer(threadsDialog.getComponent(), - getParentDimension(threadsDialog.getComponent())); - threadsDialog.setVisible(true); - } - - public void showMemoryDialog() { - final FrameWrapper memoryDialog = newFrame("Memory"); - memoryDialog.getContentPane().setLayout(new BorderLayout()); - memoryDialog.setClosable(true); - memoryDialog.setResizable(true); - - memoryDialog.getContentPane().add(new MemoryViewer(getDebugger(), - (getDebugger().getMachineDescription().getAddressSize() == 8)), - BorderLayout.CENTER); - addFrame(memoryDialog); - memoryDialog.pack(); - GraphicsUtilities.reshapeToAspectRatio(memoryDialog.getComponent(), - 1.0f, - 0.7f, - getParentDimension(memoryDialog.getComponent())); - GraphicsUtilities.centerInContainer(memoryDialog.getComponent(), - getParentDimension(memoryDialog.getComponent())); - memoryDialog.setVisible(true); - } - - /** Changes the editor factory this debugger uses to display source - code. Specified factory may be null, in which case the default - factory is used. */ - public void setEditorFactory(EditorFactory fact) { - if (fact != null) { - editorFact = fact; - } else { - editorFact = new DefaultEditorFactory(); - } - } - - //---------------------------------------------------------------------- - // Internals only below this point - // - - private WorkerThread workerThread; - private boolean mdiMode; - private JVMDebugger localDebugger; - private BugSpotAgent agent = new BugSpotAgent(); - private JMenuBar menuBar; - /** List */ - private java.util.List attachMenuItems; - private java.util.List detachMenuItems; - private java.util.List debugMenuItems; - private java.util.List suspendDebugMenuItems; - private java.util.List resumeDebugMenuItems; - private FrameWrapper stackFrame; - private VariablePanel localsPanel; - private StackTracePanel stackTracePanel; - private FrameWrapper registerFrame; - private RegisterPanel registerPanel; - // Used for mixed-language stack traces - private Map threadToJavaThreadMap; - - private JMenu debugMenu; - - // MDI mode only: desktop pane - private JDesktopPane desktop; - - // Attach/detach state - private boolean attached; - - // Suspension (combined Java/C++) state - private boolean suspended; - - // Fixed-width font - private Font fixedWidthFont; - - // Breakpoint setting - // Maps Strings to List/**/ - private Map sourceFileToLineNumberInfoMap; - // Maps Strings (file names) to Sets of Integers (line numbers) - private Map fileToBreakpointMap; - - // Debug events - private javax.swing.Timer debugEventTimer; - - // Java debug events - private boolean javaEventPending; - - static class BreakpointResult { - private boolean success; - private boolean set; - private int lineNo; - private String why; - - /** For positive results */ - BreakpointResult(boolean success, boolean set, int lineNo) { - this(success, set, lineNo, null); - } - - /** For negative results */ - BreakpointResult(boolean success, boolean set, int lineNo, String why) { - this.success = success; - this.set = set; - this.lineNo = lineNo; - this.why = why; - } - - public boolean succeeded() { - return success; - } - - public boolean set() { - return set; - } - - /** Line at which the breakpoint was actually set; only valid if - succeeded() returns true */ - public int getLine() { - return lineNo; - } - - public String getWhy() { - return why; - } - } - - - // Editors for source code. File name-to-Editor mapping. - private Map editors; - private EditorFactory editorFact = new DefaultEditorFactory(); - private EditorCommands editorComm = new EditorCommands() { - public void windowClosed(Editor editor) { - editors.remove(editor.getSourceFileName()); - } - - public void toggleBreakpointAtLine(Editor editor, int lineNumber) { - // FIXME: handle "lazy" breakpoints where the source file has - // been opened with some other mechanism (File -> Open) and we - // don't have debug information pointing to that file yet - // FIXME: NOT FINISHED - - BreakpointResult res = - handleBreakpointToggle(editor, lineNumber); - if (res.succeeded()) { - if (res.set()) { - editor.showBreakpointAtLine(res.getLine()); - } else { - editor.clearBreakpointAtLine(res.getLine()); - } - } else { - String why = res.getWhy(); - if (why == null) { - why = ""; - } else { - why = ": " + why; - } - showMessageDialog("Unable to toggle breakpoint" + why, - "Unable to toggle breakpoint", - JOptionPane.WARNING_MESSAGE); - } - } - }; - - private void attach(final int pid) { - try { - getAgent().attach(pid); - setMenuItemsEnabled(detachMenuItems, true); - setMenuItemsEnabled(suspendDebugMenuItems, false); - setMenuItemsEnabled(resumeDebugMenuItems, true); - debugMenu.setEnabled(true); - attached = true; - suspended = true; - - if (getAgent().isJavaMode()) { - System.err.println("Java HotSpot(TM) virtual machine detected."); - } else { - System.err.println("(No Java(TM) virtual machine detected)"); - } - - // Set up editor map - editors = new HashMap(); - - // Initialize breakpoints - fileToBreakpointMap = new HashMap(); - - // Create combined stack trace and local variable panel - JPanel framePanel = new JPanel(); - framePanel.setLayout(new BorderLayout()); - framePanel.setBorder(GraphicsUtilities.newBorder(5)); - localsPanel = new VariablePanel(); - JTabbedPane tab = new JTabbedPane(); - tab.addTab("Locals", localsPanel); - tab.setTabPlacement(JTabbedPane.BOTTOM); - framePanel.add(tab, BorderLayout.CENTER); - JPanel stackPanel = new JPanel(); - stackPanel.setLayout(new BoxLayout(stackPanel, BoxLayout.X_AXIS)); - stackPanel.add(new JLabel("Context:")); - stackPanel.add(Box.createHorizontalStrut(5)); - stackTracePanel = new StackTracePanel(); - stackTracePanel.addListener(new StackTracePanel.Listener() { - public void frameChanged(CFrame fr, JavaVFrame jfr) { - setCurrentFrame(fr, jfr); - } - }); - stackPanel.add(stackTracePanel); - framePanel.add(stackPanel, BorderLayout.NORTH); - stackFrame = newFrame("Stack"); - stackFrame.getContentPane().setLayout(new BorderLayout()); - stackFrame.getContentPane().add(framePanel, BorderLayout.CENTER); - stackFrame.setResizable(true); - stackFrame.setClosable(false); - addFrame(stackFrame); - stackFrame.setSize(400, 200); - GraphicsUtilities.moveToInContainer(stackFrame.getComponent(), 0.0f, 1.0f, 0, 20); - stackFrame.setVisible(true); - - // Create register panel - registerPanel = new RegisterPanel(); - registerPanel.setFont(fixedWidthFont); - registerFrame = newFrame("Registers"); - registerFrame.getContentPane().setLayout(new BorderLayout()); - registerFrame.getContentPane().add(registerPanel, BorderLayout.CENTER); - addFrame(registerFrame); - registerFrame.setResizable(true); - registerFrame.setClosable(false); - registerFrame.setSize(225, 200); - GraphicsUtilities.moveToInContainer(registerFrame.getComponent(), - 1.0f, 0.0f, 0, 0); - registerFrame.setVisible(true); - - resetCurrentThread(); - } catch (DebuggerException e) { - final String errMsg = formatMessage(e.getMessage(), 80); - setMenuItemsEnabled(attachMenuItems, true); - showMessageDialog("Unable to connect to process ID " + pid + ":\n\n" + errMsg, - "Unable to Connect", - JOptionPane.WARNING_MESSAGE); - getAgent().detach(); - } - } - - private synchronized void detachDebugger() { - if (!attached) { - return; - } - if (isSuspended()) { - resume(); // Necessary for JVMDI resumption - } - getAgent().detach(); - // FIXME: clear out breakpoints (both Java and C/C++) from target - // process - sourceFileToLineNumberInfoMap = null; - fileToBreakpointMap = null; - threadToJavaThreadMap = null; - editors = null; - attached = false; - } - - private synchronized void detach() { - detachDebugger(); - setMenuItemsEnabled(attachMenuItems, true); - setMenuItemsEnabled(detachMenuItems, false); - debugMenu.setEnabled(false); - if (mdiMode) { - // FIXME: is this sufficient, or will I have to do anything else - // to the components to kill them off? What about WorkerThreads? - desktop.removeAll(); - desktop.invalidate(); - desktop.validate(); - desktop.repaint(); - } - // FIXME: keep track of all windows and close them even in non-MDI - // mode - debugEventTimer.stop(); - } - - // Returns a Debugger for processes on the local machine. This is - // only used to fetch the process list. - private Debugger getLocalDebugger() { - if (localDebugger == null) { - String os = PlatformInfo.getOS(); - String cpu = PlatformInfo.getCPU(); - - if (os.equals("win32")) { - if (!cpu.equals("x86")) { - throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Windows"); - } - - localDebugger = new WindbgDebuggerLocal(new MachineDescriptionIntelX86(), true); - } else if (os.equals("linux")) { - if (!cpu.equals("x86")) { - throw new DebuggerException("Unsupported CPU \"" + cpu + "\" for Linux"); - } - - // FIXME: figure out how to specify path to debugger module - throw new RuntimeException("FIXME: figure out how to specify path to debugger module"); - // localDebugger = new PosixDebuggerLocal(new MachineDescriptionIntelX86(), true); - } else { - // FIXME: port to Solaris - throw new DebuggerException("Unsupported OS \"" + os + "\""); - } - - // FIXME: we require that the primitive type sizes be configured - // in order to use basic functionality in class Address such as - // the fetching of floating-point values. There are a lot of - // assumptions in the current code that Java floats and doubles - // are of equivalent size to C values. The configurability of the - // primitive type sizes hasn't seemed necessary and in this kind - // of debugging scenario (namely, debugging arbitrary C++ - // processes) it appears difficult to support that kind of - // flexibility. - localDebugger.configureJavaPrimitiveTypeSizes(1, 1, 2, 8, 4, 4, 8, 2); - } - - return localDebugger; - } - - private BugSpotAgent getAgent() { - return agent; - } - - private Debugger getDebugger() { - return getAgent().getDebugger(); - } - - private CDebugger getCDebugger() { - return getAgent().getCDebugger(); - } - - private void resetCurrentThread() { - setCurrentThread((ThreadProxy) getCDebugger().getThreadList().get(0)); - } - - private void setCurrentThread(ThreadProxy t) { - // Create stack trace - // FIXME: add ability to intermix C/Java frames - java.util.List trace = new ArrayList(); - CFrame fr = getCDebugger().topFrameForThread(t); - while (fr != null) { - trace.add(new StackTraceEntry(fr, getCDebugger())); - try { - fr = fr.sender(t); - } catch (AddressException e) { - e.printStackTrace(); - showMessageDialog("Error while walking stack; stack trace will be truncated\n(see console for details)", - "Error walking stack", - JOptionPane.WARNING_MESSAGE); - fr = null; - } - } - JavaThread jthread = javaThreadForProxy(t); - if (jthread != null) { - // Java mode, and we have a Java thread. - // Find all Java frames on the stack. We currently do this in a - // manner which involves minimal interaction between the Java - // and C/C++ debugging systems: any C frame which has a PC in an - // unknown location (i.e., not in any DSO) is assumed to be a - // Java frame. We merge stack segments of unknown frames with - // segments of Java frames beginning with native methods. - java.util.List javaTrace = new ArrayList(); - VFrame vf = jthread.getLastJavaVFrameDbg(); - while (vf != null) { - if (vf.isJavaFrame()) { - javaTrace.add(new StackTraceEntry((JavaVFrame) vf)); - vf = vf.sender(); - } - } - // Merge stack traces - java.util.List mergedTrace = new ArrayList(); - int c = 0; - int j = 0; - while (c < trace.size()) { - StackTraceEntry entry = (StackTraceEntry) trace.get(c); - if (entry.isUnknownCFrame()) { - boolean gotJavaFrame = false; - while (j < javaTrace.size()) { - StackTraceEntry javaEntry = (StackTraceEntry) javaTrace.get(j); - JavaVFrame jvf = javaEntry.getJavaFrame(); - Method m = jvf.getMethod(); - if (!m.isNative() || !gotJavaFrame) { - gotJavaFrame = true; - mergedTrace.add(javaEntry); - ++j; - } else { - break; // Reached native method; have intervening C frames - } - } - if (gotJavaFrame) { - // Skip this sequence of unknown frames, as we've - // successfully identified it as Java frames - while (c < trace.size() && entry.isUnknownCFrame()) { - ++c; - if (c < trace.size()) { - entry = (StackTraceEntry) trace.get(c); - } - } - continue; - } - } - // If we get here, we either have an unknown frame we didn't - // know how to categorize or we have a known C frame. Add it - // to the trace. - mergedTrace.add(entry); - ++c; - } - trace = mergedTrace; - } - stackTracePanel.setTrace(trace); - - registerPanel.update(t); - } - - private void setCurrentFrame(CFrame fr, JavaVFrame jfr) { - localsPanel.clear(); - - if (fr != null) { - localsPanel.update(fr); - - // FIXME: load source file if we can find it, otherwise display disassembly - LoadObject lo = getCDebugger().loadObjectContainingPC(fr.pc()); - if (lo != null) { - CDebugInfoDataBase db = lo.getDebugInfoDataBase(); - if (db != null) { - LineNumberInfo info = db.lineNumberForPC(fr.pc()); - if (info != null) { - System.err.println("PC " + fr.pc() + ": Source file \"" + - info.getSourceFileName() + - "\", line number " + - info.getLineNumber() + - ", PC range [" + - info.getStartPC() + - ", " + - info.getEndPC() + - ")"); - // OK, here we go... - showLineNumber(null, info.getSourceFileName(), info.getLineNumber()); - } else { - System.err.println("(No line number information for PC " + fr.pc() + ")"); - // Dump line number information for database - db.iterate(new LineNumberVisitor() { - public void doLineNumber(LineNumberInfo info) { - System.err.println(" Source file \"" + - info.getSourceFileName() + - "\", line number " + - info.getLineNumber() + - ", PC range [" + - info.getStartPC() + - ", " + - info.getEndPC() + - ")"); - } - }); - } - } - } - } else { - if (Assert.ASSERTS_ENABLED) { - Assert.that(jfr != null, "Must have either C or Java frame"); - } - localsPanel.update(jfr); - // See whether we can locate source file and line number - // FIXME: infer pathmap entries from user's locating of this - // source file - // FIXME: figure out what to do for native methods. Possible to - // go to line number for the native method declaration? - Method m = jfr.getMethod(); - Symbol sfn = ((InstanceKlass) m.getMethodHolder()).getSourceFileName(); - if (sfn != null) { - int bci = jfr.getBCI(); - int lineNo = m.getLineNumberFromBCI(bci); - if (lineNo >= 0) { - // FIXME: show disassembly otherwise - showLineNumber(packageName(m.getMethodHolder().getName().asString()), - sfn.asString(), lineNo); - } - } - } - } - - private String packageName(String str) { - int idx = str.lastIndexOf('/'); - if (idx < 0) { - return ""; - } - return str.substring(0, idx).replace('/', '.'); - } - - private JavaThread javaThreadForProxy(ThreadProxy t) { - if (!getAgent().isJavaMode()) { - return null; - } - if (threadToJavaThreadMap == null) { - threadToJavaThreadMap = new HashMap(); - Threads threads = VM.getVM().getThreads(); - for (JavaThread thr = threads.first(); thr != null; thr = thr.next()) { - threadToJavaThreadMap.put(thr.getThreadProxy(), thr); - } - } - return (JavaThread) threadToJavaThreadMap.get(t); - } - - private static JMenu createMenu(String name, char mnemonic, int mnemonicPos) { - JMenu menu = new JMenu(name); - menu.setMnemonic(mnemonic); - menu.setDisplayedMnemonicIndex(mnemonicPos); - return menu; - } - - private static JMenuItem createMenuItem(String name, ActionListener l) { - JMenuItem item = new JMenuItem(name); - item.addActionListener(l); - return item; - } - - private static JMenuItem createMenuItemInternal(String name, ActionListener l, int accelerator, int modifiers) { - JMenuItem item = createMenuItem(name, l); - item.setAccelerator(KeyStroke.getKeyStroke(accelerator, modifiers)); - return item; - } - - private static JMenuItem createMenuItem(String name, ActionListener l, int accelerator) { - return createMenuItemInternal(name, l, accelerator, 0); - } - - private static JMenuItem createMenuItem(String name, ActionListener l, char mnemonic, int mnemonicPos) { - JMenuItem item = createMenuItem(name, l); - item.setMnemonic(mnemonic); - item.setDisplayedMnemonicIndex(mnemonicPos); - return item; - } - - private static JMenuItem createMenuItem(String name, - ActionListener l, - int accelerator, - int acceleratorMods, - char mnemonic, - int mnemonicPos) { - JMenuItem item = createMenuItemInternal(name, l, accelerator, acceleratorMods); - item.setMnemonic(mnemonic); - item.setDisplayedMnemonicIndex(mnemonicPos); - return item; - } - - /** Punctuates the given string with \n's where necessary to not - exceed the given number of characters per line. Strips - extraneous whitespace. */ - private static String formatMessage(String message, int charsPerLine) { - StringBuffer buf = new StringBuffer(message.length()); - StringTokenizer tokenizer = new StringTokenizer(message); - int curLineLength = 0; - while (tokenizer.hasMoreTokens()) { - String tok = tokenizer.nextToken(); - if (curLineLength + tok.length() > charsPerLine) { - buf.append('\n'); - curLineLength = 0; - } else { - if (curLineLength != 0) { - buf.append(' '); - ++curLineLength; - } - } - buf.append(tok); - curLineLength += tok.length(); - } - return buf.toString(); - } - - private void setMenuItemsEnabled(java.util.List items, boolean enabled) { - for (Iterator iter = items.iterator(); iter.hasNext(); ) { - ((JMenuItem) iter.next()).setEnabled(enabled); - } - } - - private void showMessageDialog(final String message, final String title, final int jOptionPaneKind) { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - if (mdiMode) { - JOptionPane.showInternalMessageDialog(desktop, message, title, jOptionPaneKind); - } else { - JOptionPane.showMessageDialog(null, message, title, jOptionPaneKind); - } - } - }); - } - - private FrameWrapper newFrame(String title) { - if (mdiMode) { - return new JInternalFrameWrapper(new JInternalFrame(title)); - } else { - return new JFrameWrapper(new JFrame(title)); - } - } - - private void addFrame(FrameWrapper frame) { - if (mdiMode) { - desktop.add(frame.getComponent()); - } - } - - private void removeFrame(FrameWrapper frame) { - if (mdiMode) { - desktop.remove(frame.getComponent()); - desktop.invalidate(); - desktop.validate(); - desktop.repaint(); - } - // FIXME: do something when not in MDI mode - } - - private Dimension getParentDimension(Component c) { - if (mdiMode) { - return desktop.getSize(); - } else { - return Toolkit.getDefaultToolkit().getScreenSize(); - } - } - - // Default editor implementation - class DefaultEditor implements Editor { - private DefaultEditorFactory factory; - private FrameWrapper editorFrame; - private String filename; - private SourceCodePanel code; - private boolean shown; - private Object userData; - - public DefaultEditor(DefaultEditorFactory fact, String filename, final EditorCommands comm) { - this.filename = filename; - this.factory = fact; - editorFrame = newFrame(filename); - code = new SourceCodePanel(); - // FIXME: when font changes, change font in editors as well - code.setFont(fixedWidthFont); - editorFrame.getContentPane().add(code); - editorFrame.setClosable(true); - editorFrame.setResizable(true); - editorFrame.setClosingActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - comm.windowClosed(DefaultEditor.this); - removeFrame(editorFrame); - editorFrame.dispose(); - factory.editorClosed(DefaultEditor.this); - } - }); - editorFrame.setActivatedActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - factory.makeEditorCurrent(DefaultEditor.this); - code.requestFocus(); - } - }); - code.setEditorCommands(comm, this); - } - - public boolean openFile() { return code.openFile(filename); } - public String getSourceFileName() { return filename; } - public int getCurrentLineNumber() { return code.getCurrentLineNumber(); } - public void showLineNumber(int lineNo) { - if (!shown) { - addFrame(editorFrame); - GraphicsUtilities.reshapeToAspectRatio(editorFrame.getComponent(), - 1.0f, - 0.85f, - getParentDimension(editorFrame.getComponent())); - editorFrame.setVisible(true); - shown = true; - } - code.showLineNumber(lineNo); - editorFrame.toFront(); - } - public void highlightLineNumber(int lineNo) { code.highlightLineNumber(lineNo); } - public void showBreakpointAtLine(int lineNo) { code.showBreakpointAtLine(lineNo); } - public boolean hasBreakpointAtLine(int lineNo) { return code.hasBreakpointAtLine(lineNo); } - public void clearBreakpointAtLine(int lineNo) { code.clearBreakpointAtLine(lineNo); } - public void clearBreakpoints() { code.clearBreakpoints(); } - public void setUserData(Object o) { userData = o; } - public Object getUserData() { return userData; } - public void toFront() { editorFrame.toFront(); - factory.makeEditorCurrent(this); } - } - - class DefaultEditorFactory implements EditorFactory { - private LinkedList/**/ editors = new LinkedList(); - - public Editor openFile(String filename, EditorCommands commands) { - DefaultEditor editor = new DefaultEditor(this, filename, editorComm); - if (!editor.openFile()) { - return null; - } - return editor; - } - - public Editor getCurrentEditor() { - if (editors.isEmpty()) { - return null; - } - return (Editor) editors.getFirst(); - } - - void editorClosed(Editor editor) { - editors.remove(editor); - } - - void makeEditorCurrent(Editor editor) { - editors.remove(editor); - editors.addFirst(editor); - } - } - - // Helper class for loading .java files; show only those with - // correct file name which are also in the correct package - static class JavaFileFilter extends javax.swing.filechooser.FileFilter { - private String packageName; - private String fileName; - - JavaFileFilter(String packageName, String fileName) { - this.packageName = packageName; - this.fileName = fileName; - } - - public boolean accept(File f) { - if (f.isDirectory()) { - return true; - } - // This rejects most files - if (!f.getName().equals(fileName)) { - return false; - } - // Ensure selected file is in the correct package - PackageScanner scanner = new PackageScanner(); - String pkg = scanner.scan(f); - if (!pkg.equals(packageName)) { - return false; - } - return true; - } - - public String getDescription() { return "Java source files"; } - } - - // Auxiliary information used only for Java source files - static class JavaUserData { - private String packageName; // External format - private String sourceFileName; - - /** Source file name is equivalent to that found in the .java - file; i.e., not a full path */ - JavaUserData(String packageName, String sourceFileName) { - this.packageName = packageName; - this.sourceFileName = sourceFileName; - } - - String packageName() { return packageName; } - String sourceFileName() { return sourceFileName; } - } - - // Opens a source file. This makes it available for the setting of - // lazy breakpoints. - private void openSourceFile() { - JFileChooser chooser = new JFileChooser(); - chooser.setDialogTitle("Open source code file"); - chooser.setMultiSelectionEnabled(false); - if (chooser.showOpenDialog(null) != JFileChooser.APPROVE_OPTION) { - return; - } - File chosen = chooser.getSelectedFile(); - if (chosen == null) { - return; - } - - // See whether we have a Java source file. If so, derive a package - // name for it. - String path = chosen.getPath(); - String name = null; - JavaUserData data = null; - if (path.endsWith(".java")) { - PackageScanner scanner = new PackageScanner(); - String pkg = scanner.scan(chosen); - // Now knowing both the package name and file name, we can put - // this in the editor map and use it for setting breakpoints - // later - String fileName = chosen.getName(); - name = pkg + "." + fileName; - data = new JavaUserData(pkg, fileName); - } else { - // FIXME: need pathmap mechanism - name = path; - } - Editor editor = (Editor) editors.get(name); - if (editor == null) { - editor = editorFact.openFile(path, editorComm); - if (editor == null) { - showMessageDialog("Unable to open file \"" + path + "\" -- unexpected error.", - "Unable to open file", - JOptionPane.WARNING_MESSAGE); - return; - } - editors.put(name, editor); - if (data != null) { - editor.setUserData(data); - } - } else { - editor.toFront(); - } - editor.showLineNumber(1); - // Show breakpoints as well if we have any for this file - Set set = (Set) fileToBreakpointMap.get(editor.getSourceFileName()); - if (set != null) { - for (Iterator iter = set.iterator(); iter.hasNext(); ) { - editor.showBreakpointAtLine(((Integer) iter.next()).intValue()); - } - } - } - - // Package name may be null, in which case the file is assumed to be - // a C source file. Otherwise it is assumed to be a Java source file - // and certain filtering rules will be applied. - private void showLineNumber(String packageName, String fileName, int lineNumber) { - String name; - if (packageName == null) { - name = fileName; - } else { - name = packageName + "." + fileName; - } - Editor editor = (Editor) editors.get(name); - if (editor == null) { - // See whether file exists - File file = new File(fileName); - String realFileName = fileName; - if (!file.exists()) { - // User must specify path to file - JFileChooser chooser = new JFileChooser(); - chooser.setDialogTitle("Please locate " + fileName); - chooser.setMultiSelectionEnabled(false); - if (packageName != null) { - chooser.setFileFilter(new JavaFileFilter(packageName, fileName)); - } - int res = chooser.showOpenDialog(null); - if (res != JFileChooser.APPROVE_OPTION) { - // FIXME: show disassembly instead - return; - } - // FIXME: would like to infer more from the selection; i.e., - // a pathmap leading up to this file - File chosen = chooser.getSelectedFile(); - if (chosen == null) { - return; - } - realFileName = chosen.getPath(); - } - // Now instruct editor factory to open file - editor = editorFact.openFile(realFileName, editorComm); - if (editor == null) { - showMessageDialog("Unable to open file \"" + realFileName + "\" -- unexpected error.", - "Unable to open file", - JOptionPane.WARNING_MESSAGE); - return; - } - // Got an editor; put it in map - editors.put(name, editor); - // If Java source file, add additional information for later - if (packageName != null) { - editor.setUserData(new JavaUserData(packageName, fileName)); - } - } - // Got editor; show line - editor.showLineNumber(lineNumber); - editor.highlightLineNumber(lineNumber); - // Show breakpoints as well if we have any for this file - Set set = (Set) fileToBreakpointMap.get(editor.getSourceFileName()); - if (set != null) { - for (Iterator iter = set.iterator(); iter.hasNext(); ) { - editor.showBreakpointAtLine(((Integer) iter.next()).intValue()); - } - } - } - - // - // Suspend/resume - // - - private boolean isSuspended() { - return suspended; - } - - private synchronized void suspend() { - setMenuItemsEnabled(resumeDebugMenuItems, true); - setMenuItemsEnabled(suspendDebugMenuItems, false); - BugSpotAgent agent = getAgent(); - if (agent.canInteractWithJava() && !agent.isJavaSuspended()) { - agent.suspendJava(); - } - agent.suspend(); - // FIXME: call VM.getVM().fireVMSuspended() - resetCurrentThread(); - debugEventTimer.stop(); - suspended = true; - } - - private synchronized void resume() { - // Note: we don't wipe out the cached state like the - // sourceFileToLineNumberInfoMap since it is too expensive to - // recompute. Instead we recompute it if any DLLs are loaded or - // unloaded. - threadToJavaThreadMap = null; - setMenuItemsEnabled(resumeDebugMenuItems, false); - setMenuItemsEnabled(suspendDebugMenuItems, true); - registerPanel.clear(); - // FIXME: call VM.getVM().fireVMResumed() - BugSpotAgent agent = getAgent(); - agent.resume(); - if (agent.canInteractWithJava()) { - if (agent.isJavaSuspended()) { - agent.resumeJava(); - } - if (javaEventPending) { - javaEventPending = false; - // Clear it out before resuming polling for events - agent.javaEventContinue(); - } - } - agent.enableJavaInteraction(); - suspended = false; - debugEventTimer.start(); - } - - // - // Breakpoints - // - - private synchronized BreakpointResult handleBreakpointToggle(Editor editor, int lineNumber) { - // Currently we only use user data in editors to indicate Java - // source files. If this changes then this code will need to - // change. - JavaUserData data = (JavaUserData) editor.getUserData(); - String filename = editor.getSourceFileName(); - if (data == null) { - // C/C++ code - // FIXME: as noted above in EditorCommands.toggleBreakpointAtLine, - // this needs more work to handle "lazy" breakpoints in files - // which we don't know about in the debug information yet - CDebugger dbg = getCDebugger(); - ProcessControl prctl = dbg.getProcessControl(); - if (prctl == null) { - return new BreakpointResult(false, false, 0, "Process control not enabled"); - } - boolean mustSuspendAndResume = (!prctl.isSuspended()); - try { - if (mustSuspendAndResume) { - prctl.suspend(); - } - // Search debug info for all DSOs - LineNumberInfo info = getLineNumberInfo(filename, lineNumber); - if (info != null) { - Set bpset = (Set) fileToBreakpointMap.get(filename); - if (bpset == null) { - bpset = new HashSet(); - fileToBreakpointMap.put(filename, bpset); - } - Integer key = new Integer(info.getLineNumber()); - if (bpset.contains(key)) { - // Clear breakpoint at this line's PC - prctl.clearBreakpoint(info.getStartPC()); - bpset.remove(key); - return new BreakpointResult(true, false, info.getLineNumber()); - } else { - // Set breakpoint at this line's PC - System.err.println("Setting breakpoint at PC " + info.getStartPC()); - prctl.setBreakpoint(info.getStartPC()); - bpset.add(key); - return new BreakpointResult(true, true, info.getLineNumber()); - } - } else { - return new BreakpointResult(false, false, 0, "No debug information for this source file and line"); - } - } finally { - if (mustSuspendAndResume) { - prctl.resume(); - } - } - } else { - BugSpotAgent agent = getAgent(); - if (!agent.canInteractWithJava()) { - String why; - if (agent.isJavaInteractionDisabled()) { - why = "Can not toggle Java breakpoints while stopped because\nof C/C++ debug events (breakpoints, single-stepping)"; - } else { - why = "Could not talk to SA's JVMDI module to enable Java\nprogramming language breakpoints (run with -Xdebug -Xrunsa)"; - } - return new BreakpointResult(false, false, 0, why); - } - Set bpset = (Set) fileToBreakpointMap.get(filename); - if (bpset == null) { - bpset = new HashSet(); - fileToBreakpointMap.put(filename, bpset); - } - boolean mustResumeAndSuspend = isSuspended(); - try { - if (mustResumeAndSuspend) { - agent.resume(); - } - ServiceabilityAgentJVMDIModule.BreakpointToggleResult res = - getAgent().toggleJavaBreakpoint(data.sourceFileName(), - data.packageName(), - lineNumber); - if (res.getSuccess()) { - Integer key = new Integer(res.getLineNumber()); - boolean addRemRes = false; - if (res.getWasSet()) { - addRemRes = bpset.add(key); - System.err.println("Setting breakpoint at " + res.getMethodName() + res.getMethodSignature() + - ", bci " + res.getBCI() + ", line " + res.getLineNumber()); - } else { - addRemRes = bpset.remove(key); - System.err.println("Clearing breakpoint at " + res.getMethodName() + res.getMethodSignature() + - ", bci " + res.getBCI() + ", line " + res.getLineNumber()); - } - if (Assert.ASSERTS_ENABLED) { - Assert.that(addRemRes, "Inconsistent Java breakpoint state with respect to target process"); - } - return new BreakpointResult(true, res.getWasSet(), res.getLineNumber()); - } else { - return new BreakpointResult(false, false, 0, res.getErrMsg()); - } - } finally { - if (mustResumeAndSuspend) { - agent.suspend(); - resetCurrentThread(); - } - } - } - } - - // Must call only when suspended - private LineNumberInfo getLineNumberInfo(String filename, int lineNumber) { - Map map = getSourceFileToLineNumberInfoMap(); - java.util.List infos = (java.util.List) map.get(filename); - if (infos == null) { - return null; - } - // Binary search for line number - return searchLineNumbers(infos, lineNumber, 0, infos.size()); - } - - // Must call only when suspended - private Map getSourceFileToLineNumberInfoMap() { - if (sourceFileToLineNumberInfoMap == null) { - // Build from debug info - java.util.List loadObjects = getCDebugger().getLoadObjectList(); - final Map map = new HashMap(); - for (Iterator iter = loadObjects.iterator(); iter.hasNext(); ) { - LoadObject lo = (LoadObject) iter.next(); - CDebugInfoDataBase db = lo.getDebugInfoDataBase(); - if (db != null) { - db.iterate(new LineNumberVisitor() { - public void doLineNumber(LineNumberInfo info) { - String name = info.getSourceFileName(); - if (name != null) { - java.util.List val = (java.util.List) map.get(name); - if (val == null) { - val = new ArrayList(); - map.put(name, val); - } - val.add(info); - } - } - }); - } - } - // Sort all lists - for (Iterator iter = map.values().iterator(); iter.hasNext(); ) { - java.util.List list = (java.util.List) iter.next(); - Collections.sort(list, new Comparator() { - public int compare(Object o1, Object o2) { - LineNumberInfo l1 = (LineNumberInfo) o1; - LineNumberInfo l2 = (LineNumberInfo) o2; - int n1 = l1.getLineNumber(); - int n2 = l2.getLineNumber(); - if (n1 < n2) return -1; - if (n1 == n2) return 0; - return 1; - } - }); - } - sourceFileToLineNumberInfoMap = map; - } - return sourceFileToLineNumberInfoMap; - } - - private LineNumberInfo searchLineNumbers(java.util.List infoList, int lineNo, int lowIdx, int highIdx) { - if (highIdx < lowIdx) return null; - if (lowIdx == highIdx) { - // Base case: see whether start PC is less than or equal to addr - if (checkLineNumber(infoList, lineNo, lowIdx)) { - return (LineNumberInfo) infoList.get(lowIdx); - } else { - return null; - } - } else if (lowIdx == highIdx - 1) { - if (checkLineNumber(infoList, lineNo, lowIdx)) { - return (LineNumberInfo) infoList.get(lowIdx); - } else if (checkLineNumber(infoList, lineNo, highIdx)) { - return (LineNumberInfo) infoList.get(highIdx); - } else { - return null; - } - } - int midIdx = (lowIdx + highIdx) >> 1; - LineNumberInfo info = (LineNumberInfo) infoList.get(midIdx); - if (lineNo < info.getLineNumber()) { - // Always move search down - return searchLineNumbers(infoList, lineNo, lowIdx, midIdx); - } else if (lineNo == info.getLineNumber()) { - return info; - } else { - // Move search up - return searchLineNumbers(infoList, lineNo, midIdx, highIdx); - } - } - - private boolean checkLineNumber(java.util.List infoList, int lineNo, int idx) { - LineNumberInfo info = (LineNumberInfo) infoList.get(idx); - return (info.getLineNumber() >= lineNo); - } - - // - // Debug events - // - - private synchronized void pollForDebugEvent() { - ProcessControl prctl = getCDebugger().getProcessControl(); - if (prctl == null) { - return; - } - DebugEvent ev = prctl.debugEventPoll(); - if (ev != null) { - DebugEvent.Type t = ev.getType(); - if (t == DebugEvent.Type.LOADOBJECT_LOAD || - t == DebugEvent.Type.LOADOBJECT_UNLOAD) { - // Conservatively clear cached debug info state - sourceFileToLineNumberInfoMap = null; - // FIXME: would be very useful to have "stop on load/unload" - // events - // FIXME: must do work at these events to implement lazy - // breakpoints - prctl.debugEventContinue(); - } else if (t == DebugEvent.Type.BREAKPOINT) { - // Note: Visual C++ only notifies on breakpoints it doesn't - // know about - - // FIXME: put back test - // if (!prctl.isBreakpointSet(ev.getPC())) { - showMessageDialog("Breakpoint reached at PC " + ev.getPC(), - "Breakpoint reached", - JOptionPane.INFORMATION_MESSAGE); - // } - agent.disableJavaInteraction(); - suspend(); - prctl.debugEventContinue(); - } else if (t == DebugEvent.Type.SINGLE_STEP) { - agent.disableJavaInteraction(); - suspend(); - prctl.debugEventContinue(); - } else if (t == DebugEvent.Type.ACCESS_VIOLATION) { - showMessageDialog("Access violation attempting to " + - (ev.getWasWrite() ? "write" : "read") + - " address " + ev.getAddress() + - " at PC " + ev.getPC(), - "Access Violation", - JOptionPane.WARNING_MESSAGE); - agent.disableJavaInteraction(); - suspend(); - prctl.debugEventContinue(); - } else { - String info = "Unknown debug event encountered"; - if (ev.getUnknownEventDetail() != null) { - info = info + ": " + ev.getUnknownEventDetail(); - } - showMessageDialog(info, "Unknown debug event", JOptionPane.INFORMATION_MESSAGE); - suspend(); - prctl.debugEventContinue(); - } - return; - } - - // No C++ debug event; poll for Java debug event - if (getAgent().canInteractWithJava()) { - if (!javaEventPending) { - if (getAgent().javaEventPending()) { - suspend(); - // This does a lot of work and we want to have the page - // cache available to us as it runs - sun.jvm.hotspot.livejvm.Event jev = getAgent().javaEventPoll(); - if (jev != null) { - javaEventPending = true; - if (jev.getType() == sun.jvm.hotspot.livejvm.Event.Type.BREAKPOINT) { - BreakpointEvent bpev = (BreakpointEvent) jev; - showMessageDialog("Breakpoint reached in method\n" + - bpev.methodID().method().externalNameAndSignature() + - ",\nbci " + bpev.location(), - "Breakpoint reached", - JOptionPane.INFORMATION_MESSAGE); - } else if (jev.getType() == sun.jvm.hotspot.livejvm.Event.Type.EXCEPTION) { - ExceptionEvent exev = (ExceptionEvent) jev; - showMessageDialog(exev.exception().getKlass().getName().asString() + - "\nthrown in method\n" + - exev.methodID().method().externalNameAndSignature() + - "\nat BCI " + exev.location(), - "Exception thrown", - JOptionPane.INFORMATION_MESSAGE); - } else { - Assert.that(false, "Should not reach here"); - } - } - } - } - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/BugSpotAgent.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,799 +0,0 @@ -/* - * Copyright (c) 2002, 2012, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.io.PrintStream; -import java.net.*; -import java.rmi.*; -import sun.jvm.hotspot.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.bsd.*; -import sun.jvm.hotspot.debugger.proc.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.debugger.windbg.*; -import sun.jvm.hotspot.debugger.linux.*; -import sun.jvm.hotspot.debugger.sparc.*; -import sun.jvm.hotspot.debugger.remote.*; -import sun.jvm.hotspot.livejvm.*; -import sun.jvm.hotspot.memory.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.types.*; -import sun.jvm.hotspot.utilities.*; - -/**

This class wraps the basic functionality for connecting to the - * target process or debug server. It makes it simple to start up the - * debugging system.

- * - *

This agent (as compared to the HotSpotAgent) can connect to - * and interact with arbitrary processes. If the target process - * happens to be a HotSpot JVM, the Java debugging features of the - * Serviceability Agent are enabled. Further, if the Serviceability - * Agent's JVMDI module is loaded into the target VM, interaction - * with the live Java program is possible, specifically the catching - * of exceptions and setting of breakpoints.

- * - *

The BugSpot debugger requires that the underlying Debugger - * support C/C++ debugging via the CDebugger interface.

- * - *

FIXME: especially with the addition of remote debugging, this - * has turned into a mess; needs rethinking.

*/ - -public class BugSpotAgent { - - private JVMDebugger debugger; - private MachineDescription machDesc; - private TypeDataBase db; - - private String os; - private String cpu; - private String fileSep; - - // The system can work in several ways: - // - Attaching to local process - // - Attaching to local core file - // - Connecting to remote debug server - // - Starting debug server for process - // - Starting debug server for core file - - // These are options for the "client" side of things - private static final int PROCESS_MODE = 0; - private static final int CORE_FILE_MODE = 1; - private static final int REMOTE_MODE = 2; - private int startupMode; - - // This indicates whether we are really starting a server or not - private boolean isServer; - - // All possible required information for connecting - private int pid; - private String executableName; - private String coreFileName; - private String debugServerID; - - // All needed information for server side - private String serverID; - - // Indicates whether we are attached to a HotSpot JVM or not - private boolean javaMode; - - // Indicates whether we have process control over a live HotSpot JVM - // or not; non-null if so. - private ServiceabilityAgentJVMDIModule jvmdi; - // While handling C breakpoints interactivity with the Java program - // is forbidden. Too many invariants are broken while the target is - // stopped at a C breakpoint to risk making JVMDI calls. - private boolean javaInteractionDisabled; - - private String[] jvmLibNames; - private String[] saLibNames; - - // FIXME: make these configurable, i.e., via a dotfile; also - // consider searching within the JDK from which this Java executable - // comes to find them - private static final String defaultDbxPathPrefix = "/net/jano.eng/export/disk05/hotspot/sa"; - private static final String defaultDbxSvcAgentDSOPathPrefix = "/net/jano.eng/export/disk05/hotspot/sa"; - - private static final boolean DEBUG; - static { - DEBUG = System.getProperty("sun.jvm.hotspot.bugspot.BugSpotAgent.DEBUG") - != null; - } - - static void debugPrintln(String str) { - if (DEBUG) { - System.err.println(str); - } - } - - static void showUsage() { - System.out.println(" You can also pass these -D options to java to specify where to find dbx and the \n" + - " Serviceability Agent plugin for dbx:"); - System.out.println(" -DdbxPathName=\n" + - " Default is derived from dbxPathPrefix"); - System.out.println(" or"); - System.out.println(" -DdbxPathPrefix=\n" + - " where xxx is the path name of a dir structure that contains:\n" + - " //bin/dbx\n" + - " The default is " + defaultDbxPathPrefix); - System.out.println(" and"); - System.out.println(" -DdbxSvcAgentDSOPathName=\n" + - " Default is determined from dbxSvcAgentDSOPathPrefix"); - System.out.println(" or"); - System.out.println(" -DdbxSvcAgentDSOPathPrefix=\n" + - " where xxx is the pathname of a dir structure that contains:\n" + - " //bin/lib/libsvc_agent_dbx.so\n" + - " The default is " + defaultDbxSvcAgentDSOPathPrefix); - } - - public BugSpotAgent() { - // for non-server add shutdown hook to clean-up debugger in case - // of forced exit. For remote server, shutdown hook is added by - // DebugServer. - Runtime.getRuntime().addShutdownHook(new java.lang.Thread( - new Runnable() { - public void run() { - synchronized (BugSpotAgent.this) { - if (!isServer) { - detach(); - } - } - } - })); - } - - //-------------------------------------------------------------------------------- - // Accessors (once the system is set up) - // - - public synchronized Debugger getDebugger() { - return debugger; - } - - public synchronized CDebugger getCDebugger() { - return getDebugger().getCDebugger(); - } - - public synchronized ProcessControl getProcessControl() { - return getCDebugger().getProcessControl(); - } - - public synchronized TypeDataBase getTypeDataBase() { - return db; - } - - /** Indicates whether the target process is suspended - completely. Equivalent to getProcessControl().isSuspended(). */ - public synchronized boolean isSuspended() throws DebuggerException { - return getProcessControl().isSuspended(); - } - - /** Suspends the target process completely. Equivalent to - getProcessControl().suspend(). */ - public synchronized void suspend() throws DebuggerException { - getProcessControl().suspend(); - } - - /** Resumes the target process completely. Equivalent to - getProcessControl().suspend(). */ - public synchronized void resume() throws DebuggerException { - getProcessControl().resume(); - } - - /** Indicates whether we are attached to a Java HotSpot virtual - machine */ - public synchronized boolean isJavaMode() { - return javaMode; - } - - /** Temporarily disables interaction with the target process via - JVMDI. This is done while the target process is stopped at a C - breakpoint. Can be called even if the JVMDI agent has not been - initialized. */ - public synchronized void disableJavaInteraction() { - javaInteractionDisabled = true; - } - - /** Re-enables interaction with the target process via JVMDI. This - is done while the target process is continued past a C - braekpoint. Can be called even if the JVMDI agent has not been - initialized. */ - public synchronized void enableJavaInteraction() { - javaInteractionDisabled = false; - } - - /** Indicates whether Java interaction has been disabled */ - public synchronized boolean isJavaInteractionDisabled() { - return javaInteractionDisabled; - } - - /** Indicates whether we can talk to the Serviceability Agent's - JVMDI module to be able to set breakpoints */ - public synchronized boolean canInteractWithJava() { - return (jvmdi != null) && !javaInteractionDisabled; - } - - /** Suspends all Java threads in the target process. Can only be - called if we are attached to a HotSpot JVM and can connect to - the SA's JVMDI module. Must not be called when the target - process has been suspended with suspend(). */ - public synchronized void suspendJava() throws DebuggerException { - if (!canInteractWithJava()) { - throw new DebuggerException("Could not connect to SA's JVMDI module"); - } - if (jvmdi.isSuspended()) { - throw new DebuggerException("Target process already suspended via JVMDI"); - } - jvmdi.suspend(); - } - - /** Resumes all Java threads in the target process. Can only be - called if we are attached to a HotSpot JVM and can connect to - the SA's JVMDI module. Must not be called when the target - process has been suspended with suspend(). */ - public synchronized void resumeJava() throws DebuggerException { - if (!canInteractWithJava()) { - throw new DebuggerException("Could not connect to SA's JVMDI module"); - } - if (!jvmdi.isSuspended()) { - throw new DebuggerException("Target process already resumed via JVMDI"); - } - jvmdi.resume(); - } - - /** Indicates whether the target process has been suspended at the - Java language level via the SA's JVMDI module */ - public synchronized boolean isJavaSuspended() throws DebuggerException { - return jvmdi.isSuspended(); - } - - /** Toggle a Java breakpoint at the given location. */ - public synchronized ServiceabilityAgentJVMDIModule.BreakpointToggleResult - toggleJavaBreakpoint(String srcFileName, - String pkgName, - int lineNo) { - if (!canInteractWithJava()) { - throw new DebuggerException("Could not connect to SA's JVMDI module; can not toggle Java breakpoints"); - } - return jvmdi.toggleBreakpoint(srcFileName, pkgName, lineNo); - } - - /** Access to JVMDI module's eventPending */ - public synchronized boolean javaEventPending() throws DebuggerException { - if (!canInteractWithJava()) { - throw new DebuggerException("Could not connect to SA's JVMDI module; can not poll for Java debug events"); - } - return jvmdi.eventPending(); - } - - /** Access to JVMDI module's eventPoll */ - public synchronized Event javaEventPoll() throws DebuggerException { - if (!canInteractWithJava()) { - throw new DebuggerException("Could not connect to SA's JVMDI module; can not poll for Java debug events"); - } - return jvmdi.eventPoll(); - } - - /** Access to JVMDI module's eventContinue */ - public synchronized void javaEventContinue() throws DebuggerException { - if (!canInteractWithJava()) { - throw new DebuggerException("Could not connect to SA's JVMDI module; can not continue past Java debug events"); - } - jvmdi.eventContinue(); - } - - - // FIXME: add other accessors. For example, suspension and - // resumption should be done through this interface, as well as - // interaction with the live Java process such as breakpoint setting. - // Probably should not expose the ServiceabilityAgentJVMDIModule - // from this interface. - - //-------------------------------------------------------------------------------- - // Client-side operations - // - - /** This attaches to a process running on the local machine. */ - public synchronized void attach(int processID) - throws DebuggerException { - if (debugger != null) { - throw new DebuggerException("Already attached"); - } - pid = processID; - startupMode = PROCESS_MODE; - isServer = false; - go(); - } - - /** This opens a core file on the local machine */ - public synchronized void attach(String executableName, String coreFileName) - throws DebuggerException { - if (debugger != null) { - throw new DebuggerException("Already attached"); - } - if ((executableName == null) || (coreFileName == null)) { - throw new DebuggerException("Both the core file name and executable name must be specified"); - } - this.executableName = executableName; - this.coreFileName = coreFileName; - startupMode = CORE_FILE_MODE; - 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 - come in. */ - public synchronized void attach(String remoteServerID) - throws DebuggerException { - if (debugger != null) { - throw new DebuggerException("Already attached to a process"); - } - if (remoteServerID == null) { - throw new DebuggerException("Debug server id must be specified"); - } - - debugServerID = remoteServerID; - startupMode = REMOTE_MODE; - isServer = false; - go(); - } - - /** This should only be called by the user on the client machine, - not the server machine */ - public synchronized boolean detach() throws DebuggerException { - if (isServer) { - throw new DebuggerException("Should not call detach() for server configuration"); - } - return detachInternal(); - } - - //-------------------------------------------------------------------------------- - // Server-side operations - // - - /** This attaches to a process running on the local machine and - starts a debug server, allowing remote machines to connect and - examine this process. uniqueID is used to uniquely identify the - debuggee */ - public synchronized void startServer(int processID, String uniqueID) - throws DebuggerException { - if (debugger != null) { - throw new DebuggerException("Already attached"); - } - pid = processID; - startupMode = PROCESS_MODE; - isServer = true; - serverID = uniqueID; - go(); - } - - /** This attaches to a process running on the local machine and - starts a debug server, allowing remote machines to connect and - examine this process. */ - public synchronized void startServer(int processID) - throws DebuggerException { - startServer(processID, null); - } - - /** This opens a core file on the local machine and starts a debug - server, allowing remote machines to connect and examine this - core file. uniqueID is used to uniquely identify the - debuggee */ - public synchronized void startServer(String executableName, String coreFileName, - String uniqueID) - throws DebuggerException { - if (debugger != null) { - throw new DebuggerException("Already attached"); - } - if ((executableName == null) || (coreFileName == null)) { - throw new DebuggerException("Both the core file name and Java executable name must be specified"); - } - this.executableName = executableName; - this.coreFileName = coreFileName; - startupMode = CORE_FILE_MODE; - isServer = true; - serverID = uniqueID; - go(); - } - - /** This opens a core file on the local machine and starts a debug - server, allowing remote machines to connect and examine this - core file.*/ - public synchronized void startServer(String executableName, String coreFileName) - throws DebuggerException { - startServer(executableName, coreFileName, null); - } - - /** This may only be called on the server side after startServer() - has been called */ - public synchronized boolean shutdownServer() throws DebuggerException { - if (!isServer) { - throw new DebuggerException("Should not call shutdownServer() for client configuration"); - } - return detachInternal(); - } - - - //-------------------------------------------------------------------------------- - // Internals only below this point - // - - private boolean detachInternal() { - if (debugger == null) { - return false; - } - if (canInteractWithJava()) { - jvmdi.detach(); - jvmdi = null; - } - boolean retval = true; - if (!isServer) { - VM.shutdown(); - } - // We must not call detach() if we are a client and are connected - // to a remote debugger - Debugger dbg = null; - DebuggerException ex = null; - if (isServer) { - try { - RMIHelper.unbind(serverID); - } - catch (DebuggerException de) { - ex = de; - } - dbg = debugger; - } else { - if (startupMode != REMOTE_MODE) { - dbg = debugger; - } - } - if (dbg != null) { - retval = dbg.detach(); - } - - debugger = null; - machDesc = null; - db = null; - if (ex != null) { - throw(ex); - } - return retval; - } - - private void go() { - setupDebugger(); - javaMode = setupVM(); - } - - private void setupDebugger() { - if (startupMode != REMOTE_MODE) { - // - // Local mode (client attaching to local process or setting up - // 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"); - - if (os.equals("solaris")) { - setupDebuggerSolaris(); - } else if (os.equals("win32")) { - setupDebuggerWin32(); - } else if (os.equals("linux")) { - setupDebuggerLinux(); - } else if (os.equals("bsd")) { - setupDebuggerBsd(); - } else { - // Add support for more operating systems here - throw new DebuggerException("Operating system " + os + " not yet supported"); - } - if (isServer) { - RemoteDebuggerServer remote = null; - try { - remote = new RemoteDebuggerServer(debugger); - } - catch (RemoteException rem) { - throw new DebuggerException(rem); - } - RMIHelper.rebind(serverID, remote); - } - } else { - // - // Remote mode (client attaching to server) - // - - // Create and install a security manager - - // FIXME: currently commented out because we were having - // security problems since we're "in the sun.* hierarchy" here. - // Perhaps a permissive policy file would work around this. In - // the long run, will probably have to move into com.sun.*. - - // if (System.getSecurityManager() == null) { - // System.setSecurityManager(new RMISecurityManager()); - // } - - connectRemoteDebugger(); - } - } - - private boolean setupVM() { - // We need to instantiate a HotSpotTypeDataBase on both the client - // and server machine. On the server it is only currently used to - // configure the Java primitive type sizes (which we should - // consider making constant). On the client it is used to - // configure the VM. - - try { - if (os.equals("solaris")) { - db = new HotSpotTypeDataBase(machDesc, new HotSpotSolarisVtblAccess(debugger, jvmLibNames), - debugger, jvmLibNames); - } else if (os.equals("win32")) { - db = new HotSpotTypeDataBase(machDesc, new Win32VtblAccess(debugger, jvmLibNames), - debugger, jvmLibNames); - } else if (os.equals("linux")) { - db = new HotSpotTypeDataBase(machDesc, new LinuxVtblAccess(debugger, jvmLibNames), - debugger, jvmLibNames); - } else if (os.equals("bsd")) { - db = new HotSpotTypeDataBase(machDesc, new BsdVtblAccess(debugger, jvmLibNames), - debugger, jvmLibNames); - } else { - throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess implemented yet)"); - } - } - catch (NoSuchSymbolException e) { - e.printStackTrace(); - return false; - } - - if (startupMode != REMOTE_MODE) { - // Configure the debugger with the primitive type sizes just obtained from the VM - debugger.configureJavaPrimitiveTypeSizes(db.getJBooleanType().getSize(), - db.getJByteType().getSize(), - db.getJCharType().getSize(), - db.getJDoubleType().getSize(), - db.getJFloatType().getSize(), - db.getJIntType().getSize(), - db.getJLongType().getSize(), - db.getJShortType().getSize()); - } - - if (!isServer) { - // Do not initialize the VM on the server (unnecessary, since it's - // instantiated on the client) - VM.initialize(db, debugger); - } - - try { - jvmdi = new ServiceabilityAgentJVMDIModule(debugger, saLibNames); - if (jvmdi.canAttach()) { - jvmdi.attach(); - jvmdi.setCommandTimeout(6000); - debugPrintln("Attached to Serviceability Agent's JVMDI module."); - // Jog VM to suspended point with JVMDI module - resume(); - suspendJava(); - suspend(); - debugPrintln("Suspended all Java threads."); - } else { - debugPrintln("Could not locate SA's JVMDI module; skipping attachment"); - jvmdi = null; - } - } catch (Exception e) { - e.printStackTrace(); - jvmdi = null; - } - - return true; - } - - //-------------------------------------------------------------------------------- - // OS-specific debugger setup/connect routines - // - - // - // Solaris - // - - private void setupDebuggerSolaris() { - setupJVMLibNamesSolaris(); - ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true); - debugger = dbg; - attachDebugger(); - - // Set up CPU-dependent stuff - if (cpu.equals("x86")) { - machDesc = new MachineDescriptionIntelX86(); - } else if (cpu.equals("sparc")) { - int addressSize = dbg.getRemoteProcessAddressSize(); - if (addressSize == -1) { - throw new DebuggerException("Error occurred while trying to determine the remote process's address size"); - } - - if (addressSize == 32) { - machDesc = new MachineDescriptionSPARC32Bit(); - } else if (addressSize == 64) { - machDesc = new MachineDescriptionSPARC64Bit(); - } else { - throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); - } - } else if (cpu.equals("amd64")) { - machDesc = new MachineDescriptionAMD64(); - } else { - throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64"); - } - - dbg.setMachineDescription(machDesc); - } - - private void connectRemoteDebugger() throws DebuggerException { - RemoteDebugger remote = - (RemoteDebugger) RMIHelper.lookup(debugServerID); - debugger = new RemoteDebuggerClient(remote); - machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); - os = debugger.getOS(); - if (os.equals("solaris")) { - setupJVMLibNamesSolaris(); - } else if (os.equals("win32")) { - setupJVMLibNamesWin32(); - } else if (os.equals("linux")) { - setupJVMLibNamesLinux(); - } else if (os.equals("bsd")) { - setupJVMLibNamesBsd(); - } else { - throw new RuntimeException("Unknown OS type"); - } - - cpu = debugger.getCPU(); - } - - private void setupJVMLibNamesSolaris() { - jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so", "gamma_g" }; - saLibNames = new String[] { "libsa.so", "libsa_g.so" }; - } - - // - // Win32 - // - - private void setupDebuggerWin32() { - setupJVMLibNamesWin32(); - - if (cpu.equals("x86")) { - machDesc = new MachineDescriptionIntelX86(); - } else if (cpu.equals("amd64")) { - machDesc = new MachineDescriptionAMD64(); - } else if (cpu.equals("ia64")) { - machDesc = new MachineDescriptionIA64(); - } else { - throw new DebuggerException("Win32 supported under x86, amd64 and ia64 only"); - } - - // Note we do not use a cache for the local debugger in server - // mode; it will be taken care of on the client side (once remote - // debugging is implemented). - - debugger = new WindbgDebuggerLocal(machDesc, !isServer); - - attachDebugger(); - } - - private void setupJVMLibNamesWin32() { - jvmLibNames = new String[] { "jvm.dll", "jvm_g.dll" }; - saLibNames = new String[] { "sa.dll", "sa_g.dll" }; - } - - // - // Linux - // - - private void setupDebuggerLinux() { - setupJVMLibNamesLinux(); - - if (cpu.equals("x86")) { - machDesc = new MachineDescriptionIntelX86(); - } else if (cpu.equals("ia64")) { - machDesc = new MachineDescriptionIA64(); - } else if (cpu.equals("amd64")) { - machDesc = new MachineDescriptionAMD64(); - } else if (cpu.equals("sparc")) { - if (LinuxDebuggerLocal.getAddressSize()==8) { - machDesc = new MachineDescriptionSPARC64Bit(); - } else { - machDesc = new MachineDescriptionSPARC32Bit(); - } - } else { - try { - machDesc = (MachineDescription) - Class.forName("sun.jvm.hotspot.debugger.MachineDescription" + - cpu.toUpperCase()).newInstance(); - } catch (Exception e) { - throw new DebuggerException("unsupported machine type"); - } - } - - - // Note we do not use a cache for the local debugger in server - // mode; it will be taken care of on the client side (once remote - // debugging is implemented). - - debugger = new LinuxDebuggerLocal(machDesc, !isServer); - attachDebugger(); - } - - private void setupJVMLibNamesLinux() { - // same as solaris - setupJVMLibNamesSolaris(); - } - - // - // BSD - // - - private void setupDebuggerBsd() { - setupJVMLibNamesBsd(); - - if (cpu.equals("x86")) { - machDesc = new MachineDescriptionIntelX86(); - } else if (cpu.equals("amd64") || (cpu.equals("x86_64"))) { - machDesc = new MachineDescriptionAMD64(); - } else { - throw new DebuggerException("Bsd only supported on x86/x86_64. Current arch: " + cpu); - } - - // Note we do not use a cache for the local debugger in server - // mode; it will be taken care of on the client side (once remote - // debugging is implemented). - - debugger = new BsdDebuggerLocal(machDesc, !isServer); - attachDebugger(); - } - - private void setupJVMLibNamesBsd() { - // same as solaris - setupJVMLibNamesSolaris(); - } - - /** Convenience routine which should be called by per-platform - debugger setup. Should not be called when startupMode is - REMOTE_MODE. */ - private void attachDebugger() { - if (startupMode == PROCESS_MODE) { - debugger.attach(pid); - } else if (startupMode == CORE_FILE_MODE) { - debugger.attach(executableName, coreFileName); - } else { - throw new DebuggerException("Should not call attach() for startupMode == " + startupMode); - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/JavaLineNumberInfo.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/JavaLineNumberInfo.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import sun.jvm.hotspot.oops.*; - -/** Wrapper class which describes line number information for Java - class files. The line number table is converted into this - representation on demand. These objects are then sorted by line - number for fast lookup when setting breakpoints in a particular - source file. */ - -public class JavaLineNumberInfo { - private InstanceKlass klass; - private Method method; - private int startBCI; - private int lineNumber; - - public JavaLineNumberInfo(InstanceKlass klass, - Method method, - int startBCI, - int lineNumber) { - this.klass = klass; - this.method = method; - this.startBCI = startBCI; - this.lineNumber = lineNumber; - } - - public InstanceKlass getKlass() { return klass; } - public Method getMethod() { return method; } - public int getStartBCI() { return startBCI; } - public int getLineNumber() { return lineNumber; } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/Main.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2001, 2008, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.awt.*; -import java.awt.event.*; -import javax.swing.*; - -import sun.jvm.hotspot.ui.*; - -/** The main class for the BugSpot debugger. */ - -public class Main { - public static void main(String[] args) { - JFrame frame = new JFrame("BugSpot"); - frame.setSize(800, 600); - BugSpot db = new BugSpot(); - db.setMDIMode(true); - db.build(); - frame.setJMenuBar(db.getMenuBar()); - frame.getContentPane().add(db); - frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); - - GraphicsUtilities.reshapeToAspectRatio(frame, - 4.0f/3.0f, 0.85f, Toolkit.getDefaultToolkit().getScreenSize()); - GraphicsUtilities.centerInContainer(frame, - Toolkit.getDefaultToolkit().getScreenSize()); - frame.setVisible(true); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/PCFinder.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/PCFinder.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,96 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.cdbg.*; - -/** Helper class for locating a program counter. Indicates the - confidence of the find. */ - -public class PCFinder { - public static final int LOW_CONFIDENCE = 1; - public static final int HIGH_CONFIDENCE = 2; - - public static class Info { - private String name; - private long offset; - private int confidence; - - public Info(String name, long offset, int confidence) { - this.name = name; - this.offset = offset; - this.confidence = confidence; - } - - /** May be null */ - public String getName() { return name; } - - /** If this is -1, a symbol could not be found, and the offset - should not be shown */ - public long getOffset() { return offset; } - - /** PCFinder.LOW_CONFIDENCE or PCFinder.HIGH_CONFIDENCE */ - public int getConfidence() { return confidence; } - } - - /** Passed loadobject may be null in which case the returned Info - object has low confidence */ - public static Info findPC(Address pc, LoadObject lo, CDebugger dbg) { - if (lo == null) { - return new Info(null, -1, LOW_CONFIDENCE); - } - - // First try debug info - BlockSym sym = lo.debugInfoForPC(pc); - while (sym != null) { - if (sym.isFunction()) { - // Highest confidence - return new Info(sym.toString(), pc.minus(sym.getAddress()), HIGH_CONFIDENCE); - } - } - - // Now try looking up symbol in loadobject - - // FIXME: must add support for mapfiles on Win32 and try looking - // up there first if possible. Should we hide that behind - // LoadObject.closestSymbolToPC and have the ClosestSymbol return - // confidence? I think so. On Solaris there is no notion of a - // mapfile, and the confidence for closestSymbolToPC will be high - // instead of low. - - int confidence = HIGH_CONFIDENCE; - - ClosestSymbol cs = lo.closestSymbolToPC(pc); - if (cs != null) { - // FIXME: currently low confidence (only on Win32) - return new Info(cs.getName() + "()", cs.getOffset(), LOW_CONFIDENCE); - } - - // Unknown location - return new Info(dbg.getNameOfFile(lo.getName()).toUpperCase() + - "! " + pc + "()", -1, HIGH_CONFIDENCE); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/PackageScanner.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/PackageScanner.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.io.*; - -/** Scans a .java file for the package that it is in. */ - -public class PackageScanner { - - public PackageScanner() { - } - - public String scan(String filename) { - return scan(new File(filename)); - } - - /** Returns the String comprising the package name of the classes in - this .java file. Returns the (non-null) empty string if any - error occurs or if the classes are in the unnamed package. */ - public String scan(File file) { - BufferedReader buf = null; - String res = ""; - try { - buf = new BufferedReader(new FileReader(file)); - StreamTokenizer tok = new StreamTokenizer(buf); - tok.slashStarComments(true); - tok.slashSlashComments(true); - if (tok.nextToken() != StreamTokenizer.TT_WORD) { - return res; - } - if (!tok.sval.equals("package")) { - return res; - } - if (tok.nextToken() != StreamTokenizer.TT_WORD) { - return res; - } - res = tok.sval; - return res; - } catch (FileNotFoundException e) { - return res; - } catch (IOException e) { - return res; - } finally { - try { - if (buf != null) { - buf.close(); - } - } catch (IOException e) { - } - } - } - - public static void main(String[] args) { - if (args.length != 1) { - usage(); - } - - System.out.println(new PackageScanner().scan(args[0])); - } - - private static void usage() { - System.err.println("Usage: java PackageScanner <.java file name>"); - System.err.println("Prints package the .java file is in to stdout."); - System.exit(1); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/RegisterPanel.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/RegisterPanel.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,173 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.awt.*; -import java.util.*; -import javax.swing.*; -import javax.swing.table.*; - -import sun.jvm.hotspot.debugger.*; - -/** Displays registers in a window. FIXME: this will need more work to - understand and handle register windows. */ - -public class RegisterPanel extends JPanel { - private java.util.List/**/ registers; - private AbstractTableModel dataModel; - private boolean valid; - private boolean editable; - private String nullAddressString; - private ThreadProxy curThread; - private JTable table; - - static class RegisterInfo { - private String name; - private Address value; - - RegisterInfo(String name, Address value) { - this.name = name; - this.value = value; - } - - String getName() { return name; } - Address getValue() { return value; } - } - - public RegisterPanel() { - super(); - - registers = new ArrayList(); - - dataModel = new AbstractTableModel() { - public int getColumnCount() { return 2; } - public int getRowCount() { return registers.size(); } - public String getColumnName(int col) { - switch (col) { - case 0: - return "Register Name"; - case 1: - return "Register Value"; - default: - throw new RuntimeException("Index " + col + " out of bounds"); - } - } - public Object getValueAt(int row, int col) { - RegisterInfo info = (RegisterInfo) registers.get(row); - - switch (col) { - case 0: - return info.getName(); - case 1: - if (valid) { - Address val = info.getValue(); - if (val != null) { - return val; - } else { - return nullAddressString; - } - } else { - return "-"; - } - default: - throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds"); - } - } - public boolean isCellEditable(int row, int col) { - if (col == 0) return false; - if (!valid) return false; - if (curThread == null) return false; - if (!curThread.canSetContext()) return false; - - // FIXME: add listener to watch for register changes - // return true; - return false; - } - }; - - // Build user interface - setLayout(new BorderLayout()); - table = new JTable(dataModel); - table.setCellSelectionEnabled(true); - table.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); - table.setDragEnabled(true); - JTableHeader header = table.getTableHeader(); - header.setReorderingAllowed(false); - JScrollPane scrollPane = new JScrollPane(table); - add(scrollPane, BorderLayout.CENTER); - } - - - /** Updates the register panel with the register set from the - specified thread. Call this when the process has been suspended - and the current thread has been set. FIXME: this interface will - need to change to support register windows. */ - public void update(ThreadProxy curThread) { - this.curThread = curThread; - ThreadContext context = curThread.getContext(); - editable = curThread.canSetContext(); - registers.clear(); - for (int i = 0; i < context.getNumRegisters(); i++) { - String name = context.getRegisterName(i); - Address addr = context.getRegisterAsAddress(i); - if ((nullAddressString == null) && (addr != null)) { - String addrStr = addr.toString(); - StringBuffer buf = new StringBuffer(); - buf.append("0x"); - int len = addrStr.length() - 2; - for (int j = 0; j < len; j++) { - buf.append("0"); - } - nullAddressString = buf.toString(); - } - registers.add(new RegisterInfo(name, addr)); - } - valid = true; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - dataModel.fireTableDataChanged(); - } - }); - } - - /** Clears the registers' values. Call this when the processs has - been resumed. */ - public void clear() { - valid = false; - nullAddressString = null; - SwingUtilities.invokeLater(new Runnable() { - public void run() { - dataModel.fireTableDataChanged(); - } - }); - } - - public void setFont(Font font) { - super.setFont(font); - if (table != null) { - table.setFont(font); - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTraceEntry.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTraceEntry.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2001, 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; - -/** This class describes a frame in a stack trace. It abstracts over - C/C++ and Java frames. */ - -public class StackTraceEntry { - private CFrame cFrame; - private CDebugger dbg; - private JavaVFrame javaFrame; - private String value; // What is displayed in a stack trace - // For merging C and Java stack traces. - // For more precise stack traces, should probably have a way to - // convert a CFrame to a sun.jvm.hotspot.runtime.Frame. For now, - // doing similar algorithm to jdbx (which does not have intimate - // knowledge of the VM). - private boolean isUnknownCFrame; - - public StackTraceEntry(CFrame cFrame, CDebugger dbg) { - this.cFrame = cFrame; - this.dbg = dbg; - computeValue(); - } - - public StackTraceEntry(JavaVFrame javaFrame) { - this.javaFrame = javaFrame; - computeValue(); - } - - public boolean isCFrame() { return (cFrame != null); } - public boolean isJavaFrame() { return (javaFrame != null); } - public CFrame getCFrame() { return cFrame; } - public JavaVFrame getJavaFrame() { return javaFrame; } - public boolean isUnknownCFrame() { return isUnknownCFrame; } - public String toString() { - return value; - } - - private void computeValue() { - isUnknownCFrame = true; - value = ""; - if (cFrame != null) { - PCFinder.Info info = PCFinder.findPC(cFrame.pc(), cFrame.loadObjectForPC(), dbg); - if (info.getName() != null) { - value = "(C) " + info.getName(); - isUnknownCFrame = false; - if (info.getConfidence() == PCFinder.LOW_CONFIDENCE) { - value = value + " (?)"; - } - if (info.getOffset() >= 0) { - value = value + " + 0x" + Long.toHexString(info.getOffset()); - } - } - } else if (javaFrame != null) { - isUnknownCFrame = false; - Method m = javaFrame.getMethod(); - value = "(J) " + m.externalNameAndSignature(); - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTracePanel.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/StackTracePanel.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import javax.swing.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.ui.*; - -/** This panel contains a ListBox with all of the stack frames in a - given thread. When a given entry is selected, an event is - fired. */ - -public class StackTracePanel extends JPanel { - public interface Listener { - public void frameChanged(CFrame fr, JavaVFrame jfr); - } - - class Model extends AbstractListModel implements ComboBoxModel { - private Object selectedItem; - public Object getElementAt(int index) { - if (trace == null) return null; - return trace.get(index); - } - public int getSize() { - if (trace == null) return 0; - return trace.size(); - } - public Object getSelectedItem() { - return selectedItem; - } - public void setSelectedItem(Object item) { - selectedItem = item; - } - public void dataChanged() { - fireContentsChanged(this, 0, trace.size()); - } - } - - private java.util.List trace; - private Model model; - private JComboBox list; - private java.util.List listeners; - - public StackTracePanel() { - super(); - - model = new Model(); - - // Build user interface - setLayout(new BorderLayout()); - setBorder(GraphicsUtilities.newBorder(5)); - list = new JComboBox(model); - list.setPrototypeDisplayValue("ZZZZZZZZZZZZZZZZZZZZZZZZZZZZ"); - add(list, BorderLayout.CENTER); - - // Add selection listener - list.addItemListener(new ItemListener() { - public void itemStateChanged(ItemEvent e) { - if (e.getStateChange() == ItemEvent.SELECTED) { - fireFrameChanged(); - } - } - }); - } - - /** Takes a List of StackTraceEntry objects */ - public void setTrace(java.util.List trace) { - this.trace = trace; - model.dataChanged(); - list.setSelectedIndex(0); - fireFrameChanged(); - } - - public void addListener(Listener listener) { - if (listeners == null) { - listeners = new ArrayList(); - } - listeners.add(listener); - } - - protected void fireFrameChanged() { - if (listeners != null) { - StackTraceEntry entry = (StackTraceEntry) trace.get(list.getSelectedIndex()); - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - ((Listener) iter.next()).frameChanged(entry.getCFrame(), entry.getJavaFrame()); - } - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/ThreadListPanel.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/ThreadListPanel.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,237 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.awt.*; -import java.awt.event.*; -import java.util.*; -import javax.swing.*; -import javax.swing.table.*; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.ui.*; - -// NOTE: this class was not placed in sun.jvm.hotspot.ui to prevent -// mixing components designed for C and C++ debugging with the ones -// that work with the core serviceability agent functionality (which -// does not require that the CDebugger interface be implemented). - -/** The ThreadListPanel is used for C and C++ debugging and can - visualize all threads in the target process. The caller passes in - a CDebugger attached to the target process and can request that - JavaThreads' associations with these underlying threads be - displayed; this option is only valid when attached to a HotSpot - JVM and when the {@link sun.jvm.hotspot.runtime.VM} has been - initialized. */ - -public class ThreadListPanel extends JPanel { - /** Listener which can be added to receive "Set Focus" events */ - public static interface Listener { - /** ThreadProxy will always be provided; JavaThread will only be - present if displayJavaThreads was specified in the constructor - for the panel and the thread was a JavaThread. */ - public void setFocus(ThreadProxy thread, JavaThread jthread); - } - - static class ThreadInfo { - private ThreadProxy thread; - // Distinguish between PC == null and no top frame - private boolean gotPC; - private Address pc; - private String location; - private JavaThread javaThread; - private String javaThreadName; - - public ThreadInfo(ThreadProxy thread, CDebugger dbg, JavaThread jthread) { - this.thread = thread; - this.location = ""; - CFrame fr = dbg.topFrameForThread(thread); - if (fr != null) { - gotPC = true; - pc = fr.pc(); - PCFinder.Info info = PCFinder.findPC(pc, fr.loadObjectForPC(), dbg); - if (info.getName() != null) { - location = info.getName(); - if (info.getConfidence() == PCFinder.LOW_CONFIDENCE) { - location = location + " (?)"; - } - if (info.getOffset() < 0) { - location = location + " + 0x" + Long.toHexString(info.getOffset()); - } - } - } - if (jthread != null) { - javaThread = jthread; - javaThreadName = jthread.getThreadName(); - } - } - - public ThreadProxy getThread() { return thread; } - public boolean hasPC() { return gotPC; } - public Address getPC() { return pc; } - public String getLocation() { return location; } - public boolean isJavaThread() { return (javaThread != null); } - public JavaThread getJavaThread() { return javaThread; } - public String getJavaThreadName() { return javaThreadName; } - } - - // List - private java.util.List threadList; - private JTable table; - private AbstractTableModel dataModel; - // List - private java.util.List listeners; - - /** Takes a CDebugger from which the thread list is queried. - displayJavaThreads must only be set to true if the debugger is - attached to a HotSpot JVM and if the VM has already been - initialized. */ - public ThreadListPanel(CDebugger dbg, final boolean displayJavaThreads) { - super(); - - Map threadToJavaThreadMap = null; - if (displayJavaThreads) { - // Collect Java threads from virtual machine and insert them in - // table for later querying - threadToJavaThreadMap = new HashMap(); - Threads threads = VM.getVM().getThreads(); - for (JavaThread thr = threads.first(); thr != null; thr = thr.next()) { - threadToJavaThreadMap.put(thr.getThreadProxy(), thr); - } - } - - java.util.List/**/ threads = dbg.getThreadList(); - threadList = new ArrayList(threads.size()); - for (Iterator iter = threads.iterator(); iter.hasNext(); ) { - ThreadProxy thr = (ThreadProxy) iter.next(); - JavaThread jthr = null; - if (displayJavaThreads) { - jthr = (JavaThread) threadToJavaThreadMap.get(thr); - } - threadList.add(new ThreadInfo(thr, dbg, jthr)); - } - - // Thread ID, current PC, current symbol, Java Thread, [Java thread name] - dataModel = new AbstractTableModel() { - public int getColumnCount() { return (displayJavaThreads ? 5 : 3); } - public int getRowCount() { return threadList.size(); } - public String getColumnName(int col) { - switch (col) { - case 0: - return "Thread ID"; - case 1: - return "PC"; - case 2: - return "Location"; - case 3: - return "Java?"; - case 4: - return "Java Thread Name"; - default: - throw new RuntimeException("Index " + col + " out of bounds"); - } - } - public Object getValueAt(int row, int col) { - ThreadInfo info = (ThreadInfo) threadList.get(row); - - switch (col) { - case 0: - return info.getThread(); - case 1: - { - if (info.hasPC()) { - return info.getPC(); - } - return ""; - } - case 2: - return info.getLocation(); - case 3: - if (info.isJavaThread()) { - return "Yes"; - } else { - return ""; - } - case 4: - if (info.isJavaThread()) { - return info.getJavaThreadName(); - } else { - return ""; - } - default: - throw new RuntimeException("Index (" + col + ", " + row + ") out of bounds"); - } - } - }; - - // Build user interface - setLayout(new BorderLayout()); - table = new JTable(dataModel); - table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); - JTableHeader header = table.getTableHeader(); - header.setReorderingAllowed(false); - table.setRowSelectionAllowed(true); - table.setColumnSelectionAllowed(false); - JScrollPane scrollPane = new JScrollPane(table); - add(scrollPane, BorderLayout.CENTER); - if (threadList.size() > 0) { - table.setRowSelectionInterval(0, 0); - } - - JButton button = new JButton("Set Focus"); - button.addActionListener(new ActionListener() { - public void actionPerformed(ActionEvent e) { - int i = table.getSelectedRow(); - if (i < 0) { - return; - } - ThreadInfo info = (ThreadInfo) threadList.get(i); - for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { - ((Listener) iter.next()).setFocus(info.getThread(), info.getJavaThread()); - } - } - }); - JPanel focusPanel = new JPanel(); - focusPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); - focusPanel.setLayout(new BoxLayout(focusPanel, BoxLayout.Y_AXIS)); - focusPanel.add(Box.createGlue()); - focusPanel.add(button); - focusPanel.add(Box.createGlue()); - add(focusPanel, BorderLayout.EAST); - - // FIXME: make listener model for the debugger so if the user - // specifies a mapfile for or path to a given DSO later we can - // update our state - } - - public void addListener(Listener l) { - if (listeners == null) { - listeners = new ArrayList(); - } - listeners.add(l); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/VariablePanel.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/VariablePanel.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,252 +0,0 @@ -/* - * Copyright (c) 2001, 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot; - -import java.awt.*; -import javax.swing.*; -import java.util.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.bugspot.tree.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; -import sun.jvm.hotspot.ui.tree.*; -import sun.jvm.hotspot.ui.treetable.*; - -/** Manages display of a set of local variables in a frame, or the - contents of the "this" pointer */ - -public class VariablePanel extends JPanel { - private JTreeTable treeTable; - private SimpleTreeTableModel model; - private SimpleTreeGroupNode root; - - public VariablePanel() { - super(); - - model = new SimpleTreeTableModel(); - model.setValuesEditable(false); - root = new SimpleTreeGroupNode(); - model.setRoot(root); - treeTable = new JTreeTable(model); - treeTable.setRootVisible(false); - treeTable.setShowsRootHandles(true); - treeTable.setShowsIcons(false); - treeTable.setTreeEditable(false); - treeTable.getTableHeader().setReorderingAllowed(false); - treeTable.setCellSelectionEnabled(true); - treeTable.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION); - treeTable.setDragEnabled(true); - JScrollPane sp = new JScrollPane(treeTable); - sp.getViewport().setBackground(Color.white); - - setLayout(new BorderLayout()); - add(sp, BorderLayout.CENTER); - } - - /** Clear the contents of this VariablePanel */ - public void clear() { - root.removeAllChildren(); - model.fireTreeStructureChanged(); - } - - /** Update the contents of this VariablePanel from the given CFrame */ - public void update(CFrame fr) { - // Collect locals - CCollector coll = new CCollector(); - fr.iterateLocals(coll); - update(coll); - } - - /** Update the contents of this VariablePanel from the given JavaVFrame */ - public void update(JavaVFrame jfr) { - Method m = jfr.getMethod(); - if (!m.hasLocalVariableTable()) { - return; - } - int bci = jfr.getBCI(); - // Get local variable table - LocalVariableTableElement[] locals = m.getLocalVariableTable(); - // Get locals as StackValueCollection - StackValueCollection coll = jfr.getLocals(); - root.removeAllChildren(); - // See which locals are live - for (int i = 0; i < locals.length; i++) { - LocalVariableTableElement local = locals[i]; - if (local.getStartBCI() <= bci && bci < local.getStartBCI() + local.getLength()) { - // Valid; add it - SimpleTreeNode node = null; - Symbol name = null; - try { - name = m.getConstants().getSymbolAt(local.getNameCPIndex()); - if (name == null) { - System.err.println("Null name at slot " + - local.getNameCPIndex() + - " for local variable at slot " + - local.getSlot()); - continue; - } - } catch (Exception e) { - System.err.println("Unable to fetch name at slot " + - local.getNameCPIndex() + - " for local variable at slot " + - local.getSlot()); - e.printStackTrace(); - continue; - } - sun.jvm.hotspot.oops.NamedFieldIdentifier f = - new sun.jvm.hotspot.oops.NamedFieldIdentifier(name.asString()); - Symbol descriptor = null; - try { - descriptor = m.getConstants().getSymbolAt(local.getDescriptorCPIndex()); - } catch (Exception e) { - System.err.println("Unable to fetch descriptor at slot " + - local.getDescriptorCPIndex() + - " for local variable " + f.getName() + - " at slot " + local.getSlot()); - e.printStackTrace(); - continue; - } - - if (descriptor != null) { - switch (descriptor.getByteAt(0)) { - case 'F': { - node = new sun.jvm.hotspot.ui.tree.FloatTreeNodeAdapter(coll.floatAt(local.getSlot()), f, true); - break; - } - case 'D': { - node = new sun.jvm.hotspot.ui.tree.DoubleTreeNodeAdapter(coll.doubleAt(local.getSlot()), f, true); - break; - } - case 'C': { - node = new sun.jvm.hotspot.ui.tree.CharTreeNodeAdapter((char) coll.intAt(local.getSlot()), f, true); - break; - } - case 'B': - case 'S': - case 'I': { - node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.intAt(local.getSlot()), f, true); - break; - } - case 'Z': { - node = new sun.jvm.hotspot.ui.tree.BooleanTreeNodeAdapter( - ((coll.intAt(local.getSlot()) != 0) ? true : false), f, true - ); - break; - } - case 'J': { - node = new sun.jvm.hotspot.ui.tree.LongTreeNodeAdapter(coll.longAt(local.getSlot()), f, true); - break; - } - default: { - try { - node = new sun.jvm.hotspot.ui.tree.OopTreeNodeAdapter( - VM.getVM().getObjectHeap().newOop(coll.oopHandleAt(local.getSlot())), f, true - ); - } catch (AddressException e) { - node = new sun.jvm.hotspot.ui.tree.FieldTreeNodeAdapter(f, true) { - public int getChildCount() { return 0; } - public SimpleTreeNode getChild(int i) { return null; } - public boolean isLeaf() { return false; } - public int getIndexOfChild(SimpleTreeNode child) { return 0; } - public String getValue() { - return ""; - } - }; - } - break; - } - } - if (node != null) { - root.addChild(node); - } - } - } - } - - model.fireTreeStructureChanged(); - } - - /** Update the contents of this VariablePanel from the given "this" - pointer of the given type */ - public void update(Address thisAddr, Type type) { - // Collect fields - CCollector coll = new CCollector(); - type.iterateObject(thisAddr, coll); - update(coll); - } - - private void update(CCollector coll) { - root.removeAllChildren(); - for (int i = 0; i < coll.getNumChildren(); i++) { - root.addChild(coll.getChild(i)); - } - model.fireTreeStructureChanged(); - } - - static class CCollector extends DefaultObjectVisitor { - private java.util.List children; - - public CCollector() { - children = new ArrayList(); - } - - public int getNumChildren() { - return children.size(); - } - - public SimpleTreeNode getChild(int i) { - return (SimpleTreeNode) children.get(i); - } - - public void doBit(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) { - children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true)); - } - public void doInt(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val) { - children.add(new sun.jvm.hotspot.bugspot.tree.LongTreeNodeAdapter(val, f, true)); - } - public void doEnum(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, long val, String enumName) { - children.add(new sun.jvm.hotspot.bugspot.tree.EnumTreeNodeAdapter(enumName, val, f, true)); - } - public void doFloat(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, float val) { - children.add(new sun.jvm.hotspot.bugspot.tree.FloatTreeNodeAdapter(val, f, true)); - } - public void doDouble(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, double val) { - children.add(new sun.jvm.hotspot.bugspot.tree.DoubleTreeNodeAdapter(val, f, true)); - } - public void doPointer(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { - children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true)); - } - public void doArray(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { - children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true)); - } - public void doRef(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { - children.add(new sun.jvm.hotspot.bugspot.tree.AddressTreeNodeAdapter(val, f, true)); - } - public void doCompound(sun.jvm.hotspot.debugger.cdbg.FieldIdentifier f, Address val) { - children.add(new sun.jvm.hotspot.bugspot.tree.ObjectTreeNodeAdapter(val, f, true)); - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/AddressTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/AddressTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** Encapsulates a float value in a tree handled by SimpleTreeModel */ - -public class AddressTreeNodeAdapter extends FieldTreeNodeAdapter { - private Address val; - - public AddressTreeNodeAdapter(Address val, FieldIdentifier id) { - this(val, id, false); - } - - public AddressTreeNodeAdapter(Address val, FieldIdentifier id, boolean treeTableMode) { - super(id, treeTableMode); - this.val = val; - } - - public int getChildCount() { - return 0; - } - - public SimpleTreeNode getChild(int index) { - return null; - } - - public boolean isLeaf() { - return true; - } - - public int getIndexOfChild(SimpleTreeNode child) { - return 0; - } - - public String getValue() { - if (val != null) { - return val.toString(); - } - return "NULL"; - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/DoubleTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/DoubleTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** Encapsulates a double value in a tree handled by SimpleTreeModel */ - -public class DoubleTreeNodeAdapter extends FieldTreeNodeAdapter { - private double val; - - public DoubleTreeNodeAdapter(double val, FieldIdentifier id) { - this(val, id, false); - } - - public DoubleTreeNodeAdapter(double val, FieldIdentifier id, boolean treeTableMode) { - super(id, treeTableMode); - this.val = val; - } - - public int getChildCount() { - return 0; - } - - public SimpleTreeNode getChild(int index) { - return null; - } - - public boolean isLeaf() { - return true; - } - - public int getIndexOfChild(SimpleTreeNode child) { - return 0; - } - - public String getValue() { - return Double.toString(val); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/EnumTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/EnumTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** Encapsulates an enumerated value in a tree handled by SimpleTreeModel */ - -public class EnumTreeNodeAdapter extends FieldTreeNodeAdapter { - private long val; - private String enumName; - - public EnumTreeNodeAdapter(String enumName, long val, FieldIdentifier id) { - this(enumName, val, id, false); - } - - public EnumTreeNodeAdapter(String enumName, long val, FieldIdentifier id, boolean treeTableMode) { - super(id, treeTableMode); - this.enumName = enumName; - this.val = val; - } - - public int getChildCount() { - return 0; - } - - public SimpleTreeNode getChild(int index) { - return null; - } - - public boolean isLeaf() { - return true; - } - - public int getIndexOfChild(SimpleTreeNode child) { - return 0; - } - - public String getValue() { - if (enumName != null) { - return enumName; - } else { - return Long.toString(val); - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FieldTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FieldTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** Abstract base class for all adapters for fields of C/C++ objects */ - -public abstract class FieldTreeNodeAdapter implements SimpleTreeNode { - private FieldIdentifier id; - private boolean treeTableMode; - - /** The identifier may be null, i.e., for the root of the tree */ - public FieldTreeNodeAdapter(FieldIdentifier id, boolean treeTableMode) { - this.id = id; - this.treeTableMode = treeTableMode; - } - - public FieldIdentifier getID() { - return id; - } - - /** Defaults to false in subclasses */ - public boolean getTreeTableMode() { - return treeTableMode; - } - - public Type getType() { - return getID().getType(); - } - - public String getName() { - if (getID() != null) { - return getID().toString(); - } - return ""; - } - - public String toString() { - if (treeTableMode) { - return getName(); - } else { - if (getID() != null) { - return getName() + ": " + getValue(); - } else { - return getValue(); - } - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FloatTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/FloatTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** Encapsulates a float value in a tree handled by SimpleTreeModel */ - -public class FloatTreeNodeAdapter extends FieldTreeNodeAdapter { - private float val; - - public FloatTreeNodeAdapter(float val, FieldIdentifier id) { - this(val, id, false); - } - - public FloatTreeNodeAdapter(float val, FieldIdentifier id, boolean treeTableMode) { - super(id, treeTableMode); - this.val = val; - } - - public int getChildCount() { - return 0; - } - - public SimpleTreeNode getChild(int index) { - return null; - } - - public boolean isLeaf() { - return true; - } - - public int getIndexOfChild(SimpleTreeNode child) { - return 0; - } - - public String getValue() { - return Float.toString(val); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/LongTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/LongTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,63 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** Encapsulates a long value in a tree handled by SimpleTreeModel */ - -public class LongTreeNodeAdapter extends FieldTreeNodeAdapter { - private long val; - - public LongTreeNodeAdapter(long val, FieldIdentifier id) { - this(val, id, false); - } - - public LongTreeNodeAdapter(long val, FieldIdentifier id, boolean treeTableMode) { - super(id, treeTableMode); - this.val = val; - } - - public int getChildCount() { - return 0; - } - - public SimpleTreeNode getChild(int index) { - return null; - } - - public boolean isLeaf() { - return true; - } - - public int getIndexOfChild(SimpleTreeNode child) { - return 0; - } - - public String getValue() { - return Long.toString(val); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/ObjectTreeNodeAdapter.java --- a/agent/src/share/classes/sun/jvm/hotspot/bugspot/tree/ObjectTreeNodeAdapter.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,216 +0,0 @@ -/* - * Copyright (c) 2001, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.bugspot.tree; - -import java.io.*; -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.debugger.cdbg.*; -import sun.jvm.hotspot.ui.tree.SimpleTreeNode; - -/** An adapter class which allows C/C++ objects to be displayed in a - tree via the SimpleTreeNode interface. */ - -public class ObjectTreeNodeAdapter extends FieldTreeNodeAdapter { - // Address of object - private Address addr; - - /** The address may be null (for object fields of objcets which are - null). The FieldIdentifier should not be null. treeTableMode - defaults to false. */ - public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id) { - this(addr, id, false); - } - - /** The address may be null (for object fields of objcets which are - null). The FieldIdentifier should not be null. */ - public ObjectTreeNodeAdapter(Address addr, FieldIdentifier id, boolean treeTableMode) { - super(id, treeTableMode); - this.addr = addr; - } - - public int getChildCount() { - if (addr == null) { - return 0; - } - - Counter c = new Counter(); - getType().iterateObject(addr, c); - return c.getNumFields(); - } - - public SimpleTreeNode getChild(int index) { - if (addr == null) { - return null; - } - - Fetcher f = new Fetcher(index); - getType().iterateObject(addr, f); - return f.getChild(); - } - - public boolean isLeaf() { - return (addr == null); - } - - public int getIndexOfChild(SimpleTreeNode child) { - FieldIdentifier id = ((FieldTreeNodeAdapter) child).getID(); - Finder f = new Finder(id); - getType().iterateObject(addr, f); - return f.getIndex(); - } - - public String getValue() { - if (addr != null) { - return addr.toString(); - } - return "NULL"; - } - - /** Should be used only once, then have the number of fields - fetched. */ - static class Counter extends DefaultObjectVisitor { - private int numFields; - - public int getNumFields() { - return numFields; - } - - public void doBit(FieldIdentifier f, long val) { ++numFields; } - public void doInt(FieldIdentifier f, long val) { ++numFields; } - public void doEnum(FieldIdentifier f, long val, String enumName) { ++numFields; } - public void doFloat(FieldIdentifier f, float val) { ++numFields; } - public void doDouble(FieldIdentifier f, double val) { ++numFields; } - public void doPointer(FieldIdentifier f, Address val) { ++numFields; } - public void doArray(FieldIdentifier f, Address val) { ++numFields; } - public void doRef(FieldIdentifier f, Address val) { ++numFields; } - public void doCompound(FieldIdentifier f, Address addr) { ++numFields; } - } - - /** Creates a new SimpleTreeNode for the given field. */ - class Fetcher extends DefaultObjectVisitor { - private int index; - private int curField; - private SimpleTreeNode child; - - public Fetcher(int index) { - this.index = index; - } - - public SimpleTreeNode getChild() { - return child; - } - - public void doBit(FieldIdentifier f, long val) { - if (curField == index) { - child = new LongTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doInt(FieldIdentifier f, long val) { - if (curField == index) { - child = new LongTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doEnum(FieldIdentifier f, long val, String enumName) { - if (curField == index) { - child = new EnumTreeNodeAdapter(enumName, val, f, getTreeTableMode()); - } - ++curField; - } - - public void doFloat(FieldIdentifier f, float val) { - if (curField == index) { - child = new FloatTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doDouble(FieldIdentifier f, double val) { - if (curField == index) { - child = new DoubleTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doPointer(FieldIdentifier f, Address val) { - if (curField == index) { - child = new AddressTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doArray(FieldIdentifier f, Address val) { - if (curField == index) { - child = new AddressTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doRef(FieldIdentifier f, Address val) { - if (curField == index) { - child = new AddressTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - - public void doCompound(FieldIdentifier f, Address val) { - if (curField == index) { - child = new ObjectTreeNodeAdapter(val, f, getTreeTableMode()); - } - ++curField; - } - } - - /** Finds the index of the given FieldIdentifier. */ - static class Finder extends DefaultObjectVisitor { - private FieldIdentifier id; - private int curField; - private int index = -1; - - public Finder(FieldIdentifier id) { - this.id = id; - } - - /** Returns -1 if not found */ - public int getIndex() { - return index; - } - - public void doBit(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doInt(FieldIdentifier f, long val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doEnum(FieldIdentifier f, long val, - String enumName) { if (f.equals(id)) { index = curField; } ++curField; } - public void doFloat(FieldIdentifier f, float val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doDouble(FieldIdentifier f, double val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doPointer(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doArray(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doRef(FieldIdentifier f, Address val) { if (f.equals(id)) { index = curField; } ++curField; } - public void doCompound(FieldIdentifier f, - Address val) { if (f.equals(id)) { index = curField; } ++curField; } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/BreakpointEvent.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/BreakpointEvent.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; - -public class BreakpointEvent extends Event { - private Oop thread; - private Oop clazz; - private JNIid method; - private int location; - - public BreakpointEvent(Oop thread, - Oop clazz, - JNIid method, - int location) { - super(Event.Type.BREAKPOINT); - this.thread = thread; - this.clazz = clazz; - this.method = method; - this.location = location; - } - - public Oop thread() { return thread; } - public Oop clazz() { return clazz; } - public JNIid methodID() { return method; } - public int location() { return location; } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/CIntegerAccessor.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/CIntegerAccessor.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -import sun.jvm.hotspot.debugger.*; - -class CIntegerAccessor { - private Address addr; - private long numBytes; - private boolean isUnsigned; - - CIntegerAccessor(Address addr, long numBytes, boolean isUnsigned) { - this.addr = addr; - this.numBytes = numBytes; - this.isUnsigned = isUnsigned; - } - - long getValue() { - return addr.getCIntegerAt(0, numBytes, isUnsigned); - } - - void setValue(long value) { - addr.setCIntegerAt(0, numBytes, value); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/CStringAccessor.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/CStringAccessor.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -import java.io.UnsupportedEncodingException; -import sun.jvm.hotspot.debugger.*; - -class CStringAccessor { - private Address addr; - private int bufLen; - - CStringAccessor(Address addr, int bufLen) { - this.addr = addr; - this.bufLen = bufLen; - } - - String getValue() throws DebuggerException { - int len = 0; - while ((addr.getCIntegerAt(len, 1, true) != 0) && (len < bufLen)) { - ++len; - } - byte[] res = new byte[len]; - for (int i = 0; i < len; i++) { - res[i] = (byte) addr.getCIntegerAt(i, 1, true); - } - try { - return new String(res, "US-ASCII"); - } catch (UnsupportedEncodingException e) { - throw new DebuggerException("Unable to use US-ASCII encoding"); - } - } - - void setValue(String value) throws DebuggerException { - try { - byte[] data = value.getBytes("US-ASCII"); - if (data.length >= bufLen) { - throw new DebuggerException("String too long"); - } - for (int i = 0; i < data.length; i++) { - addr.setCIntegerAt(i, 1, data[i]); - } - addr.setCIntegerAt(data.length, 1, 0); - } catch (UnsupportedEncodingException e) { - throw new DebuggerException("Unable to use US-ASCII encoding"); - } - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/Event.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/Event.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -public class Event { - public static class Type { - private Type() {} - public static final Type BREAKPOINT = new Type(); - public static final Type EXCEPTION = new Type(); - } - - private Type type; - - public Event(Type type) { - this.type = type; - } - - public Type getType() { return type; } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/ExceptionEvent.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/ExceptionEvent.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; - -public class ExceptionEvent extends Event { - private Oop thread; - private Oop clazz; - private JNIid method; - private int location; - private Oop exception; - private Oop catchClass; - private JNIid catchMethod; - private int catchLocation; - - public ExceptionEvent(Oop thread, - Oop clazz, - JNIid method, - int location, - Oop exception, - Oop catchClass, - JNIid catchMethod, - int catchLocation) { - super(Event.Type.EXCEPTION); - this.thread = thread; - this.clazz = clazz; - this.method = method; - this.location = location; - this.exception = exception; - this.catchClass = catchClass; - this.catchMethod = catchMethod; - this.catchLocation = catchLocation; - } - - public Oop thread() { return thread; } - public Oop clazz() { return clazz; } - public JNIid methodID() { return method; } - public int location() { return location; } - public Oop exception() { return exception; } - public Oop catchClass() { return catchClass; } - public JNIid catchMethodID() { return catchMethod; } - public int catchLocation() { return catchLocation; } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/JNIHandleAccessor.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/JNIHandleAccessor.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.utilities.*; - -class JNIHandleAccessor { - private Address addr; - private ObjectHeap heap; - - JNIHandleAccessor(Address addr, ObjectHeap heap) { - this.addr = addr; - this.heap = heap; - } - - Oop getValue() { - // Accessing the contents of the JNIHandle is a double dereference - Address handle = addr.getAddressAt(0); - if (handle == null) return null; - return heap.newOop(handle.getOopHandleAt(0)); - } - - void setValue(Oop value) { - Address handle = addr.getAddressAt(0); - if (Assert.ASSERTS_ENABLED) { - Assert.that(handle != null, "Must have valid global JNI handle for setting"); - } - handle.setOopHandleAt(0, value.getHandle()); - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/livejvm/ServiceabilityAgentJVMDIModule.java --- a/agent/src/share/classes/sun/jvm/hotspot/livejvm/ServiceabilityAgentJVMDIModule.java Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,415 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -package sun.jvm.hotspot.livejvm; - -import sun.jvm.hotspot.debugger.*; -import sun.jvm.hotspot.oops.*; -import sun.jvm.hotspot.runtime.*; - -/** Provides Java programming language-level interaction with a live - Java HotSpot VM via the use of the SA's JVMDI module. This is an - experimental mechanism. The BugSpot debugger should be converted - to use the JVMDI/JDWP-based JDI implementation for live process - interaction once the JDI binding for the SA is complete. */ - -public class ServiceabilityAgentJVMDIModule { - private Debugger dbg; - private String[] saLibNames; - private String saLibName; - private boolean attached; - - private boolean suspended; - - private static final int JVMDI_EVENT_BREAKPOINT = 2; - private static final int JVMDI_EVENT_EXCEPTION = 4; - - private static long timeoutMillis = 3000; - - // Values in target process - // Events sent from VM to SA - private CIntegerAccessor saAttached; - private CIntegerAccessor saEventPending; - private CIntegerAccessor saEventKind; - // Exception events - private JNIHandleAccessor saExceptionThread; - private JNIHandleAccessor saExceptionClass; - private JNIid saExceptionMethod; - private CIntegerAccessor saExceptionLocation; - private JNIHandleAccessor saExceptionException; - private JNIHandleAccessor saExceptionCatchClass; - private JNIid saExceptionCatchMethod; - private CIntegerAccessor saExceptionCatchLocation; - // Breakpoint events - private JNIHandleAccessor saBreakpointThread; - private JNIHandleAccessor saBreakpointClass; - private JNIid saBreakpointMethod; - private CIntegerAccessor saBreakpointLocation; - // Commands sent by the SA to the VM - private int SA_CMD_SUSPEND_ALL; - private int SA_CMD_RESUME_ALL; - private int SA_CMD_TOGGLE_BREAKPOINT; - private int SA_CMD_BUF_SIZE; - private CIntegerAccessor saCmdPending; - private CIntegerAccessor saCmdType; - private CIntegerAccessor saCmdResult; - private CStringAccessor saCmdResultErrMsg; - // Toggle breakpoint command arguments - private CStringAccessor saCmdBkptSrcFileName; - private CStringAccessor saCmdBkptPkgName; - private CIntegerAccessor saCmdBkptLineNumber; - private CIntegerAccessor saCmdBkptResWasError; - private CIntegerAccessor saCmdBkptResLineNumber; - private CIntegerAccessor saCmdBkptResBCI; - private CIntegerAccessor saCmdBkptResWasSet; - private CStringAccessor saCmdBkptResMethodName; - private CStringAccessor saCmdBkptResMethodSig; - - public ServiceabilityAgentJVMDIModule(Debugger dbg, String[] saLibNames) { - this.dbg = dbg; - this.saLibNames = saLibNames; - } - - /** Indicates whether a call to attach() should complete without an - exception. */ - public boolean canAttach() { - return setupLookup("SA_CMD_SUSPEND_ALL"); - } - - /** Attempt to initiate a connection with the JVMDI module in the - target VM. */ - public void attach() throws DebuggerException { - if (!canAttach()) { - throw new DebuggerException("Unable to initiate symbol lookup in SA's JVMDI module"); - } - - if (attached) { - throw new DebuggerException("Already attached"); - } - - // Attempt to look up well-known symbols in the target VM. - SA_CMD_SUSPEND_ALL = lookupConstInt("SA_CMD_SUSPEND_ALL"); - SA_CMD_RESUME_ALL = lookupConstInt("SA_CMD_RESUME_ALL"); - SA_CMD_TOGGLE_BREAKPOINT = lookupConstInt("SA_CMD_TOGGLE_BREAKPOINT"); - SA_CMD_BUF_SIZE = lookupConstInt("SA_CMD_BUF_SIZE"); - - saAttached = lookupCInt("saAttached"); - saEventPending = lookupCInt("saEventPending"); - saEventKind = lookupCInt("saEventKind"); - saCmdPending = lookupCInt("saCmdPending"); - saCmdType = lookupCInt("saCmdType"); - saCmdResult = lookupCInt("saCmdResult"); - saCmdResultErrMsg = lookupCString("saCmdResultErrMsg", SA_CMD_BUF_SIZE); - // Toggling of breakpoints - saCmdBkptSrcFileName = lookupCString("saCmdBkptSrcFileName", SA_CMD_BUF_SIZE); - saCmdBkptPkgName = lookupCString("saCmdBkptPkgName", SA_CMD_BUF_SIZE); - saCmdBkptLineNumber = lookupCInt("saCmdBkptLineNumber"); - saCmdBkptResWasError = lookupCInt("saCmdBkptResWasError"); - saCmdBkptResLineNumber = lookupCInt("saCmdBkptResLineNumber"); - saCmdBkptResBCI = lookupCInt("saCmdBkptResBCI"); - saCmdBkptResWasSet = lookupCInt("saCmdBkptResWasSet"); - saCmdBkptResMethodName = lookupCString("saCmdBkptResMethodName", SA_CMD_BUF_SIZE); - saCmdBkptResMethodSig = lookupCString("saCmdBkptResMethodSig", SA_CMD_BUF_SIZE); - - // Check for existence of symbols needed later - // FIXME: should probably cache these since we can't support the - // -Xrun module or the VM getting unloaded anyway - lookup("saExceptionThread"); - lookup("saExceptionClass"); - lookup("saExceptionMethod"); - lookup("saExceptionLocation"); - lookup("saExceptionException"); - lookup("saExceptionCatchClass"); - lookup("saExceptionCatchMethod"); - lookup("saExceptionCatchLocation"); - lookup("saBreakpointThread"); - lookup("saBreakpointClass"); - lookup("saBreakpointMethod"); - lookup("saBreakpointLocation"); - - saAttached.setValue(1); - attached = true; - } - - public void detach() { - saAttached.setValue(0); - attached = false; - saLibName = null; - } - - /** Set the timeout value (in milliseconds) for the VM to reply to - commands. Once this timeout has elapsed, the VM is assumed to - have disconnected. Defaults to 3000 milliseconds (3 seconds). */ - public void setCommandTimeout(long millis) { - timeoutMillis = millis; - } - - /** Get the timeout value (in milliseconds) for the VM to reply to - commands. Once this timeout has elapsed, the VM is assumed to - have disconnected. Defaults to 3000 milliseconds (3 seconds). */ - public long getCommandTimeout() { - return timeoutMillis; - } - - /** Indicates whether a Java debug event is pending */ - public boolean eventPending() { - return (saEventPending.getValue() != 0); - } - - /** Poll for event; returns null if none pending. */ - public Event eventPoll() { - if (saEventPending.getValue() == 0) { - return null; - } - - int kind = (int) saEventKind.getValue(); - switch (kind) { - case JVMDI_EVENT_EXCEPTION: { - JNIHandleAccessor thread = lookupJNIHandle("saExceptionThread"); - JNIHandleAccessor clazz = lookupJNIHandle("saExceptionClass"); - JNIid method = lookupJNIid("saExceptionMethod"); - CIntegerAccessor location = lookupCInt("saExceptionLocation"); - JNIHandleAccessor exception = lookupJNIHandle("saExceptionException"); - JNIHandleAccessor catchClass = lookupJNIHandle("saExceptionCatchClass"); - JNIid catchMethod = lookupJNIid("saExceptionCatchMethod"); - CIntegerAccessor catchLocation = lookupCInt("saExceptionCatchLocation"); - return new ExceptionEvent(thread.getValue(), clazz.getValue(), method, - (int) location.getValue(), exception.getValue(), - catchClass.getValue(), catchMethod, (int) catchLocation.getValue()); - } - - case JVMDI_EVENT_BREAKPOINT: { - JNIHandleAccessor thread = lookupJNIHandle("saBreakpointThread"); - JNIHandleAccessor clazz = lookupJNIHandle("saBreakpointClass"); - JNIid method = lookupJNIid("saBreakpointMethod"); - CIntegerAccessor location = lookupCInt("saBreakpointLocation"); - return new BreakpointEvent(thread.getValue(), clazz.getValue(), - method, (int) location.getValue()); - } - - default: - throw new DebuggerException("Unsupported event type " + kind); - } - } - - /** Continue past current event */ - public void eventContinue() { - saEventPending.setValue(0); - } - - /** Suspend all Java threads in the target VM. Throws - DebuggerException if the VM disconnected. */ - public void suspend() { - saCmdType.setValue(SA_CMD_SUSPEND_ALL); - saCmdPending.setValue(1); - waitForCommandCompletion(); - suspended = true; - } - - /** Resume all Java threads in the target VM. Throws - DebuggerException if the VM disconnected. */ - public void resume() { - saCmdType.setValue(SA_CMD_RESUME_ALL); - saCmdPending.setValue(1); - waitForCommandCompletion(); - suspended = false; - } - - /** Indicates whether all Java threads have been suspended via this - interface. */ - public boolean isSuspended() { - return suspended; - } - - /** Information about toggling of breakpoints */ - public static class BreakpointToggleResult { - private boolean success; - private String errMsg; - private int lineNumber; - private int bci; - private boolean wasSet; - private String methodName; - private String methodSig; - - /** Success constructor */ - public BreakpointToggleResult(int lineNumber, int bci, boolean wasSet, - String methodName, String methodSig) { - this.lineNumber = lineNumber; - this.bci = bci; - this.wasSet = wasSet; - this.methodName = methodName; - this.methodSig = methodSig; - success = true; - } - - /** Failure constructor */ - public BreakpointToggleResult(String errMsg) { - this.errMsg = errMsg; - success = false; - } - - /** Indicates whether this represents a successful return or not */ - public boolean getSuccess() { return success; } - - /** Valid only if getSuccess() returns false */ - public String getErrMsg() { return errMsg; } - - /** Line number at which breakpoint toggle occurred; valid only if - getSuccess() returns true. */ - public int getLineNumber() { return lineNumber; } - - /** BCI at which breakpoint toggle occurred; valid only if - getSuccess() returns true. */ - public int getBCI() { return bci; } - - /** Indicates whether the breakpoint toggle was the set of a - breakpoint or not; valid only if getSuccess() returns true. */ - public boolean getWasSet() { return wasSet; } - - /** Method name in which the breakpoint toggle occurred; valid - only if getSuccess() returns true. */ - public String getMethodName() { return methodName; } - - /** Method signature in which the breakpoint toggle occurred; - valid only if getSuccess() returns true. */ - public String getMethodSignature() { return methodSig; } - } - - /** Toggle a breakpoint. Throws DebuggerException if a real error - occurred; otherwise returns non-null BreakpointToggleResult. The - work of scanning the loaded classes is done in the target VM - because it turns out to be significantly faster than scanning - through the system dictionary from the SA, and interactivity - when setting breakpoints is important. */ - public BreakpointToggleResult toggleBreakpoint(String srcFileName, - String pkgName, - int lineNo) { - saCmdBkptSrcFileName.setValue(srcFileName); - saCmdBkptPkgName.setValue(pkgName); - saCmdBkptLineNumber.setValue(lineNo); - saCmdType.setValue(SA_CMD_TOGGLE_BREAKPOINT); - saCmdPending.setValue(1); - if (waitForCommandCompletion(true)) { - return new BreakpointToggleResult((int) saCmdBkptResLineNumber.getValue(), - (int) saCmdBkptResBCI.getValue(), - (saCmdBkptResWasSet.getValue() != 0), - saCmdBkptResMethodName.getValue(), - saCmdBkptResMethodSig.getValue()); - } else { - return new BreakpointToggleResult(saCmdResultErrMsg.getValue()); - } - } - - - //---------------------------------------------------------------------- - // Internals only below this point - // - - private CIntegerAccessor lookupCInt(String symbolName) { - return new CIntegerAccessor(lookup(symbolName), 4, false); - } - - private CStringAccessor lookupCString(String symbolName, int bufLen) { - return new CStringAccessor(lookup(symbolName), bufLen); - } - - private JNIHandleAccessor lookupJNIHandle(String symbolName) { - return new JNIHandleAccessor(lookup(symbolName), VM.getVM().getObjectHeap()); - } - - private JNIid lookupJNIid(String symbolName) { - Address idAddr = lookup(symbolName).getAddressAt(0); - if (idAddr == null) { - return null; - } - return new JNIid(idAddr, VM.getVM().getObjectHeap()); - } - - private int lookupConstInt(String symbolName) { - Address addr = lookup(symbolName); - return (int) addr.getCIntegerAt(0, 4, false); - } - - private boolean setupLookup(String symbolName) { - if (saLibName == null) { - for (int i = 0; i < saLibNames.length; i++) { - Address addr = dbg.lookup(saLibNames[i], symbolName); - if (addr != null) { - saLibName = saLibNames[i]; - return true; - } - } - return false; - } - return true; - } - - private Address lookup(String symbolName) { - if (saLibName == null) { - for (int i = 0; i < saLibNames.length; i++) { - Address addr = dbg.lookup(saLibNames[i], symbolName); - if (addr != null) { - saLibName = saLibNames[i]; - return addr; - } - } - throw new DebuggerException("Unable to find symbol " + symbolName + " in any of the known names for the SA"); - } - - Address addr = dbg.lookup(saLibName, symbolName); - if (addr == null) { - throw new DebuggerException("Unable to find symbol " + symbolName + " in " + saLibName); - } - return addr; - } - - private void waitForCommandCompletion() { - waitForCommandCompletion(false); - } - - /** Returns true if command succeeded, false if not */ - private boolean waitForCommandCompletion(boolean forBreakpoint) { - long start = System.currentTimeMillis(); - long cur = start; - while ((saCmdPending.getValue() != 0) && - (cur - start < timeoutMillis)) { - try { - java.lang.Thread.currentThread().sleep(10); - } catch (InterruptedException e) { - } - cur = System.currentTimeMillis(); - } - if (saCmdPending.getValue() != 0) { - detach(); - throw new DebuggerException("VM appears to have died"); - } - boolean succeeded = saCmdResult.getValue() == 0; - if (!succeeded && - (!forBreakpoint || saCmdBkptResWasError.getValue() != 0)) { - String err = saCmdResultErrMsg.getValue(); - throw new DebuggerException("Error executing JVMDI command: " + err); - } - return succeeded; - } -} diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PMap.java Fri Feb 22 10:03:02 2013 +0100 @@ -58,10 +58,6 @@ } } - protected boolean requiresVM() { - return false; - } - public static void main(String[] args) throws Exception { PMap t = new PMap(); t.start(args); diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/PStack.java Fri Feb 22 10:03:02 2013 +0100 @@ -50,29 +50,23 @@ public void run(PrintStream out) { Debugger dbg = getAgent().getDebugger(); - run(out, dbg, getAgent().isJavaMode()); + run(out, dbg); } public void run(PrintStream out, Debugger dbg) { - run(out, dbg, true); - } - - private void run(PrintStream out, Debugger dbg, final boolean isJava) { CDebugger cdbg = dbg.getCDebugger(); if (cdbg != null) { ConcurrentLocksPrinter concLocksPrinter = null; - if (isJava) { - // compute and cache java Vframes. - initJFrameCache(); - if (concurrentLocks) { - concLocksPrinter = new ConcurrentLocksPrinter(); - } - // print Java level deadlocks - try { - DeadlockDetector.print(out); - } catch (Exception exp) { - out.println("can't print deadlock information: " + exp.getMessage()); - } + // compute and cache java Vframes. + initJFrameCache(); + if (concurrentLocks) { + concLocksPrinter = new ConcurrentLocksPrinter(); + } + // print Java level deadlocks + try { + DeadlockDetector.print(out); + } catch (Exception exp) { + out.println("can't print deadlock information: " + exp.getMessage()); } List l = cdbg.getThreadList(); @@ -100,63 +94,59 @@ } out.println(); } else { - if (isJava) { - // look for one or more java frames - String[] names = null; - // check interpreter frame - Interpreter interp = VM.getVM().getInterpreter(); - if (interp.contains(pc)) { - names = getJavaNames(th, f.localVariableBase()); - // print codelet name if we can't determine method - if (names == null || names.length == 0) { - out.print(" "); - InterpreterCodelet ic = interp.getCodeletContaining(pc); - if (ic != null) { - String desc = ic.getDescription(); - if (desc != null) out.print(desc); - } - out.println(); - } - } else { - // look for known code blobs - CodeCache c = VM.getVM().getCodeCache(); - if (c.contains(pc)) { - CodeBlob cb = c.findBlobUnsafe(pc); - if (cb.isNMethod()) { - names = getJavaNames(th, f.localVariableBase()); - // just print compiled code, if can't determine method - if (names == null || names.length == 0) { - out.println(""); - } - } else if (cb.isBufferBlob()) { - out.println(""); - } else if (cb.isRuntimeStub()) { - out.println(""); - } else if (cb.isDeoptimizationStub()) { - out.println(""); - } else if (cb.isUncommonTrapStub()) { - out.println(""); - } else if (cb.isExceptionStub()) { - out.println(""); - } else if (cb.isSafepointStub()) { - out.println(""); - } else { - out.println(""); - } - } else { - printUnknown(out); - } - } - // print java frames, if any - if (names != null && names.length != 0) { - // print java frame(s) - for (int i = 0; i < names.length; i++) { - out.println(names[i]); - } - } - } else { - printUnknown(out); - } + // look for one or more java frames + String[] names = null; + // check interpreter frame + Interpreter interp = VM.getVM().getInterpreter(); + if (interp.contains(pc)) { + names = getJavaNames(th, f.localVariableBase()); + // print codelet name if we can't determine method + if (names == null || names.length == 0) { + out.print(" "); + InterpreterCodelet ic = interp.getCodeletContaining(pc); + if (ic != null) { + String desc = ic.getDescription(); + if (desc != null) out.print(desc); + } + out.println(); + } + } else { + // look for known code blobs + CodeCache c = VM.getVM().getCodeCache(); + if (c.contains(pc)) { + CodeBlob cb = c.findBlobUnsafe(pc); + if (cb.isNMethod()) { + names = getJavaNames(th, f.localVariableBase()); + // just print compiled code, if can't determine method + if (names == null || names.length == 0) { + out.println(""); + } + } else if (cb.isBufferBlob()) { + out.println(""); + } else if (cb.isRuntimeStub()) { + out.println(""); + } else if (cb.isDeoptimizationStub()) { + out.println(""); + } else if (cb.isUncommonTrapStub()) { + out.println(""); + } else if (cb.isExceptionStub()) { + out.println(""); + } else if (cb.isSafepointStub()) { + out.println(""); + } else { + out.println(""); + } + } else { + printUnknown(out); + } + } + // print java frames, if any + if (names != null && names.length != 0) { + // print java frame(s) + for (int i = 0; i < names.length; i++) { + out.println(names[i]); + } + } } f = f.sender(th); } @@ -164,7 +154,7 @@ exp.printStackTrace(); // continue, may be we can do a better job for other threads } - if (isJava && concurrentLocks) { + if (concurrentLocks) { JavaThread jthread = (JavaThread) proxyToThread.get(th); if (jthread != null) { concLocksPrinter.print(jthread, out); @@ -180,10 +170,6 @@ } } - protected boolean requiresVM() { - return false; - } - public static void main(String[] args) throws Exception { PStack t = new PStack(); t.start(args); diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java --- a/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/tools/Tool.java Fri Feb 22 10:03:02 2013 +0100 @@ -27,7 +27,6 @@ import java.io.PrintStream; import java.util.Hashtable; import sun.jvm.hotspot.*; -import sun.jvm.hotspot.bugspot.*; import sun.jvm.hotspot.runtime.*; import sun.jvm.hotspot.debugger.*; @@ -35,7 +34,7 @@ // override run & code main as shown below. public abstract class Tool implements Runnable { - private BugSpotAgent agent; + private HotSpotAgent agent; private int debugeeType; // debugeeType is one of constants below @@ -51,12 +50,7 @@ return true; } - // whether this tool requires debuggee to be java process or core? - protected boolean requiresVM() { - return true; - } - - protected void setAgent(BugSpotAgent a) { + protected void setAgent(HotSpotAgent a) { agent = a; } @@ -64,7 +58,7 @@ debugeeType = dt; } - protected BugSpotAgent getAgent() { + protected HotSpotAgent getAgent() { return agent; } @@ -155,7 +149,7 @@ usage(); } - agent = new BugSpotAgent(); + agent = new HotSpotAgent(); try { switch (debugeeType) { case DEBUGEE_PID: @@ -198,33 +192,24 @@ err.println("Debugger attached successfully."); - boolean isJava = agent.isJavaMode(); - if (isJava) { - VM vm = VM.getVM(); - if (vm.isCore()) { - err.println("Core build detected."); - } else if (vm.isClientCompiler()) { - err.println("Client compiler detected."); - } else if (vm.isServerCompiler()) { - err.println("Server compiler detected."); - } else { - throw new RuntimeException("Fatal error: " + - "should have been able to detect core/C1/C2 build"); - } + VM vm = VM.getVM(); + if (vm.isCore()) { + err.println("Core build detected."); + } else if (vm.isClientCompiler()) { + err.println("Client compiler detected."); + } else if (vm.isServerCompiler()) { + err.println("Server compiler detected."); + } else { + throw new RuntimeException("Fatal error: " + + "should have been able to detect core/C1/C2 build"); + } - String version = vm.getVMRelease(); - if (version != null) { - err.print("JVM version is "); - err.println(version); - } + String version = vm.getVMRelease(); + if (version != null) { + err.print("JVM version is "); + err.println(version); + } - run(); - } else { // not a java process or core - if (requiresVM()) { - err.println(getName() + " requires a java VM process/core!"); - } else { - run(); - } - } + run(); } } diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java --- a/agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/ui/SAPanel.java Fri Feb 22 10:03:02 2013 +0100 @@ -50,7 +50,7 @@ /** * This base class encapsulates many of the events that are fired from * the various panels in this directory so they can easily be plugged - * in to different containing frameworks (HSDB, BugSpot). + * in to different containing frameworks (HSDB). */ public class SAPanel extends JPanel { protected List listeners = new ArrayList(); diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js --- a/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Thu Feb 21 07:50:48 2013 -0500 +++ b/agent/src/share/classes/sun/jvm/hotspot/utilities/soql/sa.js Fri Feb 22 10:03:02 2013 +0100 @@ -31,7 +31,6 @@ sapkg.hotspot = Packages.sun.jvm.hotspot; sapkg.asm = sapkg.hotspot.asm; -sapkg.bugspot = sapkg.hotspot.bugspot; sapkg.c1 = sapkg.hotspot.c1; sapkg.code = sapkg.hotspot.code; sapkg.compiler = sapkg.hotspot.compiler; @@ -40,7 +39,6 @@ // sapkg.debugger = sapkg.hotspot.debugger; sapkg.interpreter = sapkg.hotspot.interpreter; -sapkg.livejvm = sapkg.hotspot.livejvm; sapkg.jdi = sapkg.hotspot.jdi; sapkg.memory = sapkg.hotspot.memory; sapkg.oops = sapkg.hotspot.oops; diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/native/jvmdi/sa.cpp --- a/agent/src/share/native/jvmdi/sa.cpp Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,601 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include -#include -#include -#include -#include "sa.hpp" -#include "jni.h" -#include "jvmdi.h" - -#ifndef WIN32 - #include -#else - typedef int int32_t; -#endif - -#ifdef WIN32 - #include - #define YIELD() Sleep(0) - #define SLEEP() Sleep(10) - #define vsnprintf _vsnprintf -#else - Error: please port YIELD() and SLEEP() macros to your platform -#endif - -using namespace std; - -////////////////////////////////////////////////////////////////////// -// // -// Exported "interface" for Java language-level interaction between // -// the SA and the VM. Note that the SA knows about the layout of // -// certain VM data structures and that knowledge is taken advantage // -// of in this code, although this interfaces with the VM via JVMDI. // -// // -////////////////////////////////////////////////////////////////////// - -extern "C" { - ///////////////////////////////////// - // // - // Events sent by the VM to the SA // - // // - ///////////////////////////////////// - - // Set by the SA when it attaches. Indicates that events should be - // posted via these exported variables, and that the VM should wait - // for those events to be acknowledged by the SA (via its setting - // saEventPending to 0). - JNIEXPORT volatile int32_t saAttached = 0; - - // Set to nonzero value by the VM when an event has been posted; set - // back to 0 by the SA when it has processed that event. - JNIEXPORT volatile int32_t saEventPending = 0; - - // Kind of the event (from jvmdi.h) - JNIEXPORT volatile int32_t saEventKind = 0; - - // - // Exception events - // - JNIEXPORT jthread saExceptionThread; - JNIEXPORT jclass saExceptionClass; - JNIEXPORT jmethodID saExceptionMethod; - JNIEXPORT int32_t saExceptionLocation; - JNIEXPORT jobject saExceptionException; - JNIEXPORT jclass saExceptionCatchClass; - JNIEXPORT jmethodID saExceptionCatchMethod; - JNIEXPORT int32_t saExceptionCatchLocation; - - // - // Breakpoint events - // - JNIEXPORT jthread saBreakpointThread; - JNIEXPORT jclass saBreakpointClass; - JNIEXPORT jmethodID saBreakpointMethod; - JNIEXPORT jlocation saBreakpointLocation; - - /////////////////////////////////////// - // // - // Commands sent by the SA to the VM // - // // - /////////////////////////////////////// - - extern JNIEXPORT const int32_t SA_CMD_SUSPEND_ALL = 0; - extern JNIEXPORT const int32_t SA_CMD_RESUME_ALL = 1; - extern JNIEXPORT const int32_t SA_CMD_TOGGLE_BREAKPOINT = 2; - extern JNIEXPORT const int32_t SA_CMD_BUF_SIZE = 1024; - - // SA sets this to a nonzero value when it is requesting a command - // to be processed; VM sets it back to 0 when the command has been - // executed - JNIEXPORT volatile int32_t saCmdPending = 0; - - // SA sets this to one of the manifest constants above to indicate - // the kind of command to be executed - JNIEXPORT volatile int32_t saCmdType = 0; - - // VM sets this to 0 if the last command succeeded or a nonzero - // value if it failed - JNIEXPORT volatile int32_t saCmdResult = 0; - - // If last command failed, this buffer will contain a descriptive - // error message - JNIEXPORT char saCmdResultErrMsg[SA_CMD_BUF_SIZE]; - - // - // Toggling of breakpoint command arguments. - // - // Originally there were separate set/clear breakpoint commands - // taking a class name, method name and signature, and the iteration - // through the debug information was done in the SA. It turns out - // that doing this work in the target VM is significantly faster, - // and since interactivity when setting and clearing breakpoints is - // important, the solution which resulted in more C/C++ code was used. - // - - // Source file name - JNIEXPORT char saCmdBkptSrcFileName[SA_CMD_BUF_SIZE]; - - // Package name ('/' as separator instead of '.') - JNIEXPORT char saCmdBkptPkgName[SA_CMD_BUF_SIZE]; - - // Line number - JNIEXPORT int32_t saCmdBkptLineNumber; - - // Output back to SA: indicator whether the last failure of a - // breakpoint toggle command was really an error or just a lack of - // debug information covering the requested line. 0 if not error. - // Valid only if saCmdResult != 0. - JNIEXPORT int32_t saCmdBkptResWasError; - - // Output back to SA: resulting line number at which the breakpoint - // was set or cleared (valid only if saCmdResult == 0) - JNIEXPORT int32_t saCmdBkptResLineNumber; - - // Output back to SA: resulting byte code index at which the - // breakpoint was set or cleared (valid only if saCmdResult == 0) - JNIEXPORT int32_t saCmdBkptResBCI; - - // Output back to SA: indicator whether the breakpoint operation - // resulted in a set or cleared breakpoint; nonzero if set, zero if - // cleared (valid only if saCmdResult == 0) - JNIEXPORT int32_t saCmdBkptResWasSet; - - // Output back to SA: method name the breakpoint was set in (valid - // only if saCmdResult == 0) - JNIEXPORT char saCmdBkptResMethodName[SA_CMD_BUF_SIZE]; - - // Output back to SA: method signature (JNI style) the breakpoint - // was set in (valid only if saCmdResult == 0) - JNIEXPORT char saCmdBkptResMethodSig[SA_CMD_BUF_SIZE]; -} - -// Internal state -static JavaVM* jvm = NULL; -static JVMDI_Interface_1* jvmdi = NULL; -static jthread debugThreadObj = NULL; -static bool suspended = false; -static vector suspendedThreads; -static JVMDI_RawMonitor eventLock = NULL; - -class MonitorLocker { -private: - JVMDI_RawMonitor lock; -public: - MonitorLocker(JVMDI_RawMonitor lock) { - this->lock = lock; - if (lock != NULL) { - jvmdi->RawMonitorEnter(lock); - } - } - ~MonitorLocker() { - if (lock != NULL) { - jvmdi->RawMonitorExit(lock); - } - } -}; - -class JvmdiDeallocator { -private: - void* ptr; -public: - JvmdiDeallocator(void* ptr) { - this->ptr = ptr; - } - ~JvmdiDeallocator() { - jvmdi->Deallocate((jbyte*) ptr); - } -}; - -class JvmdiRefListDeallocator { -private: - JNIEnv* env; - jobject* refList; - jint refCount; -public: - JvmdiRefListDeallocator(JNIEnv* env, jobject* refList, jint refCount) { - this->env = env; - this->refList = refList; - this->refCount = refCount; - } - ~JvmdiRefListDeallocator() { - for (int i = 0; i < refCount; i++) { - env->DeleteGlobalRef(refList[i]); - } - jvmdi->Deallocate((jbyte*) refList); - } -}; - -static void -stop(char* msg) { - fprintf(stderr, "%s", msg); - fprintf(stderr, "\n"); - exit(1); -} - -// This fills in the command result error message, sets the command -// result to -1, and clears the pending command flag -static void -reportErrorToSA(const char* str, ...) { - va_list varargs; - va_start(varargs, str); - vsnprintf(saCmdResultErrMsg, sizeof(saCmdResultErrMsg), str, varargs); - va_end(varargs); - saCmdResult = -1; - saCmdPending = 0; -} - -static bool -packageNameMatches(char* clazzName, char* pkg) { - int pkgLen = strlen(pkg); - int clazzNameLen = strlen(clazzName); - - if (pkgLen >= clazzNameLen + 1) { - return false; - } - - if (strncmp(clazzName, pkg, pkgLen)) { - return false; - } - - // Ensure that '/' is the next character if non-empty package name - int l = pkgLen; - if (l > 0) { - if (clazzName[l] != '/') { - return false; - } - l++; - } - // Ensure that there are no more trailing slashes - while (l < clazzNameLen) { - if (clazzName[l++] == '/') { - return false; - } - } - return true; -} - -static void -executeOneCommand(JNIEnv* env) { - switch (saCmdType) { - case SA_CMD_SUSPEND_ALL: { - if (suspended) { - reportErrorToSA("Target process already suspended"); - return; - } - - // We implement this by getting all of the threads and calling - // SuspendThread on each one, except for the thread object - // corresponding to this thread. Each thread for which the call - // succeeded (i.e., did not return JVMDI_ERROR_INVALID_THREAD) - // is added to a list which is remembered for later resumption. - // Note that this currently has race conditions since a thread - // might be started after we call GetAllThreads and since a - // thread for which we got an error earlier might be resumed by - // the VM while we are busy suspending other threads. We could - // solve this by looping until there are no more threads we can - // suspend, but a more robust and scalable solution is to add - // this functionality to the JVMDI interface (i.e., - // "suspendAll"). Probably need to provide an exclude list for - // such a routine. - jint threadCount; - jthread* threads; - if (jvmdi->GetAllThreads(&threadCount, &threads) != JVMDI_ERROR_NONE) { - reportErrorToSA("Error while getting thread list"); - return; - } - - - for (int i = 0; i < threadCount; i++) { - jthread thr = threads[i]; - if (!env->IsSameObject(thr, debugThreadObj)) { - jvmdiError err = jvmdi->SuspendThread(thr); - if (err == JVMDI_ERROR_NONE) { - // Remember this thread and do not free it - suspendedThreads.push_back(thr); - continue; - } else { - fprintf(stderr, " SA: Error %d while suspending thread\n", err); - // FIXME: stop, resume all threads, report error - } - } - env->DeleteGlobalRef(thr); - } - - // Free up threads - jvmdi->Deallocate((jbyte*) threads); - - // Suspension is complete - suspended = true; - break; - } - - case SA_CMD_RESUME_ALL: { - if (!suspended) { - reportErrorToSA("Target process already suspended"); - return; - } - - saCmdResult = 0; - bool errorOccurred = false; - jvmdiError firstError; - for (int i = 0; i < suspendedThreads.size(); i++) { - jthread thr = suspendedThreads[i]; - jvmdiError err = jvmdi->ResumeThread(thr); - env->DeleteGlobalRef(thr); - if (err != JVMDI_ERROR_NONE) { - if (!errorOccurred) { - errorOccurred = true; - firstError = err; - } - } - } - suspendedThreads.clear(); - suspended = false; - if (errorOccurred) { - reportErrorToSA("Error %d while resuming threads", firstError); - return; - } - break; - } - - case SA_CMD_TOGGLE_BREAKPOINT: { - saCmdBkptResWasError = 1; - - // Search line number info for all loaded classes - jint classCount; - jclass* classes; - - jvmdiError glcRes = jvmdi->GetLoadedClasses(&classCount, &classes); - if (glcRes != JVMDI_ERROR_NONE) { - reportErrorToSA("Error %d while getting loaded classes", glcRes); - return; - } - JvmdiRefListDeallocator rld(env, (jobject*) classes, classCount); - - bool done = false; - bool gotOne = false; - jclass targetClass; - jmethodID targetMethod; - jlocation targetLocation; - jint targetLineNumber; - - for (int i = 0; i < classCount && !done; i++) { - fflush(stderr); - jclass clazz = classes[i]; - char* srcName; - jvmdiError sfnRes = jvmdi->GetSourceFileName(clazz, &srcName); - if (sfnRes == JVMDI_ERROR_NONE) { - JvmdiDeallocator de1(srcName); - if (!strcmp(srcName, saCmdBkptSrcFileName)) { - // Got a match. Now see whether the package name of the class also matches - char* clazzName; - jvmdiError sigRes = jvmdi->GetClassSignature(clazz, &clazzName); - if (sigRes != JVMDI_ERROR_NONE) { - reportErrorToSA("Error %d while getting a class's signature", sigRes); - return; - } - JvmdiDeallocator de2(clazzName); - if (packageNameMatches(clazzName + 1, saCmdBkptPkgName)) { - // Iterate through all methods - jint methodCount; - jmethodID* methods; - if (jvmdi->GetClassMethods(clazz, &methodCount, &methods) != JVMDI_ERROR_NONE) { - reportErrorToSA("Error while getting methods of class %s", clazzName); - return; - } - JvmdiDeallocator de3(methods); - for (int j = 0; j < methodCount && !done; j++) { - jmethodID m = methods[j]; - jint entryCount; - JVMDI_line_number_entry* table; - jvmdiError lnRes = jvmdi->GetLineNumberTable(clazz, m, &entryCount, &table); - if (lnRes == JVMDI_ERROR_NONE) { - JvmdiDeallocator de4(table); - // Look for line number greater than or equal to requested line - for (int k = 0; k < entryCount && !done; k++) { - JVMDI_line_number_entry& entry = table[k]; - if (entry.line_number >= saCmdBkptLineNumber && - (!gotOne || entry.line_number < targetLineNumber)) { - gotOne = true; - targetClass = clazz; - targetMethod = m; - targetLocation = entry.start_location; - targetLineNumber = entry.line_number; - done = (targetLineNumber == saCmdBkptLineNumber); - } - } - } else if (lnRes != JVMDI_ERROR_ABSENT_INFORMATION) { - reportErrorToSA("Unexpected error %d while fetching line number table", lnRes); - return; - } - } - } - } - } else if (sfnRes != JVMDI_ERROR_ABSENT_INFORMATION) { - reportErrorToSA("Unexpected error %d while fetching source file name", sfnRes); - return; - } - } - - bool wasSet = true; - if (gotOne) { - // Really toggle this breakpoint - jvmdiError bpRes; - bpRes = jvmdi->SetBreakpoint(targetClass, targetMethod, targetLocation); - if (bpRes == JVMDI_ERROR_DUPLICATE) { - bpRes = jvmdi->ClearBreakpoint(targetClass, targetMethod, targetLocation); - wasSet = false; - } - if (bpRes != JVMDI_ERROR_NONE) { - reportErrorToSA("Unexpected error %d while setting or clearing breakpoint at bci %d, line %d", - bpRes, targetLocation, targetLineNumber); - return; - } - } else { - saCmdBkptResWasError = 0; - reportErrorToSA("No debug information found covering this line"); - return; - } - - // Provide result - saCmdBkptResLineNumber = targetLineNumber; - saCmdBkptResBCI = targetLocation; - saCmdBkptResWasSet = (wasSet ? 1 : 0); - { - char* methodName; - char* methodSig; - if (jvmdi->GetMethodName(targetClass, targetMethod, &methodName, &methodSig) - == JVMDI_ERROR_NONE) { - JvmdiDeallocator mnd(methodName); - JvmdiDeallocator msd(methodSig); - strncpy(saCmdBkptResMethodName, methodName, SA_CMD_BUF_SIZE); - strncpy(saCmdBkptResMethodSig, methodSig, SA_CMD_BUF_SIZE); - } else { - strncpy(saCmdBkptResMethodName, "", SA_CMD_BUF_SIZE); - strncpy(saCmdBkptResMethodSig, "", SA_CMD_BUF_SIZE); - } - } - break; - } - - default: - reportErrorToSA("Command %d not yet supported", saCmdType); - return; - } - - // Successful command execution - saCmdResult = 0; - saCmdPending = 0; -} - -static void -saCommandThread(void *arg) { - JNIEnv* env = NULL; - if (jvm->GetEnv((void **) &env, JNI_VERSION_1_2) != JNI_OK) { - stop("Error while starting Serviceability Agent " - "command thread: could not get JNI environment"); - } - - while (1) { - // Wait for command - while (!saCmdPending) { - SLEEP(); - } - - executeOneCommand(env); - } -} - -static void -saEventHook(JNIEnv *env, JVMDI_Event *event) -{ - MonitorLocker ml(eventLock); - - saEventKind = event->kind; - - if (event->kind == JVMDI_EVENT_VM_INIT) { - // Create event lock - if (jvmdi->CreateRawMonitor("Serviceability Agent Event Lock", &eventLock) - != JVMDI_ERROR_NONE) { - stop("Unable to create Serviceability Agent's event lock"); - } - // Start thread which receives commands from the SA. - jclass threadClass = env->FindClass("java/lang/Thread"); - if (threadClass == NULL) stop("Unable to find class java/lang/Thread"); - jstring threadName = env->NewStringUTF("Serviceability Agent Command Thread"); - if (threadName == NULL) stop("Unable to allocate debug thread name"); - jmethodID ctor = env->GetMethodID(threadClass, "", "(Ljava/lang/String;)V"); - if (ctor == NULL) stop("Unable to find appropriate constructor for java/lang/Thread"); - // Allocate thread object - jthread thr = (jthread) env->NewObject(threadClass, ctor, threadName); - if (thr == NULL) stop("Unable to allocate debug thread's java/lang/Thread instance"); - // Remember which thread this is - debugThreadObj = env->NewGlobalRef(thr); - if (debugThreadObj == NULL) stop("Unable to allocate global ref for debug thread object"); - // Start thread - jvmdiError err; - if ((err = jvmdi->RunDebugThread(thr, &saCommandThread, NULL, JVMDI_THREAD_NORM_PRIORITY)) - != JVMDI_ERROR_NONE) { - char buf[256]; - sprintf(buf, "Error %d while starting debug thread", err); - stop(buf); - } - // OK, initialization is done - return; - } - - if (!saAttached) { - return; - } - - switch (event->kind) { - case JVMDI_EVENT_EXCEPTION: { - fprintf(stderr, "SA: Exception thrown -- ignoring\n"); - saExceptionThread = event->u.exception.thread; - saExceptionClass = event->u.exception.clazz; - saExceptionMethod = event->u.exception.method; - saExceptionLocation = event->u.exception.location; - saExceptionException = event->u.exception.exception; - saExceptionCatchClass = event->u.exception.catch_clazz; - saExceptionCatchClass = event->u.exception.catch_clazz; - saExceptionCatchMethod = event->u.exception.catch_method; - saExceptionCatchLocation = event->u.exception.catch_location; - // saEventPending = 1; - break; - } - - case JVMDI_EVENT_BREAKPOINT: { - saBreakpointThread = event->u.breakpoint.thread; - saBreakpointClass = event->u.breakpoint.clazz; - saBreakpointMethod = event->u.breakpoint.method; - saBreakpointLocation = event->u.breakpoint.location; - saEventPending = 1; - break; - } - - default: - break; - } - - while (saAttached && saEventPending) { - SLEEP(); - } -} - -extern "C" { -JNIEXPORT jint JNICALL -JVM_OnLoad(JavaVM *vm, char *options, void *reserved) -{ - jvm = vm; - if (jvm->GetEnv((void**) &jvmdi, JVMDI_VERSION_1) != JNI_OK) { - return -1; - } - if (jvmdi->SetEventHook(&saEventHook) != JVMDI_ERROR_NONE) { - return -1; - } - return 0; -} -}; diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/native/jvmdi/sa.dsp --- a/agent/src/share/native/jvmdi/sa.dsp Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,105 +0,0 @@ -# Microsoft Developer Studio Project File - Name="sa" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=sa - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "sa.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "sa.mak" CFG="sa - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "sa - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "sa - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "sa - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /I "D:\jdk1.4\include" /I "D:\jdk1.4\include\win32" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /c -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "NDEBUG" -# ADD RSC /l 0x409 /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 - -!ELSEIF "$(CFG)" == "sa - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I "D:\jdk1.4\include" /I "D:\jdk1.4\include\win32" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "SA_EXPORTS" /YX /FD /GZ /c -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x409 /d "_DEBUG" -# ADD RSC /l 0x409 /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name "sa - Win32 Release" -# Name "sa - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\sa.cpp -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/native/jvmdi/sa.dsw --- a/agent/src/share/native/jvmdi/sa.dsw Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,29 +0,0 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "sa"=.\sa.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - diff -r fc64254f5579 -r 5ed317b25e23 agent/src/share/native/jvmdi/sa.hpp --- a/agent/src/share/native/jvmdi/sa.hpp Thu Feb 21 07:50:48 2013 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,30 +0,0 @@ -/* - * Copyright (c) 2002, 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 - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "jni.h" - -extern "C" { -JNIEXPORT jint JNICALL -JVM_OnLoad(JavaVM *vm, char *options, void *reserved); -} diff -r fc64254f5579 -r 5ed317b25e23 make/sa.files --- a/make/sa.files Thu Feb 21 07:50:48 2013 -0500 +++ b/make/sa.files Fri Feb 22 10:03:02 2013 +0100 @@ -24,10 +24,7 @@ # This filelist macro is included in platform specific sa.make # included all packages/*.java. package list can be generated by -# $(GAMMADIR)/agent/make/build-pkglist. Then manually removed all -# classes in sun.jvm.hotspot.ui (and subpackages), all ui classes -# in sun.jvm.hotspot.bugspot/hotspot and SPARC and x86 disassembler -# classes and sun.jvm.hotspot.utilities.soql. +# $(GAMMADIR)/agent/make/build-pkglist. # define AGENT_DIR before including this file in sa.make @@ -40,8 +37,6 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/asm/sparc/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/bugspot/tree/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/c1/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/ci/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/code/*.java \ @@ -82,7 +77,6 @@ $(AGENT_SRC_DIR)/sun/jvm/hotspot/gc_interface/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/interpreter/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/jdi/*.java \ -$(AGENT_SRC_DIR)/sun/jvm/hotspot/livejvm/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/memory/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/oops/*.java \ $(AGENT_SRC_DIR)/sun/jvm/hotspot/opto/*.java \