Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java @ 2894:d9ee2a573a55
Merge.
author | Thomas Wuerthinger <thomas@wuerthinger.net> |
---|---|
date | Wed, 08 Jun 2011 14:10:06 +0200 |
parents | c18cbe5936b8 |
children | f6f3bb0ee072 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2000, 2006, 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 | |
27 import java.io.PrintStream; | |
28 import java.net.*; | |
29 import java.rmi.*; | |
30 import sun.jvm.hotspot.debugger.*; | |
31 import sun.jvm.hotspot.debugger.dbx.*; | |
32 import sun.jvm.hotspot.debugger.proc.*; | |
33 import sun.jvm.hotspot.debugger.remote.*; | |
34 import sun.jvm.hotspot.debugger.win32.*; | |
35 import sun.jvm.hotspot.debugger.windbg.*; | |
36 import sun.jvm.hotspot.debugger.linux.*; | |
37 import sun.jvm.hotspot.memory.*; | |
38 import sun.jvm.hotspot.oops.*; | |
39 import sun.jvm.hotspot.runtime.*; | |
40 import sun.jvm.hotspot.types.*; | |
41 import sun.jvm.hotspot.utilities.*; | |
42 | |
43 /** <P> This class wraps much of the basic functionality and is the | |
44 * highest-level factory for VM data structures. It makes it simple | |
45 * to start up the debugging system. </P> | |
46 * | |
47 * <P> FIXME: need to add a way to configure the paths to dbx and the | |
48 * DSO from the outside. However, this should work for now for | |
49 * internal use. </P> | |
50 * | |
51 * <P> FIXME: especially with the addition of remote debugging, this | |
52 * has turned into a mess; needs rethinking. </P> | |
53 */ | |
54 | |
55 public class HotSpotAgent { | |
56 private JVMDebugger debugger; | |
57 private MachineDescription machDesc; | |
58 private TypeDataBase db; | |
59 | |
60 private String os; | |
61 private String cpu; | |
62 private String fileSep; | |
63 | |
64 // The system can work in several ways: | |
65 // - Attaching to local process | |
66 // - Attaching to local core file | |
67 // - Connecting to remote debug server | |
68 // - Starting debug server for process | |
69 // - Starting debug server for core file | |
70 | |
71 // These are options for the "client" side of things | |
72 private static final int PROCESS_MODE = 0; | |
73 private static final int CORE_FILE_MODE = 1; | |
74 private static final int REMOTE_MODE = 2; | |
75 private int startupMode; | |
76 | |
77 // This indicates whether we are really starting a server or not | |
78 private boolean isServer; | |
79 | |
80 // All possible required information for connecting | |
81 private int pid; | |
82 private String javaExecutableName; | |
83 private String coreFileName; | |
84 private String debugServerID; | |
85 | |
86 // All needed information for server side | |
87 private String serverID; | |
88 | |
89 private String[] jvmLibNames; | |
90 | |
91 // FIXME: make these configurable, i.e., via a dotfile; also | |
92 // consider searching within the JDK from which this Java executable | |
93 // comes to find them | |
94 private static final String defaultDbxPathPrefix = "/net/jano.sfbay/export/disk05/hotspot/sa"; | |
95 private static final String defaultDbxSvcAgentDSOPathPrefix = "/net/jano.sfbay/export/disk05/hotspot/sa"; | |
96 | |
97 static void showUsage() { | |
98 System.out.println(" You can also pass these -D options to java to specify where to find dbx and the \n" + | |
99 " Serviceability Agent plugin for dbx:"); | |
100 System.out.println(" -DdbxPathName=<path-to-dbx-executable>\n" + | |
101 " Default is derived from dbxPathPrefix"); | |
102 System.out.println(" or"); | |
103 System.out.println(" -DdbxPathPrefix=<xxx>\n" + | |
104 " where xxx is the path name of a dir structure that contains:\n" + | |
105 " <os>/<arch>/bin/dbx\n" + | |
106 " The default is " + defaultDbxPathPrefix); | |
107 System.out.println(" and"); | |
108 System.out.println(" -DdbxSvcAgentDSOPathName=<path-to-dbx-serviceability-agent-module>\n" + | |
109 " Default is determined from dbxSvcAgentDSOPathPrefix"); | |
110 System.out.println(" or"); | |
111 System.out.println(" -DdbxSvcAgentDSOPathPrefix=<xxx>\n" + | |
112 " where xxx is the pathname of a dir structure that contains:\n" + | |
113 " <os>/<arch>/bin/lib/libsvc_agent_dbx.so\n" + | |
114 " The default is " + defaultDbxSvcAgentDSOPathPrefix); | |
115 } | |
116 | |
117 public HotSpotAgent() { | |
118 // for non-server add shutdown hook to clean-up debugger in case | |
119 // of forced exit. For remote server, shutdown hook is added by | |
120 // DebugServer. | |
121 Runtime.getRuntime().addShutdownHook(new java.lang.Thread( | |
122 new Runnable() { | |
123 public void run() { | |
124 synchronized (HotSpotAgent.this) { | |
125 if (!isServer) { | |
126 detach(); | |
127 } | |
128 } | |
129 } | |
130 })); | |
131 } | |
132 | |
133 //-------------------------------------------------------------------------------- | |
134 // Accessors (once the system is set up) | |
135 // | |
136 | |
137 public synchronized Debugger getDebugger() { | |
138 return debugger; | |
139 } | |
140 | |
141 public synchronized TypeDataBase getTypeDataBase() { | |
142 return db; | |
143 } | |
144 | |
145 //-------------------------------------------------------------------------------- | |
146 // Client-side operations | |
147 // | |
148 | |
149 /** This attaches to a process running on the local machine. */ | |
150 public synchronized void attach(int processID) | |
151 throws DebuggerException { | |
152 if (debugger != null) { | |
153 throw new DebuggerException("Already attached"); | |
154 } | |
155 pid = processID; | |
156 startupMode = PROCESS_MODE; | |
157 isServer = false; | |
158 go(); | |
159 } | |
160 | |
161 /** This opens a core file on the local machine */ | |
162 public synchronized void attach(String javaExecutableName, String coreFileName) | |
163 throws DebuggerException { | |
164 if (debugger != null) { | |
165 throw new DebuggerException("Already attached"); | |
166 } | |
167 if ((javaExecutableName == null) || (coreFileName == null)) { | |
168 throw new DebuggerException("Both the core file name and Java executable name must be specified"); | |
169 } | |
170 this.javaExecutableName = javaExecutableName; | |
171 this.coreFileName = coreFileName; | |
172 startupMode = CORE_FILE_MODE; | |
173 isServer = false; | |
174 go(); | |
175 } | |
176 | |
177 /** This attaches to a "debug server" on a remote machine; this | |
178 remote server has already attached to a process or opened a | |
179 core file and is waiting for RMI calls on the Debugger object to | |
180 come in. */ | |
181 public synchronized void attach(String remoteServerID) | |
182 throws DebuggerException { | |
183 if (debugger != null) { | |
184 throw new DebuggerException("Already attached to a process"); | |
185 } | |
186 if (remoteServerID == null) { | |
187 throw new DebuggerException("Debug server id must be specified"); | |
188 } | |
189 | |
190 debugServerID = remoteServerID; | |
191 startupMode = REMOTE_MODE; | |
192 isServer = false; | |
193 go(); | |
194 } | |
195 | |
196 /** This should only be called by the user on the client machine, | |
197 not the server machine */ | |
198 public synchronized boolean detach() throws DebuggerException { | |
199 if (isServer) { | |
200 throw new DebuggerException("Should not call detach() for server configuration"); | |
201 } | |
202 return detachInternal(); | |
203 } | |
204 | |
205 //-------------------------------------------------------------------------------- | |
206 // Server-side operations | |
207 // | |
208 | |
209 /** This attaches to a process running on the local machine and | |
210 starts a debug server, allowing remote machines to connect and | |
211 examine this process. Uses specified name to uniquely identify a | |
212 specific debuggee on the server */ | |
213 public synchronized void startServer(int processID, String uniqueID) { | |
214 if (debugger != null) { | |
215 throw new DebuggerException("Already attached"); | |
216 } | |
217 pid = processID; | |
218 startupMode = PROCESS_MODE; | |
219 isServer = true; | |
220 serverID = uniqueID; | |
221 go(); | |
222 } | |
223 | |
224 /** This attaches to a process running on the local machine and | |
225 starts a debug server, allowing remote machines to connect and | |
226 examine this process. */ | |
227 public synchronized void startServer(int processID) | |
228 throws DebuggerException { | |
229 startServer(processID, null); | |
230 } | |
231 | |
232 /** This opens a core file on the local machine and starts a debug | |
233 server, allowing remote machines to connect and examine this | |
234 core file. Uses supplied uniqueID to uniquely identify a specific | |
235 debugee */ | |
236 public synchronized void startServer(String javaExecutableName, | |
237 String coreFileName, | |
238 String uniqueID) { | |
239 if (debugger != null) { | |
240 throw new DebuggerException("Already attached"); | |
241 } | |
242 if ((javaExecutableName == null) || (coreFileName == null)) { | |
243 throw new DebuggerException("Both the core file name and Java executable name must be specified"); | |
244 } | |
245 this.javaExecutableName = javaExecutableName; | |
246 this.coreFileName = coreFileName; | |
247 startupMode = CORE_FILE_MODE; | |
248 isServer = true; | |
249 serverID = uniqueID; | |
250 go(); | |
251 } | |
252 | |
253 /** This opens a core file on the local machine and starts a debug | |
254 server, allowing remote machines to connect and examine this | |
255 core file. */ | |
256 public synchronized void startServer(String javaExecutableName, String coreFileName) | |
257 throws DebuggerException { | |
258 startServer(javaExecutableName, coreFileName, null); | |
259 } | |
260 | |
261 /** This may only be called on the server side after startServer() | |
262 has been called */ | |
263 public synchronized boolean shutdownServer() throws DebuggerException { | |
264 if (!isServer) { | |
265 throw new DebuggerException("Should not call shutdownServer() for client configuration"); | |
266 } | |
267 return detachInternal(); | |
268 } | |
269 | |
270 | |
271 //-------------------------------------------------------------------------------- | |
272 // Internals only below this point | |
273 // | |
274 | |
275 private boolean detachInternal() { | |
276 if (debugger == null) { | |
277 return false; | |
278 } | |
279 boolean retval = true; | |
280 if (!isServer) { | |
281 VM.shutdown(); | |
282 } | |
283 // We must not call detach() if we are a client and are connected | |
284 // to a remote debugger | |
285 Debugger dbg = null; | |
286 DebuggerException ex = null; | |
287 if (isServer) { | |
288 try { | |
289 RMIHelper.unbind(serverID); | |
290 } | |
291 catch (DebuggerException de) { | |
292 ex = de; | |
293 } | |
294 dbg = debugger; | |
295 } else { | |
296 if (startupMode != REMOTE_MODE) { | |
297 dbg = debugger; | |
298 } | |
299 } | |
300 if (dbg != null) { | |
301 retval = dbg.detach(); | |
302 } | |
303 | |
304 debugger = null; | |
305 machDesc = null; | |
306 db = null; | |
307 if (ex != null) { | |
308 throw(ex); | |
309 } | |
310 return retval; | |
311 } | |
312 | |
313 private void go() { | |
314 setupDebugger(); | |
315 setupVM(); | |
316 } | |
317 | |
318 private void setupDebugger() { | |
319 if (startupMode != REMOTE_MODE) { | |
320 // | |
321 // Local mode (client attaching to local process or setting up | |
322 // server, but not client attaching to server) | |
323 // | |
324 | |
325 try { | |
326 os = PlatformInfo.getOS(); | |
327 cpu = PlatformInfo.getCPU(); | |
328 } | |
329 catch (UnsupportedPlatformException e) { | |
330 throw new DebuggerException(e); | |
331 } | |
332 fileSep = System.getProperty("file.separator"); | |
333 | |
334 if (os.equals("solaris")) { | |
335 setupDebuggerSolaris(); | |
336 } else if (os.equals("win32")) { | |
337 setupDebuggerWin32(); | |
338 } else if (os.equals("linux")) { | |
339 setupDebuggerLinux(); | |
340 } else { | |
341 // Add support for more operating systems here | |
342 throw new DebuggerException("Operating system " + os + " not yet supported"); | |
343 } | |
344 | |
345 if (isServer) { | |
346 RemoteDebuggerServer remote = null; | |
347 try { | |
348 remote = new RemoteDebuggerServer(debugger); | |
349 } | |
350 catch (RemoteException rem) { | |
351 throw new DebuggerException(rem); | |
352 } | |
353 RMIHelper.rebind(serverID, remote); | |
354 } | |
355 } else { | |
356 // | |
357 // Remote mode (client attaching to server) | |
358 // | |
359 | |
360 // Create and install a security manager | |
361 | |
362 // FIXME: currently commented out because we were having | |
363 // security problems since we're "in the sun.* hierarchy" here. | |
364 // Perhaps a permissive policy file would work around this. In | |
365 // the long run, will probably have to move into com.sun.*. | |
366 | |
367 // if (System.getSecurityManager() == null) { | |
368 // System.setSecurityManager(new RMISecurityManager()); | |
369 // } | |
370 | |
371 connectRemoteDebugger(); | |
372 } | |
373 } | |
374 | |
375 private void setupVM() { | |
376 // We need to instantiate a HotSpotTypeDataBase on both the client | |
377 // and server machine. On the server it is only currently used to | |
378 // configure the Java primitive type sizes (which we should | |
379 // consider making constant). On the client it is used to | |
380 // configure the VM. | |
381 | |
382 try { | |
383 if (os.equals("solaris")) { | |
384 db = new HotSpotTypeDataBase(machDesc, | |
385 new HotSpotSolarisVtblAccess(debugger, jvmLibNames), | |
386 debugger, jvmLibNames); | |
387 } else if (os.equals("win32")) { | |
388 db = new HotSpotTypeDataBase(machDesc, | |
389 new Win32VtblAccess(debugger, jvmLibNames), | |
390 debugger, jvmLibNames); | |
391 } else if (os.equals("linux")) { | |
392 db = new HotSpotTypeDataBase(machDesc, | |
393 new LinuxVtblAccess(debugger, jvmLibNames), | |
394 debugger, jvmLibNames); | |
395 } else { | |
396 throw new DebuggerException("OS \"" + os + "\" not yet supported (no VtblAccess yet)"); | |
397 } | |
398 } | |
399 catch (NoSuchSymbolException e) { | |
400 throw new DebuggerException("Doesn't appear to be a HotSpot VM (could not find symbol \"" + | |
401 e.getSymbol() + "\" in remote process)"); | |
402 } | |
403 | |
404 if (startupMode != REMOTE_MODE) { | |
405 // Configure the debugger with the primitive type sizes just obtained from the VM | |
406 debugger.configureJavaPrimitiveTypeSizes(db.getJBooleanType().getSize(), | |
407 db.getJByteType().getSize(), | |
408 db.getJCharType().getSize(), | |
409 db.getJDoubleType().getSize(), | |
410 db.getJFloatType().getSize(), | |
411 db.getJIntType().getSize(), | |
412 db.getJLongType().getSize(), | |
413 db.getJShortType().getSize()); | |
414 } | |
415 | |
416 if (!isServer) { | |
417 // Do not initialize the VM on the server (unnecessary, since it's | |
418 // instantiated on the client) | |
419 try { | |
420 VM.initialize(db, debugger); | |
421 } catch (DebuggerException e) { | |
422 throw (e); | |
423 } catch (Exception e) { | |
424 throw new DebuggerException(e); | |
425 } | |
426 } | |
427 } | |
428 | |
429 //-------------------------------------------------------------------------------- | |
430 // OS-specific debugger setup/connect routines | |
431 // | |
432 | |
433 // | |
434 // Solaris | |
435 // | |
436 | |
437 private void setupDebuggerSolaris() { | |
438 setupJVMLibNamesSolaris(); | |
439 if(System.getProperty("sun.jvm.hotspot.debugger.useProcDebugger") != null) { | |
440 ProcDebuggerLocal dbg = new ProcDebuggerLocal(null, true); | |
441 debugger = dbg; | |
442 attachDebugger(); | |
443 | |
444 // Set up CPU-dependent stuff | |
445 if (cpu.equals("x86")) { | |
446 machDesc = new MachineDescriptionIntelX86(); | |
447 } else if (cpu.equals("sparc")) { | |
448 int addressSize = dbg.getRemoteProcessAddressSize(); | |
449 if (addressSize == -1) { | |
450 throw new DebuggerException("Error occurred while trying to determine the remote process's " + | |
451 "address size"); | |
452 } | |
453 | |
454 if (addressSize == 32) { | |
455 machDesc = new MachineDescriptionSPARC32Bit(); | |
456 } else if (addressSize == 64) { | |
457 machDesc = new MachineDescriptionSPARC64Bit(); | |
458 } else { | |
459 throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); | |
460 } | |
461 } else if (cpu.equals("amd64")) { | |
462 machDesc = new MachineDescriptionAMD64(); | |
463 } else { | |
464 throw new DebuggerException("Solaris only supported on sparc/sparcv9/x86/amd64"); | |
465 } | |
466 | |
467 dbg.setMachineDescription(machDesc); | |
468 return; | |
469 | |
470 } else { | |
471 String dbxPathName; | |
472 String dbxPathPrefix; | |
473 String dbxSvcAgentDSOPathName; | |
474 String dbxSvcAgentDSOPathPrefix; | |
475 String[] dbxSvcAgentDSOPathNames = null; | |
476 | |
477 // use path names/prefixes specified on command | |
478 dbxPathName = System.getProperty("dbxPathName"); | |
479 if (dbxPathName == null) { | |
480 dbxPathPrefix = System.getProperty("dbxPathPrefix"); | |
481 if (dbxPathPrefix == null) { | |
482 dbxPathPrefix = defaultDbxPathPrefix; | |
483 } | |
484 dbxPathName = dbxPathPrefix + fileSep + os + fileSep + cpu + fileSep + "bin" + fileSep + "dbx"; | |
485 } | |
486 | |
487 dbxSvcAgentDSOPathName = System.getProperty("dbxSvcAgentDSOPathName"); | |
488 if (dbxSvcAgentDSOPathName != null) { | |
489 dbxSvcAgentDSOPathNames = new String[] { dbxSvcAgentDSOPathName } ; | |
490 } else { | |
491 dbxSvcAgentDSOPathPrefix = System.getProperty("dbxSvcAgentDSOPathPrefix"); | |
492 if (dbxSvcAgentDSOPathPrefix == null) { | |
493 dbxSvcAgentDSOPathPrefix = defaultDbxSvcAgentDSOPathPrefix; | |
494 } | |
495 if (cpu.equals("sparc")) { | |
496 dbxSvcAgentDSOPathNames = new String[] { | |
497 // FIXME: bad hack for SPARC v9. This is necessary because | |
498 // there are two dbx executables on SPARC, one for v8 and one | |
499 // for v9, and it isn't obvious how to tell the two apart | |
500 // using the dbx command line. See | |
501 // DbxDebuggerLocal.importDbxModule(). | |
502 dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + "v9" + fileSep + "lib" + | |
503 fileSep + "libsvc_agent_dbx.so", | |
504 dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" + | |
505 fileSep + "libsvc_agent_dbx.so", | |
506 }; | |
507 } else { | |
508 dbxSvcAgentDSOPathNames = new String[] { | |
509 dbxSvcAgentDSOPathPrefix + fileSep + os + fileSep + cpu + fileSep + "lib" + | |
510 fileSep + "libsvc_agent_dbx.so" | |
511 }; | |
512 } | |
513 } | |
514 | |
515 // Note we do not use a cache for the local debugger in server | |
516 // mode; it's taken care of on the client side | |
517 DbxDebuggerLocal dbg = new DbxDebuggerLocal(null, dbxPathName, dbxSvcAgentDSOPathNames, !isServer); | |
518 debugger = dbg; | |
519 | |
520 attachDebugger(); | |
521 | |
522 // Set up CPU-dependent stuff | |
523 if (cpu.equals("x86")) { | |
524 machDesc = new MachineDescriptionIntelX86(); | |
525 } else if (cpu.equals("sparc")) { | |
526 int addressSize = dbg.getRemoteProcessAddressSize(); | |
527 if (addressSize == -1) { | |
528 throw new DebuggerException("Error occurred while trying to determine the remote process's " + | |
529 "address size. It's possible that the Serviceability Agent's dbx module failed to " + | |
530 "initialize. Examine the standard output and standard error streams from the dbx " + | |
531 "process for more information."); | |
532 } | |
533 | |
534 if (addressSize == 32) { | |
535 machDesc = new MachineDescriptionSPARC32Bit(); | |
536 } else if (addressSize == 64) { | |
537 machDesc = new MachineDescriptionSPARC64Bit(); | |
538 } else { | |
539 throw new DebuggerException("Address size " + addressSize + " is not supported on SPARC"); | |
540 } | |
541 } | |
542 | |
543 dbg.setMachineDescription(machDesc); | |
544 | |
545 } | |
546 } | |
547 | |
548 private void connectRemoteDebugger() throws DebuggerException { | |
549 RemoteDebugger remote = | |
550 (RemoteDebugger) RMIHelper.lookup(debugServerID); | |
551 debugger = new RemoteDebuggerClient(remote); | |
552 machDesc = ((RemoteDebuggerClient) debugger).getMachineDescription(); | |
553 os = debugger.getOS(); | |
554 if (os.equals("solaris")) { | |
555 setupJVMLibNamesSolaris(); | |
556 } else if (os.equals("win32")) { | |
557 setupJVMLibNamesWin32(); | |
558 } else if (os.equals("linux")) { | |
559 setupJVMLibNamesLinux(); | |
560 } else { | |
561 throw new RuntimeException("Unknown OS type"); | |
562 } | |
563 | |
564 cpu = debugger.getCPU(); | |
565 } | |
566 | |
567 private void setupJVMLibNamesSolaris() { | |
568 jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so", "gamma_g" }; | |
569 } | |
570 | |
571 // | |
572 // Win32 | |
573 // | |
574 | |
575 private void setupDebuggerWin32() { | |
576 setupJVMLibNamesWin32(); | |
577 | |
578 if (cpu.equals("x86")) { | |
579 machDesc = new MachineDescriptionIntelX86(); | |
580 } else if (cpu.equals("amd64")) { | |
581 machDesc = new MachineDescriptionAMD64(); | |
582 } else if (cpu.equals("ia64")) { | |
583 machDesc = new MachineDescriptionIA64(); | |
584 } else { | |
585 throw new DebuggerException("Win32 supported under x86, amd64 and ia64 only"); | |
586 } | |
587 | |
588 // Note we do not use a cache for the local debugger in server | |
589 // mode; it will be taken care of on the client side (once remote | |
590 // debugging is implemented). | |
591 | |
592 if (System.getProperty("sun.jvm.hotspot.debugger.useWindbgDebugger") != null) { | |
593 debugger = new WindbgDebuggerLocal(machDesc, !isServer); | |
594 } else { | |
595 debugger = new Win32DebuggerLocal(machDesc, !isServer); | |
596 } | |
597 | |
598 attachDebugger(); | |
599 | |
600 // FIXME: add support for server mode | |
601 } | |
602 | |
603 private void setupJVMLibNamesWin32() { | |
604 jvmLibNames = new String[] { "jvm.dll", "jvm_g.dll" }; | |
605 } | |
606 | |
607 // | |
608 // Linux | |
609 // | |
610 | |
611 private void setupDebuggerLinux() { | |
612 setupJVMLibNamesLinux(); | |
613 | |
614 if (cpu.equals("x86")) { | |
615 machDesc = new MachineDescriptionIntelX86(); | |
616 } else if (cpu.equals("ia64")) { | |
617 machDesc = new MachineDescriptionIA64(); | |
618 } else if (cpu.equals("amd64")) { | |
619 machDesc = new MachineDescriptionAMD64(); | |
620 } else if (cpu.equals("sparc")) { | |
621 if (LinuxDebuggerLocal.getAddressSize()==8) { | |
622 machDesc = new MachineDescriptionSPARC64Bit(); | |
623 } else { | |
624 machDesc = new MachineDescriptionSPARC32Bit(); | |
625 } | |
626 } else { | |
627 throw new DebuggerException("Linux only supported on x86/ia64/amd64/sparc/sparc64"); | |
628 } | |
629 | |
630 LinuxDebuggerLocal dbg = | |
631 new LinuxDebuggerLocal(machDesc, !isServer); | |
632 debugger = dbg; | |
633 | |
634 attachDebugger(); | |
635 } | |
636 | |
637 private void setupJVMLibNamesLinux() { | |
638 jvmLibNames = new String[] { "libjvm.so", "libjvm_g.so" }; | |
639 } | |
640 | |
641 /** Convenience routine which should be called by per-platform | |
642 debugger setup. Should not be called when startupMode is | |
643 REMOTE_MODE. */ | |
644 private void attachDebugger() { | |
645 if (startupMode == PROCESS_MODE) { | |
646 debugger.attach(pid); | |
647 } else if (startupMode == CORE_FILE_MODE) { | |
648 debugger.attach(javaExecutableName, coreFileName); | |
649 } else { | |
650 throw new DebuggerException("Should not call attach() for startupMode == " + startupMode); | |
651 } | |
652 } | |
653 } |