30 import java.io.InputStream; |
30 import java.io.InputStream; |
31 |
31 |
32 import com.sun.tools.attach.VirtualMachine; |
32 import com.sun.tools.attach.VirtualMachine; |
33 |
33 |
34 import sun.tools.attach.HotSpotVirtualMachine; |
34 import sun.tools.attach.HotSpotVirtualMachine; |
35 import jdk.internal.vm.agent.spi.ToolProvider; |
|
36 import jdk.internal.vm.agent.spi.ToolProviderFinder; |
|
37 |
35 |
38 /* |
36 /* |
39 * This class is the main class for the JInfo utility. It parses its arguments |
37 * This class is the main class for the JInfo utility. It parses its arguments |
40 * and decides if the command should be satisfied using the VM attach mechanism |
38 * and decides if the command should be satisfied using the VM attach mechanism |
41 * or an SA tool. |
39 * or an SA tool. |
42 */ |
40 */ |
43 final public class JInfo { |
41 final public class JInfo { |
44 private static final String SA_JINFO_TOOL_NAME = "jinfo"; |
42 |
45 private boolean useSA = false; |
43 public static void main(String[] args) throws Exception { |
46 private String[] args = null; |
|
47 |
|
48 private JInfo(String[] args) throws IllegalArgumentException { |
|
49 if (args.length == 0) { |
44 if (args.length == 0) { |
50 throw new IllegalArgumentException(); |
45 usage(1); // no arguments |
51 } |
46 } |
52 |
47 checkForUnsupportedOptions(args); |
53 int argCopyIndex = 0; |
48 |
54 // First determine if we should launch SA or not |
49 boolean doFlag = false; |
55 if (args[0].equals("-F")) { |
50 boolean doFlags = false; |
56 // delete the -F |
51 boolean doSysprops = false; |
57 argCopyIndex = 1; |
52 |
58 useSA = true; |
53 // Parse the options (arguments starting with "-" ) |
59 } else if (args[0].equals("-flags") |
54 int optionCount = 0; |
60 || args[0].equals("-sysprops")) |
55 while (optionCount < args.length) { |
61 { |
56 String arg = args[optionCount]; |
62 if (args.length == 2) { |
57 if (!arg.startsWith("-")) { |
63 if (!isPid(args[1])) { |
58 break; |
64 // If args[1] doesn't parse to a number then |
59 } |
65 // it must be the SA debug server |
60 |
66 // (otherwise it is the pid) |
61 optionCount++; |
67 useSA = true; |
62 |
68 } |
63 if (arg.equals("-help") || arg.equals("-h")) { |
69 } else if (args.length == 3) { |
64 usage(0); |
70 // arguments include an executable and a core file |
65 } |
71 useSA = true; |
66 |
72 } else { |
67 if (arg.equals("-flag")) { |
73 throw new IllegalArgumentException(); |
68 doFlag = true; |
74 } |
69 continue; |
75 } else if (!args[0].startsWith("-")) { |
70 } |
76 if (args.length == 2) { |
71 |
77 // the only arguments are an executable and a core file |
72 if (arg.equals("-flags")) { |
78 useSA = true; |
73 doFlags = true; |
79 } else if (args.length == 1) { |
74 continue; |
80 if (!isPid(args[0])) { |
75 } |
81 // The only argument is not a PID; it must be SA debug |
76 |
82 // server |
77 if (arg.equals("-sysprops")) { |
83 useSA = true; |
78 doSysprops = true; |
84 } |
79 continue; |
85 } else { |
80 } |
86 throw new IllegalArgumentException(); |
81 } |
87 } |
82 |
88 } else if (args[0].equals("-h") || args[0].equals("-help")) { |
83 // Next we check the parameter count. -flag allows extra parameters |
89 if (args.length > 1) { |
84 int paramCount = args.length - optionCount; |
90 throw new IllegalArgumentException(); |
85 if ((doFlag && paramCount != 2) || (paramCount != 1)) { |
91 } |
|
92 } else if (args[0].equals("-flag")) { |
|
93 if (args.length == 3) { |
|
94 if (!isPid(args[2])) { |
|
95 throw new IllegalArgumentException(); |
|
96 } |
|
97 } else { |
|
98 throw new IllegalArgumentException(); |
|
99 } |
|
100 } else { |
|
101 throw new IllegalArgumentException(); |
|
102 } |
|
103 |
|
104 this.args = Arrays.copyOfRange(args, argCopyIndex, args.length); |
|
105 } |
|
106 |
|
107 @SuppressWarnings("fallthrough") |
|
108 private void execute() throws Exception { |
|
109 if (args[0].equals("-h") |
|
110 || args[0].equals("-help")) { |
|
111 usage(0); |
|
112 } |
|
113 |
|
114 if (useSA) { |
|
115 // SA only supports -flags or -sysprops |
|
116 if (args[0].startsWith("-")) { |
|
117 if (!(args[0].equals("-flags") || args[0].equals("-sysprops"))) { |
|
118 usage(1); |
|
119 } |
|
120 } |
|
121 |
|
122 // invoke SA which does it's own argument parsing |
|
123 runTool(); |
|
124 |
|
125 } else { |
|
126 // Now we can parse arguments for the non-SA case |
|
127 String pid = null; |
|
128 |
|
129 switch(args[0]) { |
|
130 case "-flag": |
|
131 if (args.length != 3) { |
|
132 usage(1); |
|
133 } |
|
134 String option = args[1]; |
|
135 pid = args[2]; |
|
136 flag(pid, option); |
|
137 break; |
|
138 case "-flags": |
|
139 if (args.length != 2) { |
|
140 usage(1); |
|
141 } |
|
142 pid = args[1]; |
|
143 flags(pid); |
|
144 break; |
|
145 case "-sysprops": |
|
146 if (args.length != 2) { |
|
147 usage(1); |
|
148 } |
|
149 pid = args[1]; |
|
150 sysprops(pid); |
|
151 break; |
|
152 case "-help": |
|
153 case "-h": |
|
154 usage(0); |
|
155 // Fall through |
|
156 default: |
|
157 if (args.length == 1) { |
|
158 // no flags specified, we do -sysprops and -flags |
|
159 pid = args[0]; |
|
160 sysprops(pid); |
|
161 System.out.println(); |
|
162 flags(pid); |
|
163 System.out.println(); |
|
164 commandLine(pid); |
|
165 } else { |
|
166 usage(1); |
|
167 } |
|
168 } |
|
169 } |
|
170 } |
|
171 |
|
172 public static void main(String[] args) throws Exception { |
|
173 JInfo jinfo = null; |
|
174 try { |
|
175 jinfo = new JInfo(args); |
|
176 jinfo.execute(); |
|
177 } catch (IllegalArgumentException e) { |
|
178 usage(1); |
86 usage(1); |
179 } |
87 } |
180 } |
88 |
181 |
89 if (!doFlag && !doFlags && !doSysprops) { |
182 private static boolean isPid(String arg) { |
90 // Print flags and sysporps if no options given |
183 return arg.matches("[0-9]+"); |
91 sysprops(args[optionCount]); |
184 } |
92 System.out.println(); |
185 |
93 flags(args[optionCount]); |
186 // Invoke SA tool with the given arguments |
94 System.out.println(); |
187 private void runTool() throws Exception { |
95 commandLine(args[optionCount]); |
188 ToolProvider tool = ToolProviderFinder.find(SA_JINFO_TOOL_NAME); |
96 } |
189 if (tool == null) { |
97 |
190 usage(1); |
98 if (doFlag) { |
191 } |
99 flag(args[optionCount+1], args[optionCount]); |
192 tool.run(args); |
100 } |
|
101 else { |
|
102 if (doFlags) { |
|
103 flags(args[optionCount]); |
|
104 } |
|
105 else if (doSysprops) { |
|
106 sysprops(args[optionCount]); |
|
107 } |
|
108 } |
193 } |
109 } |
194 |
110 |
195 private static void flag(String pid, String option) throws IOException { |
111 private static void flag(String pid, String option) throws IOException { |
196 HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid); |
112 HotSpotVirtualMachine vm = (HotSpotVirtualMachine) attach(pid); |
197 String flag; |
113 String flag; |
272 } while (n > 0); |
188 } while (n > 0); |
273 in.close(); |
189 in.close(); |
274 vm.detach(); |
190 vm.detach(); |
275 } |
191 } |
276 |
192 |
277 |
193 private static void checkForUnsupportedOptions(String[] args) { |
278 // print usage message |
194 // Check arguments for -F, and non-numeric value |
|
195 // and warn the user that SA is not supported anymore |
|
196 |
|
197 int paramCount = 0; |
|
198 |
|
199 for (String s : args) { |
|
200 if (s.equals("-F")) { |
|
201 SAOptionError("-F option used"); |
|
202 } |
|
203 |
|
204 if (! s.startsWith("-")) { |
|
205 if (! s.matches("[0-9]+")) { |
|
206 SAOptionError("non PID argument"); |
|
207 } |
|
208 paramCount += 1; |
|
209 } |
|
210 } |
|
211 |
|
212 if (paramCount > 1) { |
|
213 SAOptionError("More than one non-option argument"); |
|
214 } |
|
215 } |
|
216 |
|
217 private static void SAOptionError(String msg) { |
|
218 System.err.println("Error: " + msg); |
|
219 System.err.println("Cannot connect to core dump or remote debug server. Use jhsdb jinfo instead"); |
|
220 System.exit(1); |
|
221 } |
|
222 |
|
223 // print usage message |
279 private static void usage(int exit) { |
224 private static void usage(int exit) { |
280 boolean usageSA = ToolProviderFinder.find(SA_JINFO_TOOL_NAME) != null; |
|
281 |
|
282 System.err.println("Usage:"); |
225 System.err.println("Usage:"); |
283 if (usageSA) { |
226 System.err.println(" jinfo <option> <pid>"); |
284 System.err.println(" jinfo [option] <pid>"); |
227 System.err.println(" (to connect to a running process)"); |
285 System.err.println(" (to connect to a running process)"); |
228 System.err.println(""); |
286 System.err.println(" jinfo -F [option] <pid>"); |
229 System.err.println("where <option> is one of:"); |
287 System.err.println(" (to connect to a hung process)"); |
230 System.err.println(" -flag <name> to print the value of the named VM flag"); |
288 System.err.println(" jinfo [option] <executable> <core>"); |
231 System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag"); |
289 System.err.println(" (to connect to a core file)"); |
232 System.err.println(" -flag <name>=<value> to set the named VM flag to the given value"); |
290 System.err.println(" jinfo [option] [server_id@]<remote server IP or hostname>"); |
233 System.err.println(" -flags to print VM flags"); |
291 System.err.println(" (to connect to remote debug server)"); |
234 System.err.println(" -sysprops to print Java system properties"); |
292 System.err.println(""); |
235 System.err.println(" <no option> to print both VM flags and system properties"); |
293 System.err.println("where <option> is one of:"); |
236 System.err.println(" -h | -help to print this help message"); |
294 System.err.println(" for running processes:"); |
|
295 System.err.println(" -flag <name> to print the value of the named VM flag"); |
|
296 System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag"); |
|
297 System.err.println(" -flag <name>=<value> to set the named VM flag to the given value"); |
|
298 System.err.println(" for running or hung processes and core files:"); |
|
299 System.err.println(" -flags to print VM flags"); |
|
300 System.err.println(" -sysprops to print Java system properties"); |
|
301 System.err.println(" <no option> to print both VM flags and system properties"); |
|
302 System.err.println(" -h | -help to print this help message"); |
|
303 } else { |
|
304 System.err.println(" jinfo <option> <pid>"); |
|
305 System.err.println(" (to connect to a running process)"); |
|
306 System.err.println(""); |
|
307 System.err.println("where <option> is one of:"); |
|
308 System.err.println(" -flag <name> to print the value of the named VM flag"); |
|
309 System.err.println(" -flag [+|-]<name> to enable or disable the named VM flag"); |
|
310 System.err.println(" -flag <name>=<value> to set the named VM flag to the given value"); |
|
311 System.err.println(" -flags to print VM flags"); |
|
312 System.err.println(" -sysprops to print Java system properties"); |
|
313 System.err.println(" <no option> to print both VM flags and system properties"); |
|
314 System.err.println(" -h | -help to print this help message"); |
|
315 } |
|
316 |
|
317 System.exit(exit); |
237 System.exit(exit); |
318 } |
238 } |
319 } |
239 } |