Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java @ 17716:cdb71841f4bc
6498581: ThreadInterruptTest3 produces wrong output on Windows
Summary: There is race condition between os::interrupt and os::is_interrupted on Windows. In JVM_Sleep(Thread.sleep), check if thread gets interrupted, it may see interrupted but not really interrupted so cause spurious waking up (early return from sleep). Fix by checking if interrupt event really gets set thus prevent false return. For intrinsic of _isInterrupted, on Windows, go fastpath only on bit not set.
Reviewed-by: acorn, kvn
Contributed-by: david.holmes@oracle.com, yumin.qi@oracle.com
author | minqi |
---|---|
date | Wed, 26 Feb 2014 15:20:41 -0800 |
parents | 38ea2efa32a7 |
children |
rev | line source |
---|---|
0 | 1 /* |
8750 | 2 * Copyright (c) 2000, 2013, 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 package sun.jvm.hotspot; | |
26 | |
10229 | 27 import java.rmi.RemoteException; |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
28 import java.lang.reflect.Constructor; |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
29 import java.lang.reflect.InvocationTargetException; |
10229 | 30 |
31 import sun.jvm.hotspot.debugger.Debugger; | |
32 import sun.jvm.hotspot.debugger.DebuggerException; | |
33 import sun.jvm.hotspot.debugger.JVMDebugger; | |
34 import sun.jvm.hotspot.debugger.MachineDescription; | |
35 import sun.jvm.hotspot.debugger.MachineDescriptionAMD64; | |
36 import sun.jvm.hotspot.debugger.MachineDescriptionIA64; | |
37 import sun.jvm.hotspot.debugger.MachineDescriptionIntelX86; | |
38 import sun.jvm.hotspot.debugger.MachineDescriptionSPARC32Bit; | |
39 import sun.jvm.hotspot.debugger.MachineDescriptionSPARC64Bit; | |
40 import sun.jvm.hotspot.debugger.NoSuchSymbolException; | |
41 import sun.jvm.hotspot.debugger.bsd.BsdDebuggerLocal; | |
42 import sun.jvm.hotspot.debugger.linux.LinuxDebuggerLocal; | |
43 import sun.jvm.hotspot.debugger.proc.ProcDebuggerLocal; | |
44 import sun.jvm.hotspot.debugger.remote.RemoteDebugger; | |
45 import sun.jvm.hotspot.debugger.remote.RemoteDebuggerClient; | |
46 import sun.jvm.hotspot.debugger.remote.RemoteDebuggerServer; | |
47 import sun.jvm.hotspot.debugger.windbg.WindbgDebuggerLocal; | |
48 import sun.jvm.hotspot.runtime.VM; | |
49 import sun.jvm.hotspot.types.TypeDataBase; | |
50 import sun.jvm.hotspot.utilities.PlatformInfo; | |
51 import sun.jvm.hotspot.utilities.UnsupportedPlatformException; | |
0 | 52 |
53 /** <P> This class wraps much of the basic functionality and is the | |
54 * highest-level factory for VM data structures. It makes it simple | |
55 * to start up the debugging system. </P> | |
56 * | |
57 * <P> FIXME: especially with the addition of remote debugging, this | |
58 * has turned into a mess; needs rethinking. </P> | |
59 */ | |
60 | |
61 public class HotSpotAgent { | |
62 private JVMDebugger debugger; | |
63 private MachineDescription machDesc; | |
64 private TypeDataBase db; | |
65 | |
66 private String os; | |
67 private String cpu; | |
68 | |
69 // The system can work in several ways: | |
70 // - Attaching to local process | |
71 // - Attaching to local core file | |
72 // - Connecting to remote debug server | |
73 // - Starting debug server for process | |
74 // - Starting debug server for core file | |
75 | |
76 // These are options for the "client" side of things | |
77 private static final int PROCESS_MODE = 0; | |
78 private static final int CORE_FILE_MODE = 1; | |
79 private static final int REMOTE_MODE = 2; | |
80 private int startupMode; | |
81 | |
82 // This indicates whether we are really starting a server or not | |
83 private boolean isServer; | |
84 | |
85 // All possible required information for connecting | |
86 private int pid; | |
87 private String javaExecutableName; | |
88 private String coreFileName; | |
89 private String debugServerID; | |
90 | |
91 // All needed information for server side | |
92 private String serverID; | |
93 | |
94 private String[] jvmLibNames; | |
95 | |
96 static void showUsage() { | |
97 } | |
98 | |
99 public HotSpotAgent() { | |
100 // for non-server add shutdown hook to clean-up debugger in case | |
101 // of forced exit. For remote server, shutdown hook is added by | |
102 // DebugServer. | |
103 Runtime.getRuntime().addShutdownHook(new java.lang.Thread( | |
104 new Runnable() { | |
105 public void run() { | |
106 synchronized (HotSpotAgent.this) { | |
107 if (!isServer) { | |
108 detach(); | |
109 } | |
110 } | |
111 } | |
112 })); | |
113 } | |
114 | |
115 //-------------------------------------------------------------------------------- | |
116 // Accessors (once the system is set up) | |
117 // | |
118 | |
119 public synchronized Debugger getDebugger() { | |
120 return debugger; | |
121 } | |
122 | |
123 public synchronized TypeDataBase getTypeDataBase() { | |
124 return db; | |
125 } | |
126 | |
127 //-------------------------------------------------------------------------------- | |
128 // Client-side operations | |
129 // | |
130 | |
131 /** This attaches to a process running on the local machine. */ | |
132 public synchronized void attach(int processID) | |
133 throws DebuggerException { | |
134 if (debugger != null) { | |
135 throw new DebuggerException("Already attached"); | |
136 } | |
137 pid = processID; | |
138 startupMode = PROCESS_MODE; | |
139 isServer = false; | |
140 go(); | |
141 } | |
142 | |
143 /** This opens a core file on the local machine */ | |
144 public synchronized void attach(String javaExecutableName, String coreFileName) | |
145 throws DebuggerException { | |
146 if (debugger != null) { | |
147 throw new DebuggerException("Already attached"); | |
148 } | |
149 if ((javaExecutableName == null) || (coreFileName == null)) { | |
150 throw new DebuggerException("Both the core file name and Java executable name must be specified"); | |
151 } | |
152 this.javaExecutableName = javaExecutableName; | |
153 this.coreFileName = coreFileName; | |
154 startupMode = CORE_FILE_MODE; | |
155 isServer = false; | |
156 go(); | |
157 } | |
158 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
159 /** This uses a JVMDebugger that is already attached to the core or process */ |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
160 public synchronized void attach(JVMDebugger d) |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
161 throws DebuggerException { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
162 debugger = d; |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
163 isServer = false; |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
164 go(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
165 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
166 |
0 | 167 /** This attaches to a "debug server" on a remote machine; this |
168 remote server has already attached to a process or opened a | |
169 core file and is waiting for RMI calls on the Debugger object to | |
170 come in. */ | |
171 public synchronized void attach(String remoteServerID) | |
172 throws DebuggerException { | |
173 if (debugger != null) { | |
174 throw new DebuggerException("Already attached to a process"); | |
175 } | |
176 if (remoteServerID == null) { | |
177 throw new DebuggerException("Debug server id must be specified"); | |
178 } | |
179 | |
180 debugServerID = remoteServerID; | |
181 startupMode = REMOTE_MODE; | |
182 isServer = false; | |
183 go(); | |
184 } | |
185 | |
186 /** This should only be called by the user on the client machine, | |
187 not the server machine */ | |
188 public synchronized boolean detach() throws DebuggerException { | |
189 if (isServer) { | |
190 throw new DebuggerException("Should not call detach() for server configuration"); | |
191 } | |
192 return detachInternal(); | |
193 } | |
194 | |
195 //-------------------------------------------------------------------------------- | |
196 // Server-side operations | |
197 // | |
198 | |
199 /** This attaches to a process running on the local machine and | |
200 starts a debug server, allowing remote machines to connect and | |
201 examine this process. Uses specified name to uniquely identify a | |
202 specific debuggee on the server */ | |
203 public synchronized void startServer(int processID, String uniqueID) { | |
204 if (debugger != null) { | |
205 throw new DebuggerException("Already attached"); | |
206 } | |
207 pid = processID; | |
208 startupMode = PROCESS_MODE; | |
209 isServer = true; | |
210 serverID = uniqueID; | |
211 go(); | |
212 } | |
213 | |
214 /** This attaches to a process running on the local machine and | |
215 starts a debug server, allowing remote machines to connect and | |
216 examine this process. */ | |
217 public synchronized void startServer(int processID) | |
218 throws DebuggerException { | |
219 startServer(processID, null); | |
220 } | |
221 | |
222 /** This opens a core file on the local machine and starts a debug | |
223 server, allowing remote machines to connect and examine this | |
224 core file. Uses supplied uniqueID to uniquely identify a specific | |
225 debugee */ | |
226 public synchronized void startServer(String javaExecutableName, | |
227 String coreFileName, | |
228 String uniqueID) { | |
229 if (debugger != null) { | |
230 throw new DebuggerException("Already attached"); | |
231 } | |
232 if ((javaExecutableName == null) || (coreFileName == null)) { | |
233 throw new DebuggerException("Both the core file name and Java executable name must be specified"); | |
234 } | |
235 this.javaExecutableName = javaExecutableName; | |
236 this.coreFileName = coreFileName; | |
237 startupMode = CORE_FILE_MODE; | |
238 isServer = true; | |
239 serverID = uniqueID; | |
240 go(); | |
241 } | |
242 | |
243 /** This opens a core file on the local machine and starts a debug | |
244 server, allowing remote machines to connect and examine this | |
245 core file. */ | |
246 public synchronized void startServer(String javaExecutableName, String coreFileName) | |
247 throws DebuggerException { | |
248 startServer(javaExecutableName, coreFileName, null); | |
249 } | |
250 | |
251 /** This may only be called on the server side after startServer() | |
252 has been called */ | |
253 public synchronized boolean shutdownServer() throws DebuggerException { | |
254 if (!isServer) { | |
255 throw new DebuggerException("Should not call shutdownServer() for client configuration"); | |
256 } | |
257 return detachInternal(); | |
258 } | |
259 | |
260 | |
261 //-------------------------------------------------------------------------------- | |
262 // Internals only below this point | |
263 // | |
264 | |
265 private boolean detachInternal() { | |
266 if (debugger == null) { | |
267 return false; | |
268 } | |
269 boolean retval = true; | |
270 if (!isServer) { | |
271 VM.shutdown(); | |
272 } | |
273 // We must not call detach() if we are a client and are connected | |
274 // to a remote debugger | |
275 Debugger dbg = null; | |
276 DebuggerException ex = null; | |
277 if (isServer) { | |
278 try { | |
279 RMIHelper.unbind(serverID); | |
280 } | |
281 catch (DebuggerException de) { | |
282 ex = de; | |
283 } | |
284 dbg = debugger; | |
285 } else { | |
286 if (startupMode != REMOTE_MODE) { | |
287 dbg = debugger; | |
288 } | |
289 } | |
290 if (dbg != null) { | |
291 retval = dbg.detach(); | |
292 } | |
293 | |
294 debugger = null; | |
295 machDesc = null; | |
296 db = null; | |
297 if (ex != null) { | |
298 throw(ex); | |
299 } | |
300 return retval; | |
301 } | |
302 | |
303 private void go() { | |
304 setupDebugger(); | |
305 setupVM(); | |
306 } | |
307 | |
308 private void setupDebugger() { | |
309 if (startupMode != REMOTE_MODE) { | |
310 // | |
311 // Local mode (client attaching to local process or setting up | |
312 // server, but not client attaching to server) | |
313 // | |
314 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
315 // Handle existing or alternate JVMDebugger: |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
316 // these will set os, cpu independently of our PlatformInfo implementation. |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
317 String alternateDebugger = System.getProperty("sa.altDebugger"); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
318 if (debugger != null) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
319 setupDebuggerExisting(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
320 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
321 } else if (alternateDebugger != null) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
322 setupDebuggerAlternate(alternateDebugger); |
0 | 323 |
324 } else { | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
325 // Otherwise, os, cpu are those of our current platform: |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
326 try { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
327 os = PlatformInfo.getOS(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
328 cpu = PlatformInfo.getCPU(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
329 } catch (UnsupportedPlatformException e) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
330 throw new DebuggerException(e); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
331 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
332 if (os.equals("solaris")) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
333 setupDebuggerSolaris(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
334 } else if (os.equals("win32")) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
335 setupDebuggerWin32(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
336 } else if (os.equals("linux")) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
337 setupDebuggerLinux(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
338 } else if (os.equals("bsd")) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
339 setupDebuggerBsd(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
340 } else if (os.equals("darwin")) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
341 setupDebuggerDarwin(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
342 } else { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
343 // Add support for more operating systems here |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
344 throw new DebuggerException("Operating system " + os + " not yet supported"); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
345 } |
0 | 346 } |
347 | |
348 if (isServer) { | |
349 RemoteDebuggerServer remote = null; | |
350 try { | |
351 remote = new RemoteDebuggerServer(debugger); | |
352 } | |
353 catch (RemoteException rem) { | |
354 throw new DebuggerException(rem); | |
355 } | |
356 RMIHelper.rebind(serverID, remote); | |
357 } | |
358 } else { | |
359 // | |
360 // Remote mode (client attaching to server) | |
361 // | |
362 | |
363 // Create and install a security manager | |
364 | |
365 // FIXME: currently commented out because we were having | |
366 // security problems since we're "in the sun.* hierarchy" here. | |
367 // Perhaps a permissive policy file would work around this. In | |
368 // the long run, will probably have to move into com.sun.*. | |
369 | |
370 // if (System.getSecurityManager() == null) { | |
371 // System.setSecurityManager(new RMISecurityManager()); | |
372 // } | |
373 | |
374 connectRemoteDebugger(); | |
375 } | |
376 } | |
377 | |
378 private void setupVM() { | |
379 // We need to instantiate a HotSpotTypeDataBase on both the client | |
380 // and server machine. On the server it is only currently used to | |
381 // configure the Java primitive type sizes (which we should | |
382 // consider making constant). On the client it is used to | |
383 // configure the VM. | |
384 | |
385 try { | |
386 if (os.equals("solaris")) { | |
387 db = new HotSpotTypeDataBase(machDesc, | |
388 new HotSpotSolarisVtblAccess(debugger, jvmLibNames), | |
389 debugger, jvmLibNames); | |
390 } else if (os.equals("win32")) { | |
391 db = new HotSpotTypeDataBase(machDesc, | |
392 new Win32VtblAccess(debugger, jvmLibNames), | |
393 debugger, jvmLibNames); | |
394 } else if (os.equals("linux")) { | |
395 db = new HotSpotTypeDataBase(machDesc, | |
396 new LinuxVtblAccess(debugger, jvmLibNames), | |
397 debugger, jvmLibNames); | |
3960 | 398 } else if (os.equals("bsd")) { |
399 db = new HotSpotTypeDataBase(machDesc, | |
400 new BsdVtblAccess(debugger, jvmLibNames), | |
401 debugger, jvmLibNames); | |
8750 | 402 } else if (os.equals("darwin")) { |
403 db = new HotSpotTypeDataBase(machDesc, | |
404 new BsdVtblAccess(debugger, jvmLibNames), | |
405 debugger, jvmLibNames); | |
0 | 406 } else { |
407 throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess yet)"); | |
408 } | |
409 } | |
410 catch (NoSuchSymbolException e) { | |
411 throw new DebuggerException("Doesn't appear to be a HotSpot VM (could not find symbol \"" + | |
412 e.getSymbol() + "\" in remote process)"); | |
413 } | |
414 | |
415 if (startupMode != REMOTE_MODE) { | |
416 // Configure the debugger with the primitive type sizes just obtained from the VM | |
417 debugger.configureJavaPrimitiveTypeSizes(db.getJBooleanType().getSize(), | |
418 db.getJByteType().getSize(), | |
419 db.getJCharType().getSize(), | |
420 db.getJDoubleType().getSize(), | |
421 db.getJFloatType().getSize(), | |
422 db.getJIntType().getSize(), | |
423 db.getJLongType().getSize(), | |
424 db.getJShortType().getSize()); | |
425 } | |
426 | |
427 if (!isServer) { | |
428 // Do not initialize the VM on the server (unnecessary, since it's | |
429 // instantiated on the client) | |
430 try { | |
431 VM.initialize(db, debugger); | |
432 } catch (DebuggerException e) { | |
433 throw (e); | |
434 } catch (Exception e) { | |
435 throw new DebuggerException(e); | |
436 } | |
437 } | |
438 } | |
439 | |
440 //-------------------------------------------------------------------------------- | |
441 // OS-specific debugger setup/connect routines | |
442 // | |
443 | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
444 // Use the existing JVMDebugger, as passed to our constructor. |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
445 // Retrieve os and cpu from that debugger, not the current platform. |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
446 private void setupDebuggerExisting() { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
447 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
448 os = debugger.getOS(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
449 cpu = debugger.getCPU(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
450 setupJVMLibNames(os); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
451 machDesc = debugger.getMachineDescription(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
452 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
453 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
454 // Given a classname, load an alternate implementation of JVMDebugger. |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
455 private void setupDebuggerAlternate(String alternateName) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
456 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
457 try { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
458 Class c = Class.forName(alternateName); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
459 Constructor cons = c.getConstructor(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
460 debugger = (JVMDebugger) cons.newInstance(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
461 attachDebugger(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
462 setupDebuggerExisting(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
463 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
464 } catch (ClassNotFoundException cnfe) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
465 throw new DebuggerException("Cannot find alternate SA Debugger: '" + alternateName + "'"); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
466 } catch (NoSuchMethodException nsme) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
467 throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' has missing constructor."); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
468 } catch (InstantiationException ie) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
469 throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", ie); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
470 } catch (IllegalAccessException iae) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
471 throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
472 } catch (InvocationTargetException iae) { |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
473 throw new DebuggerException("Alternate SA Debugger: '" + alternateName + "' fails to initialise: ", iae); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
474 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
475 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
476 System.err.println("Loaded alternate HotSpot SA Debugger: " + alternateName); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
477 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
478 |
0 | 479 // |
480 // Solaris | |
481 // | |
482 | |
483 private void setupDebuggerSolaris() { | |
484 setupJVMLibNamesSolaris(); | |
3939 | 485 ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true); |
486 debugger = dbg; | |
487 attachDebugger(); | |
0 | 488 |
3939 | 489 // Set up CPU-dependent stuff |
490 if (cpu.equals("x86")) { | |
491 machDesc = new MachineDescriptionIntelX86(); | |
492 } else if (cpu.equals("sparc")) { | |
493 int addressSize = dbg.getRemoteProcessAddressSize(); | |
494 if (addressSize == -1) { | |
495 throw new DebuggerException("Error occurred while trying to determine the remote process's " + | |
496 "address size"); | |
0 | 497 } |
498 | |
3939 | 499 if (addressSize == 32) { |
500 machDesc = new MachineDescriptionSPARC32Bit(); | |
501 } else if (addressSize == 64) { | |
502 machDesc = new MachineDescriptionSPARC64Bit(); | |
0 | 503 } else { |
3939 | 504 throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); |
0 | 505 } |
3939 | 506 } else if (cpu.equals("amd64")) { |
507 machDesc = new MachineDescriptionAMD64(); | |
508 } else { | |
509 throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64"); | |
510 } | |
0 | 511 |
3939 | 512 dbg.setMachineDescription(machDesc); |
513 return; | |
0 | 514 } |
515 | |
516 private void connectRemoteDebugger() throws DebuggerException { | |
517 RemoteDebugger remote = | |
518 (RemoteDebugger) RMIHelper.lookup(debugServerID); | |
519 debugger = new RemoteDebuggerClient(remote); | |
520 machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); | |
521 os = debugger.getOS(); | |
11054
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
522 setupJVMLibNames(os); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
523 cpu = debugger.getCPU(); |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
524 } |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
525 |
38ea2efa32a7
8010278: SA: provide mechanism for using an alternative SA debugger back-end.
kevinw
parents:
10229
diff
changeset
|
526 private void setupJVMLibNames(String os) { |
0 | 527 if (os.equals("solaris")) { |
528 setupJVMLibNamesSolaris(); | |
529 } else if (os.equals("win32")) { | |
530 setupJVMLibNamesWin32(); | |
531 } else if (os.equals("linux")) { | |
532 setupJVMLibNamesLinux(); | |
3960 | 533 } else if (os.equals("bsd")) { |
534 setupJVMLibNamesBsd(); | |
8750 | 535 } else if (os.equals("darwin")) { |
536 setupJVMLibNamesDarwin(); | |
0 | 537 } else { |
538 throw new RuntimeException("Unknown OS type"); | |
539 } | |
540 } | |
541 | |
542 private void setupJVMLibNamesSolaris() { | |
10229 | 543 jvmLibNames = new String[] { "libjvm.so" }; |
0 | 544 } |
545 | |
546 // | |
547 // Win32 | |
548 // | |
549 | |
550 private void setupDebuggerWin32() { | |
551 setupJVMLibNamesWin32(); | |
552 | |
553 if (cpu.equals("x86")) { | |
554 machDesc = new MachineDescriptionIntelX86(); | |
555 } else if (cpu.equals("amd64")) { | |
556 machDesc = new MachineDescriptionAMD64(); | |
557 } else if (cpu.equals("ia64")) { | |
558 machDesc = new MachineDescriptionIA64(); | |
559 } else { | |
560 throw new DebuggerException("Win32 supported under x86, amd64 and ia64 only"); | |
561 } | |
562 | |
563 // Note we do not use a cache for the local debugger in server | |
564 // mode; it will be taken care of on the client side (once remote | |
565 // debugging is implemented). | |
566 | |
3939 | 567 debugger = new WindbgDebuggerLocal(machDesc, !isServer); |
0 | 568 |
569 attachDebugger(); | |
570 | |
571 // FIXME: add support for server mode | |
572 } | |
573 | |
574 private void setupJVMLibNamesWin32() { | |
10229 | 575 jvmLibNames = new String[] { "jvm.dll" }; |
0 | 576 } |
577 | |
578 // | |
579 // Linux | |
580 // | |
581 | |
582 private void setupDebuggerLinux() { | |
583 setupJVMLibNamesLinux(); | |
584 | |
585 if (cpu.equals("x86")) { | |
586 machDesc = new MachineDescriptionIntelX86(); | |
587 } else if (cpu.equals("ia64")) { | |
588 machDesc = new MachineDescriptionIA64(); | |
589 } else if (cpu.equals("amd64")) { | |
590 machDesc = new MachineDescriptionAMD64(); | |
591 } else if (cpu.equals("sparc")) { | |
592 if (LinuxDebuggerLocal.getAddressSize()==8) { | |
593 machDesc = new MachineDescriptionSPARC64Bit(); | |
594 } else { | |
595 machDesc = new MachineDescriptionSPARC32Bit(); | |
596 } | |
597 } else { | |
6641
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
598 try { |
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
599 machDesc = (MachineDescription) |
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
600 Class.forName("sun.jvm.hotspot.debugger.MachineDescription" + |
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
601 cpu.toUpperCase()).newInstance(); |
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
602 } catch (Exception e) { |
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
603 throw new DebuggerException("Linux not supported on machine type " + cpu); |
a9fed06c01d2
7154641: Servicability agent should work on platforms other than x86, sparc
bpittore
parents:
6073
diff
changeset
|
604 } |
0 | 605 } |
606 | |
607 LinuxDebuggerLocal dbg = | |
608 new LinuxDebuggerLocal(machDesc, !isServer); | |
609 debugger = dbg; | |
610 | |
611 attachDebugger(); | |
612 } | |
613 | |
614 private void setupJVMLibNamesLinux() { | |
10229 | 615 jvmLibNames = new String[] { "libjvm.so" }; |
0 | 616 } |
617 | |
3960 | 618 // |
619 // BSD | |
620 // | |
621 | |
622 private void setupDebuggerBsd() { | |
623 setupJVMLibNamesBsd(); | |
624 | |
625 if (cpu.equals("x86")) { | |
626 machDesc = new MachineDescriptionIntelX86(); | |
6073
78d2ae5ab35b
7163117: Agent can't connect to process on Mac OSX
nloodin
parents:
3960
diff
changeset
|
627 } else if (cpu.equals("amd64") || cpu.equals("x86_64")) { |
3960 | 628 machDesc = new MachineDescriptionAMD64(); |
629 } else { | |
6073
78d2ae5ab35b
7163117: Agent can't connect to process on Mac OSX
nloodin
parents:
3960
diff
changeset
|
630 throw new DebuggerException("BSD only supported on x86/x86_64. Current arch: " + cpu); |
3960 | 631 } |
632 | |
633 BsdDebuggerLocal dbg = new BsdDebuggerLocal(machDesc, !isServer); | |
634 debugger = dbg; | |
635 | |
636 attachDebugger(); | |
637 } | |
638 | |
639 private void setupJVMLibNamesBsd() { | |
10229 | 640 jvmLibNames = new String[] { "libjvm.so" }; |
3960 | 641 } |
642 | |
8750 | 643 // |
644 // Darwin | |
645 // | |
646 | |
647 private void setupDebuggerDarwin() { | |
648 setupJVMLibNamesDarwin(); | |
649 | |
650 if (cpu.equals("amd64") || cpu.equals("x86_64")) { | |
651 machDesc = new MachineDescriptionAMD64(); | |
652 } else { | |
653 throw new DebuggerException("Darwin only supported on x86_64. Current arch: " + cpu); | |
654 } | |
655 | |
656 BsdDebuggerLocal dbg = new BsdDebuggerLocal(machDesc, !isServer); | |
657 debugger = dbg; | |
658 | |
659 attachDebugger(); | |
660 } | |
661 | |
662 private void setupJVMLibNamesDarwin() { | |
10229 | 663 jvmLibNames = new String[] { "libjvm.dylib" }; |
8750 | 664 } |
665 | |
0 | 666 /** Convenience routine which should be called by per-platform |
667 debugger setup. Should not be called when startupMode is | |
668 REMOTE_MODE. */ | |
669 private void attachDebugger() { | |
670 if (startupMode == PROCESS_MODE) { | |
671 debugger.attach(pid); | |
672 } else if (startupMode == CORE_FILE_MODE) { | |
673 debugger.attach(javaExecutableName, coreFileName); | |
674 } else { | |
675 throw new DebuggerException("Should not call attach() for startupMode == " + startupMode); | |
676 } | |
677 } | |
678 } |