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 30 import sun.jvm.hotspot.*; 31 import sun.jvm.hotspot.runtime.*; 32 import sun.jvm.hotspot.debugger.*; 33 34 // generic command line or GUI tool. 35 // override run & code main as shown below. 36 37 public abstract class Tool implements Runnable { 38 private HotSpotAgent agent; 39 private JVMDebugger jvmDebugger; 40 private int debugeeType; 41 42 // debugeeType is one of constants below 43 protected static final int DEBUGEE_PID = 0; 44 protected static final int DEBUGEE_CORE = 1; 45 protected static final int DEBUGEE_REMOTE = 2; 46 47 public Tool() { 48 } 49 50 public Tool(JVMDebugger d) { 51 jvmDebugger = d; 52 } 53 54 public String getName() { 55 return getClass().getName(); 56 } 57 58 protected boolean needsJavaPrefix() { 59 return true; 60 } 61 62 protected void setAgent(HotSpotAgent a) { 63 agent = a; 64 } 65 66 protected void setDebugeeType(int dt) { 67 debugeeType = dt; 68 } 69 70 protected HotSpotAgent getAgent() { 71 return agent; 72 } 73 74 protected int getDebugeeType() { 75 return debugeeType; 76 } 77 78 protected void printUsage() { 79 String name = null; 80 if (needsJavaPrefix()) { 81 name = "java " + getName(); 82 } else { 83 name = getName(); 84 } 85 System.out.println("Usage: " + name + " [option] <pid>"); 86 System.out.println("\t\t(to connect to a live java process)"); 87 System.out.println(" or " + name + " [option] <executable> <core>"); 88 System.out.println("\t\t(to connect to a core file)"); 89 System.out.println(" or " + name + " [option] [server_id@]<remote server IP or hostname>"); 90 System.out.println("\t\t(to connect to a remote debug server)"); 91 System.out.println(); 92 System.out.println("where option must be one of:"); 93 printFlagsUsage(); 94 } 95 96 protected void printFlagsUsage() { 97 System.out.println(" -h | -help\tto print this help message"); 98 } 99 100 protected void usage() { 101 printUsage(); 102 } 103 104 /* 105 Derived class main should be of the following form: 106 107 public static void main(String[] args) { 108 <derived class> obj = new <derived class>; 109 obj.execute(args); 110 } 111 112 */ 113 114 protected void execute(String[] args) { 115 int returnStatus = 1; 116 117 try { 118 returnStatus = start(args); 119 } finally { 120 stop(); 121 } 122 123 // Exit with 0 or 1 124 System.exit(returnStatus); 125 } 126 127 public void stop() { 128 if (agent != null) { 129 agent.detach(); 130 } 131 } 132 133 private int start(String[] args) { 134 135 if ((args.length < 1) || (args.length > 2)) { 136 usage(); 137 return 1; 138 } 139 140 // Attempt to handle -h or -help or some invalid flag 141 if (args[0].startsWith("-h")) { 142 usage(); 143 return 0; 144 } else if (args[0].startsWith("-")) { 145 usage(); 146 return 1; 147 } 148 149 PrintStream err = System.err; 150 151 int pid = 0; 152 String coreFileName = null; 153 String executableName = null; 154 String remoteServer = null; 155 156 switch (args.length) { 157 case 1: 158 try { 159 pid = Integer.parseInt(args[0]); 160 debugeeType = DEBUGEE_PID; 161 } catch (NumberFormatException e) { 162 // try remote server 163 remoteServer = args[0]; 164 debugeeType = DEBUGEE_REMOTE; 165 } 166 break; 167 168 case 2: 169 executableName = args[0]; 170 coreFileName = args[1]; 171 debugeeType = DEBUGEE_CORE; 172 break; 173 174 default: 175 usage(); 176 return 1; 177 } 178 179 agent = new HotSpotAgent(); 180 try { 181 switch (debugeeType) { 182 case DEBUGEE_PID: 183 err.println("Attaching to process ID " + pid + ", please wait..."); 184 agent.attach(pid); 185 break; 186 187 case DEBUGEE_CORE: 188 err.println("Attaching to core " + coreFileName + 189 " from executable " + executableName + ", please wait..."); 190 agent.attach(executableName, coreFileName); 191 break; 192 193 case DEBUGEE_REMOTE: 194 err.println("Attaching to remote server " + remoteServer + ", please wait..."); 195 agent.attach(remoteServer); 196 break; 197 } 198 } 199 catch (DebuggerException e) { 200 switch (debugeeType) { 201 case DEBUGEE_PID: 202 err.print("Error attaching to process: "); 203 break; 204 205 case DEBUGEE_CORE: 206 err.print("Error attaching to core file: "); 207 break; 208 209 case DEBUGEE_REMOTE: 210 err.print("Error attaching to remote server: "); 211 break; 212 } 213 if (e.getMessage() != null) { 214 err.println(e.getMessage()); 215 e.printStackTrace(); 216 } 217 err.println(); 218 return 1; 219 } 220 221 err.println("Debugger attached successfully."); 222 startInternal(); 223 return 0; 224 } 225 226 // When using an existing JVMDebugger. 227 public void start() { 228 229 if (jvmDebugger == null) { 230 throw new RuntimeException("Tool.start() called with no JVMDebugger set."); 231 } 232 agent = new HotSpotAgent(); 233 agent.attach(jvmDebugger); 234 startInternal(); 235 } 236 237 // Remains of the start mechanism, common to both start methods. 238 private void startInternal() { 239 240 PrintStream err = System.err; 241 VM vm = VM.getVM(); 242 if (vm.isCore()) { 243 err.println("Core build detected."); 244 } else if (vm.isClientCompiler()) { 245 err.println("Client compiler detected."); 246 } else if (vm.isServerCompiler()) { 247 err.println("Server compiler detected."); 248 } else { 249 throw new RuntimeException("Fatal error: " 250 + "should have been able to detect core/C1/C2 build"); 251 } 252 253 String version = vm.getVMRelease(); 254 if (version != null) { 255 err.print("JVM version is "); 256 err.println(version); 257 } 258 259 run(); 260 } 261 }