1 /* 2 * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 package sun.jvm.hotspot.tools; 26 27 import java.io.PrintStream; 28 import java.util.Hashtable; 29 import sun.jvm.hotspot.*; 30 import sun.jvm.hotspot.runtime.*; 31 import sun.jvm.hotspot.debugger.*; 32 33 // generic command line or GUI tool. 34 // override run & code main as shown below. 35 36 public abstract class Tool implements Runnable { 37 private HotSpotAgent agent; 38 private JVMDebugger jvmDebugger; 39 private int debugeeType; 40 41 // debugeeType is one of constants below 42 protected static final int DEBUGEE_PID = 0; 43 protected static final int DEBUGEE_CORE = 1; 44 protected static final int DEBUGEE_REMOTE = 2; 45 46 public Tool() { 47 } 48 49 public Tool(JVMDebugger d) { 50 jvmDebugger = d; 51 } 52 53 public String getName() { 54 return getClass().getName(); 55 } 56 57 protected boolean needsJavaPrefix() { 58 return true; 59 } 60 61 protected void setAgent(HotSpotAgent a) { 62 agent = a; 63 } 64 65 protected void setDebugeeType(int dt) { 66 debugeeType = dt; 67 } 68 69 protected HotSpotAgent getAgent() { 70 return agent; 71 } 72 73 protected int getDebugeeType() { 74 return debugeeType; 75 } 76 77 protected void printUsage() { 78 String name = null; 79 if (needsJavaPrefix()) { 80 name = "java " + getName(); 81 } else { 82 name = getName(); 83 } 84 System.out.println("Usage: " + name + " [option] <pid>"); 85 System.out.println("\t\t(to connect to a live java process)"); 86 System.out.println(" or " + name + " [option] <executable> <core>"); 87 System.out.println("\t\t(to connect to a core file)"); 88 System.out.println(" or " + name + " [option] [server_id@]<remote server IP or hostname>"); 89 System.out.println("\t\t(to connect to a remote debug server)"); 90 System.out.println(); 91 System.out.println("where option must be one of:"); 92 printFlagsUsage(); 93 } 94 95 protected void printFlagsUsage() { 96 System.out.println(" -h | -help\tto print this help message"); 97 } 98 99 protected void usage() { 100 printUsage(); 101 } 102 103 /* 104 Derived class main should be of the following form: 105 106 public static void main(String[] args) { 107 <derived class> obj = new <derived class>; 108 obj.start(args); 109 } 110 111 */ 112 113 protected void stop() { 114 if (agent != null) { 115 agent.detach(); 116 } 117 } 118 119 protected void start(String[] args) { 120 if ((args.length < 1) || (args.length > 2)) { 121 usage(); 122 return; 123 } 124 125 // Attempt to handle -h or -help or some invalid flag 126 if (args[0].startsWith("-")) { 127 usage(); 128 } 129 130 PrintStream err = System.err; 131 132 int pid = 0; 133 String coreFileName = null; 134 String executableName = null; 135 String remoteServer = null; 136 137 switch (args.length) { 138 case 1: 139 try { 140 pid = Integer.parseInt(args[0]); 141 debugeeType = DEBUGEE_PID; 142 } catch (NumberFormatException e) { 143 // try remote server 144 remoteServer = args[0]; 145 debugeeType = DEBUGEE_REMOTE; 146 } 147 break; 148 149 case 2: 150 executableName = args[0]; 151 coreFileName = args[1]; 152 debugeeType = DEBUGEE_CORE; 153 break; 154 155 default: 156 usage(); 157 } 158 159 agent = new HotSpotAgent(); 160 try { 161 switch (debugeeType) { 162 case DEBUGEE_PID: 163 err.println("Attaching to process ID " + pid + ", please wait..."); 164 agent.attach(pid); 165 break; 166 167 case DEBUGEE_CORE: 168 err.println("Attaching to core " + coreFileName + 169 " from executable " + executableName + ", please wait..."); 170 agent.attach(executableName, coreFileName); 171 break; 172 173 case DEBUGEE_REMOTE: 174 err.println("Attaching to remote server " + remoteServer + ", please wait..."); 175 agent.attach(remoteServer); 176 break; 177 } 178 } 179 catch (DebuggerException e) { 180 switch (debugeeType) { 181 case DEBUGEE_PID: 182 err.print("Error attaching to process: "); 183 break; 184 185 case DEBUGEE_CORE: 186 err.print("Error attaching to core file: "); 187 break; 188 189 case DEBUGEE_REMOTE: 190 err.print("Error attaching to remote server: "); 191 break; 192 } 193 if (e.getMessage() != null) { 194 err.print(e.getMessage()); 195 e.printStackTrace(); 196 } 197 err.println(); 198 return; 199 } 200 201 err.println("Debugger attached successfully."); 202 startInternal(); 203 } 204 205 // When using an existing JVMDebugger. 206 public void start() { 207 208 if (jvmDebugger == null) { 209 throw new RuntimeException("Tool.start() called with no JVMDebugger set."); 210 } 211 agent = new HotSpotAgent(); 212 agent.attach(jvmDebugger); 213 startInternal(); 214 } 215 216 // Remains of the start mechanism, common to both start methods. 217 private void startInternal() { 218 219 PrintStream err = System.err; 220 VM vm = VM.getVM(); 221 if (vm.isCore()) { 222 err.println("Core build detected."); 223 } else if (vm.isClientCompiler()) { 224 err.println("Client compiler detected."); 225 } else if (vm.isServerCompiler()) { 226 err.println("Server compiler detected."); 227 } else { 228 throw new RuntimeException("Fatal error: " 229 + "should have been able to detect core/C1/C2 build"); 230 } 231 232 String version = vm.getVMRelease(); 233 if (version != null) { 234 err.print("JVM version is "); 235 err.println(version); 236 } 237 238 run(); 239 } 240 }