blob: c10bad9284388c1519f6be9fc2f32f6a4d17d0d8 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2006 Sun Microsystems, Inc. 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. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package sun.tools.jinfo;
27
28import java.lang.reflect.Method;
29import java.io.File;
30import java.io.IOException;
31import java.io.InputStream;
32
33import com.sun.tools.attach.VirtualMachine;
34import sun.tools.attach.HotSpotVirtualMachine;
35
36/*
37 * This class is the main class for the JInfo utility. It parses its arguments
38 * and decides if the command should be satisifed using the VM attach mechanism
39 * or an SA tool. At this time the only option that uses the VM attach
40 * mechanism is the -flag option to set or print a command line option of a
41 * running application. All other options are mapped to SA tools.
42 */
43public class JInfo {
44
45 public static void main(String[] args) throws Exception {
46 if (args.length == 0) {
47 usage(); // no arguments
48 }
49
50 boolean useSA = true;
51 String arg1 = args[0];
52 if (arg1.startsWith("-")) {
53 if (arg1.equals("-flags") ||
54 arg1.equals("-sysprops")) {
55 // SA JInfo needs <pid> or <server> or
56 // (<executable> and <code file>). So, total
57 // argument count including option has to 2 or 3.
58 if (args.length != 2 && args.length != 3) {
59 usage();
60 }
61 } else if (arg1.equals("-flag")) {
62 // do not use SA, use attach-on-demand
63 useSA = false;
64 } else {
65 // unknown option or -h or -help, print help
66 usage();
67 }
68 }
69
70 if (useSA) {
71 runTool(args);
72 } else {
73 if (args.length == 3) {
74 String pid = args[2];
75 String option = args[1];
76 flag(pid, option);
77 } else {
78 usage();
79 }
80 }
81 }
82
83 // Invoke SA tool with the given arguments
84 private static void runTool(String args[]) throws Exception {
85 String tool = "sun.jvm.hotspot.tools.JInfo";
86 // Tool not available on this platform.
87 Class<?> c = loadClass(tool);
88 if (c == null) {
89 usage();
90 }
91
92 // invoke the main method with the arguments
93 Class[] argTypes = { String[].class } ;
94 Method m = c.getDeclaredMethod("main", argTypes);
95
96 Object[] invokeArgs = { args };
97 m.invoke(null, invokeArgs);
98 }
99
100 // loads the given class using the system class loader
101 private static Class loadClass(String name) {
102 //
103 // We specify the system clas loader so as to cater for development
104 // environments where this class is on the boot class path but sa-jdi.jar
105 // is on the system class path. Once the JDK is deployed then both
106 // tools.jar and sa-jdi.jar are on the system class path.
107 //
108 try {
109 return Class.forName(name, true,
110 ClassLoader.getSystemClassLoader());
111 } catch (Exception x) { }
112 return null;
113 }
114
115 private static void flag(String pid, String option) throws IOException {
116 VirtualMachine vm = attach(pid);
117 String flag;
118 InputStream in;
119 int index = option.indexOf('=');
120 if (index != -1) {
121 flag = option.substring(0, index);
122 String value = option.substring(index + 1);
123 in = ((HotSpotVirtualMachine)vm).setFlag(flag, value);
124 } else {
125 char c = option.charAt(0);
126 switch (c) {
127 case '+':
128 flag = option.substring(1);
129 in = ((HotSpotVirtualMachine)vm).setFlag(flag, "1");
130 break;
131 case '-':
132 flag = option.substring(1);
133 in = ((HotSpotVirtualMachine)vm).setFlag(flag, "0");
134 break;
135 default:
136 flag = option;
137 in = ((HotSpotVirtualMachine)vm).printFlag(flag);
138 break;
139 }
140 }
141
142 drain(vm, in);
143 }
144
145 // Attach to <pid>, exiting if we fail to attach
146 private static VirtualMachine attach(String pid) {
147 try {
148 return VirtualMachine.attach(pid);
149 } catch (Exception x) {
150 String msg = x.getMessage();
151 if (msg != null) {
152 System.err.println(pid + ": " + msg);
153 } else {
154 x.printStackTrace();
155 }
156 System.exit(1);
157 return null; // keep compiler happy
158 }
159 }
160
161 // Read the stream from the target VM until EOF, then detach
162 private static void drain(VirtualMachine vm, InputStream in) throws IOException {
163 // read to EOF and just print output
164 byte b[] = new byte[256];
165 int n;
166 do {
167 n = in.read(b);
168 if (n > 0) {
169 String s = new String(b, 0, n, "UTF-8");
170 System.out.print(s);
171 }
172 } while (n > 0);
173 in.close();
174 vm.detach();
175 }
176
177
178 // print usage message
179 private static void usage() {
180
181 Class c = loadClass("sun.jvm.hotspot.tools.JInfo");
182 boolean usageSA = (c != null);
183
184 System.out.println("Usage:");
185 if (usageSA) {
186 System.out.println(" jinfo [option] <pid>");
187 System.out.println(" (to connect to running process)");
188 System.out.println(" jinfo [option] <executable <core>");
189 System.out.println(" (to connect to a core file)");
190 System.out.println(" jinfo [option] [server_id@]<remote server IP or hostname>");
191 System.out.println(" (to connect to remote debug server)");
192 System.out.println("");
193 System.out.println("where <option> is one of:");
194 System.out.println(" -flag <name> to print the value of the named VM flag");
195 System.out.println(" -flag [+|-]<name> to enable or disable the named VM flag");
196 System.out.println(" -flag <name>=<value> to set the named VM flag to the given value");
197 System.out.println(" -flags to print VM flags");
198 System.out.println(" -sysprops to print Java system properties");
199 System.out.println(" <no option> to print both of the above");
200 System.out.println(" -h | -help to print this help message");
201 } else {
202 System.out.println(" jinfo <option> <pid>");
203 System.out.println(" (to connect to a running process)");
204 System.out.println("");
205 System.out.println("where <option> is one of:");
206 System.out.println(" -flag <name> to print the value of the named VM flag");
207 System.out.println(" -flag [+|-]<name> to enable or disable the named VM flag");
208 System.out.println(" -flag <name>=<value> to set the named VM flag to the given value");
209 System.out.println(" -h | -help to print this help message");
210 }
211
212 System.exit(1);
213 }
214}