Mercurial > hg > truffle
annotate agent/test/jdi/VMConnection.java @ 18714:b56e88144e0a
prefer exact class matches when searching for unit tests with method name
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Wed, 17 Dec 2014 20:00:44 -0800 |
parents | c18cbe5936b8 |
children |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2002, Oracle and/or its affiliates. All rights reserved. |
0 | 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 * | |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
20 * or visit www.oracle.com if you need additional information or have any |
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
21 * questions. |
0 | 22 * |
23 */ | |
24 | |
25 import com.sun.jdi.*; | |
26 import com.sun.jdi.connect.*; | |
27 import com.sun.jdi.request.EventRequestManager; | |
28 | |
29 import java.util.*; | |
30 import java.io.*; | |
31 | |
32 | |
33 /** | |
34 * Manages a VM conection for the JDI test framework. | |
35 */ | |
36 class VMConnection { | |
37 private VirtualMachine vm; | |
38 private Process process = null; | |
39 private int outputCompleteCount = 0; | |
40 | |
41 private final Connector connector; | |
42 private final Map connectorArgs; | |
43 private final int traceFlags; | |
44 | |
45 /** | |
46 * Return a String containing VM Options to pass to the debugee | |
47 * or an empty string if there are none. | |
48 * These are read from the first non-comment line | |
49 * in file test/com/sun/jdi/@debuggeeVMOptions. | |
50 */ | |
51 static public String getDebuggeeVMOptions() { | |
52 | |
53 // When we run under jtreg, test.src contains the pathname of | |
54 // the test/com/sun/jdi dir. | |
55 BufferedReader reader; | |
56 final String filename = "@debuggeeVMOptions"; | |
57 String srcDir = System.getProperty("test.src"); | |
58 | |
59 if (srcDir == null) { | |
60 srcDir = System.getProperty("user.dir"); | |
61 } | |
62 srcDir = srcDir + File.separator; | |
63 | |
64 File myDir = new File(srcDir); | |
65 | |
66 File myFile = new File(myDir, filename); | |
67 if (!myFile.canRead()) { | |
68 try { | |
69 // We have some subdirs of test/com/sun/jdi so in case we | |
70 // are in one of them, look in our parent dir for the file. | |
71 myFile = new File(myDir.getCanonicalFile().getParent(), | |
72 filename); | |
73 if (!myFile.canRead()) { | |
74 return ""; | |
75 } | |
76 } catch (IOException ee) { | |
77 System.out.println("-- Error 1 trying to access file " + | |
78 myFile.getPath() + ": " + ee); | |
79 return ""; | |
80 } | |
81 } | |
82 String wholePath = myFile.getPath(); | |
83 try { | |
84 reader = new BufferedReader(new FileReader(myFile)); | |
85 } catch (FileNotFoundException ee) { | |
86 System.out.println("-- Error 2 trying to access file " + | |
87 wholePath + ": " + ee); | |
88 return ""; | |
89 } | |
90 | |
91 String line; | |
92 String retVal = ""; | |
93 while (true) { | |
94 try { | |
95 line = reader.readLine(); | |
96 } catch (IOException ee) { | |
97 System.out.println("-- Error reading options from file " + | |
98 wholePath + ": " + ee); | |
99 break; | |
100 } | |
101 if (line == null) { | |
102 System.out.println("-- No debuggee VM options found in file " + | |
103 wholePath); | |
104 break; | |
105 } | |
106 line = line.trim(); | |
107 if (line.length() != 0 && !line.startsWith("#")) { | |
108 System.out.println("-- Added debuggeeVM options from file " + | |
109 wholePath + ": " + line); | |
110 retVal = line; | |
111 break; | |
112 } | |
113 // Else, read he next line. | |
114 } | |
115 try { | |
116 reader.close(); | |
117 } catch (IOException ee) { | |
118 } | |
119 return retVal; | |
120 } | |
121 | |
122 private Connector findConnector(String name) { | |
123 List connectors = Bootstrap.virtualMachineManager().allConnectors(); | |
124 Iterator iter = connectors.iterator(); | |
125 while (iter.hasNext()) { | |
126 Connector connector = (Connector)iter.next(); | |
127 if (connector.name().equals(name)) { | |
128 return connector; | |
129 } | |
130 } | |
131 return null; | |
132 } | |
133 | |
134 private Map parseConnectorArgs(Connector connector, String argString) { | |
135 StringTokenizer tokenizer = new StringTokenizer(argString, ","); | |
136 Map arguments = connector.defaultArguments(); | |
137 | |
138 while (tokenizer.hasMoreTokens()) { | |
139 String token = tokenizer.nextToken(); | |
140 int index = token.indexOf('='); | |
141 if (index == -1) { | |
142 throw new IllegalArgumentException("Illegal connector argument: " + | |
143 token); | |
144 } | |
145 String name = token.substring(0, index); | |
146 String value = token.substring(index + 1); | |
147 Connector.Argument argument = (Connector.Argument)arguments.get(name); | |
148 if (argument == null) { | |
149 throw new IllegalArgumentException("Argument " + name + | |
150 "is not defined for connector: " + | |
151 connector.name()); | |
152 } | |
153 argument.setValue(value); | |
154 } | |
155 return arguments; | |
156 } | |
157 | |
158 VMConnection(String connectSpec, int traceFlags) { | |
159 String nameString; | |
160 String argString; | |
161 int index = connectSpec.indexOf(':'); | |
162 if (index == -1) { | |
163 nameString = connectSpec; | |
164 argString = ""; | |
165 } else { | |
166 nameString = connectSpec.substring(0, index); | |
167 argString = connectSpec.substring(index + 1); | |
168 } | |
169 | |
170 connector = findConnector(nameString); | |
171 if (connector == null) { | |
172 throw new IllegalArgumentException("No connector named: " + | |
173 nameString); | |
174 } | |
175 | |
176 connectorArgs = parseConnectorArgs(connector, argString); | |
177 this.traceFlags = traceFlags; | |
178 } | |
179 | |
180 synchronized VirtualMachine open() { | |
181 if (connector instanceof LaunchingConnector) { | |
182 vm = launchTarget(); | |
183 } else if (connector instanceof AttachingConnector) { | |
184 vm = attachTarget(); | |
185 } else if (connector instanceof ListeningConnector) { | |
186 vm = listenTarget(); | |
187 } else { | |
188 throw new InternalError("Invalid connect type"); | |
189 } | |
190 vm.setDebugTraceMode(traceFlags); | |
191 System.out.println("JVM version:" + vm.version()); | |
192 System.out.println("JDI version: " + Bootstrap.virtualMachineManager().majorInterfaceVersion() + | |
193 "." + Bootstrap.virtualMachineManager().minorInterfaceVersion()); | |
194 System.out.println("JVM description: " + vm.description()); | |
195 | |
196 return vm; | |
197 } | |
198 | |
199 boolean setConnectorArg(String name, String value) { | |
200 /* | |
201 * Too late if the connection already made | |
202 */ | |
203 if (vm != null) { | |
204 return false; | |
205 } | |
206 | |
207 Connector.Argument argument = (Connector.Argument)connectorArgs.get(name); | |
208 if (argument == null) { | |
209 return false; | |
210 } | |
211 argument.setValue(value); | |
212 return true; | |
213 } | |
214 | |
215 String connectorArg(String name) { | |
216 Connector.Argument argument = (Connector.Argument)connectorArgs.get(name); | |
217 if (argument == null) { | |
218 return ""; | |
219 } | |
220 return argument.value(); | |
221 } | |
222 | |
223 public synchronized VirtualMachine vm() { | |
224 if (vm == null) { | |
225 throw new InternalError("VM not connected"); | |
226 } else { | |
227 return vm; | |
228 } | |
229 } | |
230 | |
231 boolean isOpen() { | |
232 return (vm != null); | |
233 } | |
234 | |
235 boolean isLaunch() { | |
236 return (connector instanceof LaunchingConnector); | |
237 } | |
238 | |
239 Connector connector() { | |
240 return connector; | |
241 } | |
242 | |
243 boolean isListen() { | |
244 return (connector instanceof ListeningConnector); | |
245 } | |
246 | |
247 boolean isAttach() { | |
248 return (connector instanceof AttachingConnector); | |
249 } | |
250 | |
251 private synchronized void notifyOutputComplete() { | |
252 outputCompleteCount++; | |
253 notifyAll(); | |
254 } | |
255 | |
256 private synchronized void waitOutputComplete() { | |
257 // Wait for stderr and stdout | |
258 if (process != null) { | |
259 while (outputCompleteCount < 2) { | |
260 try {wait();} catch (InterruptedException e) {} | |
261 } | |
262 } | |
263 } | |
264 | |
265 public void disposeVM() { | |
266 try { | |
267 if (vm != null) { | |
268 vm.dispose(); | |
269 vm = null; | |
270 } | |
271 } finally { | |
272 if (process != null) { | |
273 process.destroy(); | |
274 process = null; | |
275 } | |
276 waitOutputComplete(); | |
277 } | |
278 } | |
279 | |
280 private void dumpStream(InputStream stream) throws IOException { | |
281 PrintStream outStream = System.out; | |
282 BufferedReader in = | |
283 new BufferedReader(new InputStreamReader(stream)); | |
284 String line; | |
285 while ((line = in.readLine()) != null) { | |
286 outStream.println(line); | |
287 } | |
288 } | |
289 | |
290 /** | |
291 * Create a Thread that will retrieve and display any output. | |
292 * Needs to be high priority, else debugger may exit before | |
293 * it can be displayed. | |
294 */ | |
295 private void displayRemoteOutput(final InputStream stream) { | |
296 Thread thr = new Thread("output reader") { | |
297 public void run() { | |
298 try { | |
299 dumpStream(stream); | |
300 } catch (IOException ex) { | |
301 System.err.println("IOException reading output of child java interpreter:" | |
302 + ex.getMessage()); | |
303 } finally { | |
304 notifyOutputComplete(); | |
305 } | |
306 } | |
307 }; | |
308 thr.setPriority(Thread.MAX_PRIORITY-1); | |
309 thr.start(); | |
310 } | |
311 | |
312 private void dumpFailedLaunchInfo(Process process) { | |
313 try { | |
314 dumpStream(process.getErrorStream()); | |
315 dumpStream(process.getInputStream()); | |
316 } catch (IOException e) { | |
317 System.err.println("Unable to display process output: " + | |
318 e.getMessage()); | |
319 } | |
320 } | |
321 | |
322 /* launch child target vm */ | |
323 private VirtualMachine launchTarget() { | |
324 LaunchingConnector launcher = (LaunchingConnector)connector; | |
325 try { | |
326 VirtualMachine vm = launcher.launch(connectorArgs); | |
327 process = vm.process(); | |
328 displayRemoteOutput(process.getErrorStream()); | |
329 displayRemoteOutput(process.getInputStream()); | |
330 return vm; | |
331 } catch (IOException ioe) { | |
332 ioe.printStackTrace(); | |
333 System.err.println("\n Unable to launch target VM."); | |
334 } catch (IllegalConnectorArgumentsException icae) { | |
335 icae.printStackTrace(); | |
336 System.err.println("\n Internal debugger error."); | |
337 } catch (VMStartException vmse) { | |
338 System.err.println(vmse.getMessage() + "\n"); | |
339 dumpFailedLaunchInfo(vmse.process()); | |
340 System.err.println("\n Target VM failed to initialize."); | |
341 } | |
342 return null; // Shuts up the compiler | |
343 } | |
344 | |
345 /* attach to running target vm */ | |
346 private VirtualMachine attachTarget() { | |
347 AttachingConnector attacher = (AttachingConnector)connector; | |
348 try { | |
349 return attacher.attach(connectorArgs); | |
350 } catch (IOException ioe) { | |
351 ioe.printStackTrace(); | |
352 System.err.println("\n Unable to attach to target VM."); | |
353 } catch (IllegalConnectorArgumentsException icae) { | |
354 icae.printStackTrace(); | |
355 System.err.println("\n Internal debugger error."); | |
356 } | |
357 return null; // Shuts up the compiler | |
358 } | |
359 | |
360 /* listen for connection from target vm */ | |
361 private VirtualMachine listenTarget() { | |
362 ListeningConnector listener = (ListeningConnector)connector; | |
363 try { | |
364 String retAddress = listener.startListening(connectorArgs); | |
365 System.out.println("Listening at address: " + retAddress); | |
366 vm = listener.accept(connectorArgs); | |
367 listener.stopListening(connectorArgs); | |
368 return vm; | |
369 } catch (IOException ioe) { | |
370 ioe.printStackTrace(); | |
371 System.err.println("\n Unable to attach to target VM."); | |
372 } catch (IllegalConnectorArgumentsException icae) { | |
373 icae.printStackTrace(); | |
374 System.err.println("\n Internal debugger error."); | |
375 } | |
376 return null; // Shuts up the compiler | |
377 } | |
378 } |