12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.bugspot; 26 27 import java.io.PrintStream; 28 import java.net.*; 29 import java.rmi.*; 30 import sun.jvm.hotspot.*; 31 import sun.jvm.hotspot.debugger.*; 32 import sun.jvm.hotspot.debugger.dbx.*; 33 import sun.jvm.hotspot.debugger.proc.*; 34 import sun.jvm.hotspot.debugger.cdbg.*; 35 import sun.jvm.hotspot.debugger.win32.*; 36 import sun.jvm.hotspot.debugger.windbg.*; 37 import sun.jvm.hotspot.debugger.linux.*; 38 import sun.jvm.hotspot.debugger.sparc.*; 39 import sun.jvm.hotspot.debugger.remote.*; 40 import sun.jvm.hotspot.livejvm.*; 41 import sun.jvm.hotspot.memory.*; 42 import sun.jvm.hotspot.oops.*; 43 import sun.jvm.hotspot.runtime.*; 44 import sun.jvm.hotspot.types.*; 45 import sun.jvm.hotspot.utilities.*; 46 47 /** <P> This class wraps the basic functionality for connecting to the 48 * target process or debug server. It makes it simple to start up the 49 * debugging system. </P> 50 * 51 * <P> This agent (as compared to the HotSpotAgent) can connect to 52 * and interact with arbitrary processes. If the target process 53 * happens to be a HotSpot JVM, the Java debugging features of the 54 * Serviceability Agent are enabled. Further, if the Serviceability 55 * Agent's JVMDI module is loaded into the target VM, interaction 56 * with the live Java program is possible, specifically the catching 57 * of exceptions and setting of breakpoints. </P> 58 * 59 * <P> The BugSpot debugger requires that the underlying Debugger 60 * support C/C++ debugging via the CDebugger interface. </P> 61 * 62 * <P> FIXME: need to add a way to configure the paths to dbx and the 63 * DSO from the outside. However, this should work for now for 64 * internal use. </P> 65 * 66 * <P> FIXME: especially with the addition of remote debugging, this 67 * has turned into a mess; needs rethinking. </P> */ 68 69 public class BugSpotAgent { 70 71 private JVMDebugger debugger; 72 private MachineDescription machDesc; 73 private TypeDataBase db; 74 75 private String os; 76 private String cpu; 77 private String fileSep; 78 79 // The system can work in several ways: 80 // - Attaching to local process 81 // - Attaching to local core file 82 // - Connecting to remote debug server 83 // - Starting debug server for process 84 // - Starting debug server for core file 85 610 jvmdi = null; 611 } 612 } catch (Exception e) { 613 e.printStackTrace(); 614 jvmdi = null; 615 } 616 617 return true; 618 } 619 620 //-------------------------------------------------------------------------------- 621 // OS-specific debugger setup/connect routines 622 // 623 624 // 625 // Solaris 626 // 627 628 private void setupDebuggerSolaris() { 629 setupJVMLibNamesSolaris(); 630 String prop = System.getProperty("sun.jvm.hotspot.debugger.useProcDebugger"); 631 if (prop != null && !prop.equals("false")) { 632 ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true); 633 debugger = dbg; 634 attachDebugger(); 635 636 // Set up CPU-dependent stuff 637 if (cpu.equals("x86")) { 638 machDesc = new MachineDescriptionIntelX86(); 639 } else if (cpu.equals("sparc")) { 640 int addressSize = dbg.getRemoteProcessAddressSize(); 641 if (addressSize == -1) { 642 throw new DebuggerException("Error occurred while trying to determine the remote process's address size"); 643 } 644 645 if (addressSize == 32) { 646 machDesc = new MachineDescriptionSPARC32Bit(); 647 } else if (addressSize == 64) { 648 machDesc = new MachineDescriptionSPARC64Bit(); 649 } else { 650 throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); 651 } 652 } else if (cpu.equals("amd64")) { 653 machDesc = new MachineDescriptionAMD64(); 654 } else { 655 throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64"); 656 } 657 658 dbg.setMachineDescription(machDesc); 659 return; 660 } else { 661 String dbxPathName; 662 String dbxPathPrefix; 663 String dbxSvcAgentDSOPathName; 664 String dbxSvcAgentDSOPathPrefix; 665 String[] dbxSvcAgentDSOPathNames = null; 666 667 // use path names/prefixes specified on command 668 dbxPathName = System.getProperty("dbxPathName"); 669 if (dbxPathName == null) { 670 dbxPathPrefix = System.getProperty("dbxPathPrefix"); 671 if (dbxPathPrefix == null) { 672 dbxPathPrefix = defaultDbxPathPrefix; 673 } 674 dbxPathName = dbxPathPrefix + fileSep + os + fileSep + cpu + fileSep + "bin" + fileSep + "dbx"; 675 } 676 677 dbxSvcAgentDSOPathName = System.getProperty("dbxSvcAgentDSOPathName"); 678 if (dbxSvcAgentDSOPathName != null) { 679 dbxSvcAgentDSOPathNames = new String[] { dbxSvcAgentDSOPathName } ; 680 } else { 681 dbxSvcAgentDSOPathPrefix = System.getProperty("dbxSvcAgentDSOPathPrefix"); 682 if (dbxSvcAgentDSOPathPrefix == null) { 683 dbxSvcAgentDSOPathPrefix = defaultDbxSvcAgentDSOPathPrefix; 684 } 685 if (cpu.equals("sparc")) { 686 dbxSvcAgentDSOPathNames = new String[] { 687 // FIXME: bad hack for SPARC v9. This is necessary because 688 // there are two dbx executables on SPARC, one for v8 and one 689 // for v9, and it isn't obvious how to tell the two apart 690 // using the dbx command line. See 691 // DbxDebuggerLocal.importDbxModule(). 692 dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + "v9" + fileSep + "lib" + fileSep + "libsvc_agent_dbx.so", 693 dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" + fileSep + "libsvc_agent_dbx.so", 694 }; 695 } else { 696 dbxSvcAgentDSOPathNames = new String[] { 697 dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" + fileSep + "libsvc_agent_dbx.so" 698 }; 699 } 700 } 701 // Note we do not use a cache for the local debugger in server 702 // mode; it's taken care of on the client side 703 DbxDebuggerLocal dbg = new DbxDebuggerLocal(null, dbxPathName, dbxSvcAgentDSOPathNames, !isServer); 704 debugger = dbg; 705 706 attachDebugger(); 707 708 // Set up CPU-dependent stuff 709 if (cpu.equals("x86")) { 710 machDesc = new MachineDescriptionIntelX86(); 711 } else if (cpu.equals("sparc")) { 712 int addressSize = dbg.getRemoteProcessAddressSize(); 713 if (addressSize == -1) { 714 throw new DebuggerException("Error occurred while trying to determine the remote process's address size. It's possible that the Serviceability Agent's dbx module failed to initialize. Examine the standard output and standard error streams from the dbx process for more information."); 715 } 716 717 if (addressSize == 32) { 718 machDesc = new MachineDescriptionSPARC32Bit(); 719 } else if (addressSize == 64) { 720 machDesc = new MachineDescriptionSPARC64Bit(); 721 } else { 722 throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); 723 } 724 } 725 726 dbg.setMachineDescription(machDesc); 727 } 728 } 729 730 private void connectRemoteDebugger() throws DebuggerException { 731 RemoteDebugger remote = 732 (RemoteDebugger) RMIHelper.lookup(debugServerID); 733 debugger = new RemoteDebuggerClient(remote); 734 machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); 735 os = debugger.getOS(); 736 if (os.equals("solaris")) { 737 setupJVMLibNamesSolaris(); 738 } else if (os.equals("win32")) { 739 setupJVMLibNamesWin32(); 740 } else if (os.equals("linux")) { 741 setupJVMLibNamesLinux(); 742 } else { 743 throw new RuntimeException("Unknown OS type"); 744 } 745 746 cpu = debugger.getCPU(); 747 } 748 749 private void setupJVMLibNamesSolaris() { | 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.bugspot; 26 27 import java.io.PrintStream; 28 import java.net.*; 29 import java.rmi.*; 30 import sun.jvm.hotspot.*; 31 import sun.jvm.hotspot.debugger.*; 32 import sun.jvm.hotspot.debugger.proc.*; 33 import sun.jvm.hotspot.debugger.cdbg.*; 34 import sun.jvm.hotspot.debugger.win32.*; 35 import sun.jvm.hotspot.debugger.windbg.*; 36 import sun.jvm.hotspot.debugger.linux.*; 37 import sun.jvm.hotspot.debugger.sparc.*; 38 import sun.jvm.hotspot.debugger.remote.*; 39 import sun.jvm.hotspot.livejvm.*; 40 import sun.jvm.hotspot.memory.*; 41 import sun.jvm.hotspot.oops.*; 42 import sun.jvm.hotspot.runtime.*; 43 import sun.jvm.hotspot.types.*; 44 import sun.jvm.hotspot.utilities.*; 45 46 /** <P> This class wraps the basic functionality for connecting to the 47 * target process or debug server. It makes it simple to start up the 48 * debugging system. </P> 49 * 50 * <P> This agent (as compared to the HotSpotAgent) can connect to 51 * and interact with arbitrary processes. If the target process 52 * happens to be a HotSpot JVM, the Java debugging features of the 53 * Serviceability Agent are enabled. Further, if the Serviceability 54 * Agent's JVMDI module is loaded into the target VM, interaction 55 * with the live Java program is possible, specifically the catching 56 * of exceptions and setting of breakpoints. </P> 57 * 58 * <P> The BugSpot debugger requires that the underlying Debugger 59 * support C/C++ debugging via the CDebugger interface. </P> 60 * 61 * <P> FIXME: especially with the addition of remote debugging, this 62 * has turned into a mess; needs rethinking. </P> */ 63 64 public class BugSpotAgent { 65 66 private JVMDebugger debugger; 67 private MachineDescription machDesc; 68 private TypeDataBase db; 69 70 private String os; 71 private String cpu; 72 private String fileSep; 73 74 // The system can work in several ways: 75 // - Attaching to local process 76 // - Attaching to local core file 77 // - Connecting to remote debug server 78 // - Starting debug server for process 79 // - Starting debug server for core file 80 605 jvmdi = null; 606 } 607 } catch (Exception e) { 608 e.printStackTrace(); 609 jvmdi = null; 610 } 611 612 return true; 613 } 614 615 //-------------------------------------------------------------------------------- 616 // OS-specific debugger setup/connect routines 617 // 618 619 // 620 // Solaris 621 // 622 623 private void setupDebuggerSolaris() { 624 setupJVMLibNamesSolaris(); 625 ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true); 626 debugger = dbg; 627 attachDebugger(); 628 629 // Set up CPU-dependent stuff 630 if (cpu.equals("x86")) { 631 machDesc = new MachineDescriptionIntelX86(); 632 } else if (cpu.equals("sparc")) { 633 int addressSize = dbg.getRemoteProcessAddressSize(); 634 if (addressSize == -1) { 635 throw new DebuggerException("Error occurred while trying to determine the remote process's address size"); 636 } 637 638 if (addressSize == 32) { 639 machDesc = new MachineDescriptionSPARC32Bit(); 640 } else if (addressSize == 64) { 641 machDesc = new MachineDescriptionSPARC64Bit(); 642 } else { 643 throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); 644 } 645 } else if (cpu.equals("amd64")) { 646 machDesc = new MachineDescriptionAMD64(); 647 } else { 648 throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64"); 649 } 650 651 dbg.setMachineDescription(machDesc); 652 } 653 654 private void connectRemoteDebugger() throws DebuggerException { 655 RemoteDebugger remote = 656 (RemoteDebugger) RMIHelper.lookup(debugServerID); 657 debugger = new RemoteDebuggerClient(remote); 658 machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); 659 os = debugger.getOS(); 660 if (os.equals("solaris")) { 661 setupJVMLibNamesSolaris(); 662 } else if (os.equals("win32")) { 663 setupJVMLibNamesWin32(); 664 } else if (os.equals("linux")) { 665 setupJVMLibNamesLinux(); 666 } else { 667 throw new RuntimeException("Unknown OS type"); 668 } 669 670 cpu = debugger.getCPU(); 671 } 672 673 private void setupJVMLibNamesSolaris() { |