Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/HotSpotAgent.java @ 17398:9e1ec84d2899
fix privileged check for Stable
author | Tom Rodriguez <tom.rodriguez@oracle.com> |
---|---|
date | Thu, 09 Oct 2014 11:32:21 -0700 |
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 } |