Mercurial > hg > truffle
view agent/src/share/classes/sun/jvm/hotspot/bugspot/ThreadListPanel.java @ 6972:bd7a7ce2e264
6830717: replay of compilations would help with debugging
Summary: When java process crashed in compiler thread, repeat the compilation process will help finding root cause. This is done with using SA dump application class data and replay data from core dump, then use debug version of jvm to recompile the problematic java method.
Reviewed-by: kvn, twisti, sspitsyn
Contributed-by: yumin.qi@oracle.com
author | minqi |
---|---|
date | Mon, 12 Nov 2012 14:03:53 -0800 |
parents | c18cbe5936b8 |
children |
line wrap: on
line source
/* * 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 = "<unknown>"; 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<ThreadInfo> private java.util.List threadList; private JTable table; private AbstractTableModel dataModel; // List<Listener> 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/*<ThreadProxy>*/ 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 "<no frames on stack>"; } 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); } }