Mercurial > hg > truffle
annotate agent/src/share/classes/sun/jvm/hotspot/debugger/windbg/WindbgDebuggerLocal.java @ 196:d1605aabd0a1 jdk7-b30
6719955: Update copyright year
Summary: Update copyright year for files that have been modified in 2008
Reviewed-by: ohair, tbell
author | xdono |
---|---|
date | Wed, 02 Jul 2008 12:55:16 -0700 |
parents | ba764ed4b6f2 |
children | c18cbe5936b8 |
rev | line source |
---|---|
0 | 1 /* |
196 | 2 * Copyright 2002-2008 Sun Microsystems, Inc. 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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 package sun.jvm.hotspot.debugger.windbg; | |
26 | |
27 import java.io.*; | |
28 import java.net.*; | |
29 import java.util.*; | |
30 import sun.jvm.hotspot.debugger.*; | |
31 import sun.jvm.hotspot.debugger.amd64.*; | |
32 import sun.jvm.hotspot.debugger.x86.*; | |
33 import sun.jvm.hotspot.debugger.ia64.*; | |
34 import sun.jvm.hotspot.debugger.windbg.amd64.*; | |
35 import sun.jvm.hotspot.debugger.windbg.x86.*; | |
36 import sun.jvm.hotspot.debugger.windbg.ia64.*; | |
37 import sun.jvm.hotspot.debugger.win32.coff.*; | |
38 import sun.jvm.hotspot.debugger.cdbg.*; | |
39 import sun.jvm.hotspot.debugger.cdbg.basic.BasicDebugEvent; | |
40 import sun.jvm.hotspot.utilities.*; | |
41 import sun.jvm.hotspot.utilities.memo.*; | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
42 import sun.jvm.hotspot.runtime.*; |
0 | 43 |
44 /** <P> An implementation of the JVMDebugger interface which talks to | |
45 windbg and symbol table management is done in Java. </P> | |
46 | |
47 <P> <B>NOTE</B> that since we have the notion of fetching "Java | |
48 primitive types" from the remote process (which might have | |
49 different sizes than we expect) we have a bootstrapping | |
50 problem. We need to know the sizes of these types before we can | |
51 fetch them. The current implementation solves this problem by | |
52 requiring that it be configured with these type sizes before they | |
53 can be fetched. The readJ(Type) routines here will throw a | |
54 RuntimeException if they are called before the debugger is | |
55 configured with the Java primitive type sizes. </P> */ | |
56 | |
57 public class WindbgDebuggerLocal extends DebuggerBase implements WindbgDebugger { | |
58 private PageCache cache; | |
59 private boolean attached; | |
60 private boolean isCore; | |
61 | |
62 // Symbol lookup support | |
63 // This is a map of library names to DLLs | |
64 private Map nameToDllMap; | |
65 | |
66 // C/C++ debugging support | |
67 private List/*<LoadObject>*/ loadObjects; | |
68 private CDebugger cdbg; | |
69 | |
70 // thread access | |
71 private Map threadIntegerRegisterSet; | |
72 private List threadList; | |
73 | |
74 // windbg native interface pointers | |
75 | |
76 private long ptrIDebugClient; | |
77 private long ptrIDebugControl; | |
78 private long ptrIDebugDataSpaces; | |
79 private long ptrIDebugOutputCallbacks; | |
80 private long ptrIDebugAdvanced; | |
81 private long ptrIDebugSymbols; | |
82 private long ptrIDebugSystemObjects; | |
83 | |
84 private WindbgThreadFactory threadFactory; | |
85 | |
86 //-------------------------------------------------------------------------------- | |
87 // Implementation of Debugger interface | |
88 // | |
89 | |
90 /** <P> machDesc may not be null. </P> | |
91 | |
92 <P> useCache should be set to true if debugging is being done | |
93 locally, and to false if the debugger is being created for the | |
94 purpose of supporting remote debugging. </P> */ | |
95 public WindbgDebuggerLocal(MachineDescription machDesc, | |
96 boolean useCache) throws DebuggerException { | |
97 this.machDesc = machDesc; | |
98 utils = new DebuggerUtilities(machDesc.getAddressSize(), machDesc.isBigEndian()) { | |
99 public void checkAlignment(long address, long alignment) { | |
100 // Need to override default checkAlignment because we need to | |
101 // relax alignment constraints on Windows/x86 | |
102 if ( (address % alignment != 0) | |
103 &&(alignment != 8 || address % 4 != 0)) { | |
104 throw new UnalignedAddressException( | |
105 "Trying to read at address: " | |
106 + addressValueToString(address) | |
107 + " with alignment: " + alignment, | |
108 address); | |
109 } | |
110 } | |
111 }; | |
112 | |
113 String cpu = PlatformInfo.getCPU(); | |
114 if (cpu.equals("x86")) { | |
115 threadFactory = new WindbgX86ThreadFactory(this); | |
116 } else if (cpu.equals("amd64")) { | |
117 threadFactory = new WindbgAMD64ThreadFactory(this); | |
118 } else if (cpu.equals("ia64")) { | |
119 threadFactory = new WindbgIA64ThreadFactory(this); | |
120 } | |
121 | |
122 if (useCache) { | |
123 // Cache portion of the remote process's address space. | |
124 // Fetching data over the socket connection to dbx is slow. | |
125 // Might be faster if we were using a binary protocol to talk to | |
126 // dbx, but would have to test. For now, this cache works best | |
127 // if it covers the entire heap of the remote process. FIXME: at | |
128 // least should make this tunable from the outside, i.e., via | |
129 // the UI. This is a cache of 4096 4K pages, or 16 MB. The page | |
130 // size must be adjusted to be the hardware's page size. | |
131 // (FIXME: should pick this up from the debugger.) | |
132 initCache(4096, 4096); | |
133 } | |
134 // FIXME: add instantiation of thread factory | |
135 | |
136 } | |
137 | |
138 /** From the Debugger interface via JVMDebugger */ | |
139 public boolean hasProcessList() throws DebuggerException { | |
140 return false; | |
141 } | |
142 | |
143 /** From the Debugger interface via JVMDebugger */ | |
144 public List getProcessList() throws DebuggerException { | |
145 return null; | |
146 } | |
147 | |
148 | |
149 /** From the Debugger interface via JVMDebugger */ | |
150 public synchronized void attach(int processID) throws DebuggerException { | |
151 attachInit(); | |
152 attach0(processID); | |
153 attached = true; | |
154 isCore = false; | |
155 } | |
156 | |
157 /** From the Debugger interface via JVMDebugger */ | |
158 public synchronized void attach(String executableName, String coreFileName) throws DebuggerException { | |
159 attachInit(); | |
160 attach0(executableName, coreFileName); | |
161 attached = true; | |
162 isCore = true; | |
163 } | |
164 | |
165 public List getLoadObjectList() { | |
166 requireAttach(); | |
167 return loadObjects; | |
168 } | |
169 | |
170 /** From the Debugger interface via JVMDebugger */ | |
171 public synchronized boolean detach() { | |
172 if ( ! attached) | |
173 return false; | |
174 | |
175 // Close all open DLLs | |
176 if (nameToDllMap != null) { | |
177 for (Iterator iter = nameToDllMap.values().iterator(); iter.hasNext(); ) { | |
178 DLL dll = (DLL) iter.next(); | |
179 dll.close(); | |
180 } | |
181 nameToDllMap = null; | |
182 loadObjects = null; | |
183 } | |
184 | |
185 cdbg = null; | |
186 clearCache(); | |
187 | |
188 threadIntegerRegisterSet = null; | |
189 threadList = null; | |
190 try { | |
191 detach0(); | |
192 } finally { | |
193 attached = false; | |
194 resetNativePointers(); | |
195 } | |
196 return true; | |
197 } | |
198 | |
199 | |
200 /** From the Debugger interface via JVMDebugger */ | |
201 public Address parseAddress(String addressString) throws NumberFormatException { | |
202 return newAddress(utils.scanAddress(addressString)); | |
203 } | |
204 | |
205 /** From the Debugger interface via JVMDebugger */ | |
206 public String getOS() { | |
207 return PlatformInfo.getOS(); | |
208 } | |
209 | |
210 /** From the Debugger interface via JVMDebugger */ | |
211 public String getCPU() { | |
212 return PlatformInfo.getCPU(); | |
213 } | |
214 | |
215 public boolean hasConsole() throws DebuggerException { | |
216 return true; | |
217 } | |
218 | |
219 public synchronized String consoleExecuteCommand(String cmd) throws DebuggerException { | |
220 requireAttach(); | |
221 if (! attached) { | |
222 throw new DebuggerException("debugger not yet attached to a Dr. Watson dump!"); | |
223 } | |
224 | |
225 return consoleExecuteCommand0(cmd); | |
226 } | |
227 | |
228 public String getConsolePrompt() throws DebuggerException { | |
229 return "(windbg)"; | |
230 } | |
231 | |
232 public CDebugger getCDebugger() throws DebuggerException { | |
233 if (cdbg == null) { | |
234 // FIXME: CDebugger is not yet supported for IA64 because | |
235 // of native stack walking issues. | |
236 if (! getCPU().equals("ia64")) { | |
237 cdbg = new WindbgCDebugger(this); | |
238 } | |
239 } | |
240 return cdbg; | |
241 } | |
242 | |
243 /** From the SymbolLookup interface via Debugger and JVMDebugger */ | |
244 public synchronized Address lookup(String objectName, String symbol) { | |
245 requireAttach(); | |
246 return newAddress(lookupByName(objectName, symbol)); | |
247 } | |
248 | |
249 /** From the SymbolLookup interface via Debugger and JVMDebugger */ | |
250 public synchronized OopHandle lookupOop(String objectName, String symbol) { | |
251 Address addr = lookup(objectName, symbol); | |
252 if (addr == null) { | |
253 return null; | |
254 } | |
255 return addr.addOffsetToAsOopHandle(0); | |
256 } | |
257 | |
258 public synchronized ClosestSymbol lookup(long address) { | |
259 return lookupByAddress0(address); | |
260 } | |
261 | |
262 /** From the Debugger interface */ | |
263 public MachineDescription getMachineDescription() { | |
264 return machDesc; | |
265 } | |
266 | |
267 //-------------------------------------------------------------------------------- | |
268 // Implementation of ThreadAccess interface | |
269 // | |
270 | |
271 | |
272 /** From the ThreadAccess interface via Debugger and JVMDebugger */ | |
273 public ThreadProxy getThreadForIdentifierAddress(Address addr) { | |
274 return threadFactory.createThreadWrapper(addr); | |
275 } | |
276 | |
277 public ThreadProxy getThreadForThreadId(long handle) { | |
278 // with windbg we can't make out using handle | |
279 throw new DebuggerException("Unimplemented!"); | |
280 } | |
281 | |
282 public long getThreadIdFromSysId(long sysId) throws DebuggerException { | |
283 requireAttach(); | |
284 return getThreadIdFromSysId0(sysId); | |
285 } | |
286 | |
287 //---------------------------------------------------------------------- | |
288 // Overridden from DebuggerBase because we need to relax alignment | |
289 // constraints on x86 | |
290 | |
291 public long readJLong(long address) | |
292 throws UnmappedAddressException, UnalignedAddressException { | |
293 checkJavaConfigured(); | |
294 // FIXME: allow this to be configurable. Undesirable to add a | |
295 // dependency on the runtime package here, though, since this | |
296 // package should be strictly underneath it. | |
297 // utils.checkAlignment(address, jlongSize); | |
298 utils.checkAlignment(address, jintSize); | |
299 byte[] data = readBytes(address, jlongSize); | |
300 return utils.dataToJLong(data, jlongSize); | |
301 } | |
302 | |
303 //-------------------------------------------------------------------------------- | |
304 // Internal routines (for implementation of WindbgAddress). | |
305 // These must not be called until the MachineDescription has been set up. | |
306 // | |
307 | |
308 /** From the WindbgDebugger interface */ | |
309 public String addressValueToString(long address) { | |
310 return utils.addressValueToString(address); | |
311 } | |
312 | |
313 /** From the WindbgDebugger interface */ | |
314 public WindbgAddress readAddress(long address) | |
315 throws UnmappedAddressException, UnalignedAddressException { | |
316 return (WindbgAddress) newAddress(readAddressValue(address)); | |
317 } | |
318 | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
319 public WindbgAddress readCompOopAddress(long address) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
320 throws UnmappedAddressException, UnalignedAddressException { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
321 return (WindbgAddress) newAddress(readCompOopAddressValue(address)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
322 } |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
323 |
0 | 324 /** From the WindbgDebugger interface */ |
325 public WindbgOopHandle readOopHandle(long address) | |
326 throws UnmappedAddressException, UnalignedAddressException, NotInHeapException { | |
327 long value = readAddressValue(address); | |
328 return (value == 0 ? null : new WindbgOopHandle(this, value)); | |
329 } | |
113
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
330 public WindbgOopHandle readCompOopHandle(long address) |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
331 throws UnmappedAddressException, UnalignedAddressException, NotInHeapException { |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
332 long value = readCompOopAddressValue(address); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
333 return (value == 0 ? null : new WindbgOopHandle(this, value)); |
ba764ed4b6f2
6420645: Create a vm that uses compressed oops for up to 32gb heapsizes
coleenp
parents:
0
diff
changeset
|
334 } |
0 | 335 |
336 /** From the WindbgDebugger interface */ | |
337 public int getAddressSize() { | |
338 return (int) machDesc.getAddressSize(); | |
339 } | |
340 | |
341 //-------------------------------------------------------------------------------- | |
342 // Thread context access | |
343 // | |
344 | |
345 private synchronized void setThreadIntegerRegisterSet(long threadId, | |
346 long[] regs) { | |
347 threadIntegerRegisterSet.put(new Long(threadId), regs); | |
348 } | |
349 | |
350 private synchronized void addThread(long sysId) { | |
351 threadList.add(threadFactory.createThreadWrapper(sysId)); | |
352 } | |
353 | |
354 public synchronized long[] getThreadIntegerRegisterSet(long threadId) | |
355 throws DebuggerException { | |
356 requireAttach(); | |
357 return (long[]) threadIntegerRegisterSet.get(new Long(threadId)); | |
358 } | |
359 | |
360 public synchronized List getThreadList() throws DebuggerException { | |
361 requireAttach(); | |
362 return threadList; | |
363 } | |
364 | |
365 private String findFullPath(String file) { | |
366 File f = new File(file); | |
367 if (f.exists()) { | |
368 return file; | |
369 } else { | |
370 // remove path part, if any. | |
371 file = f.getName(); | |
372 StringTokenizer st = new StringTokenizer(imagePath, File.pathSeparator); | |
373 while (st.hasMoreTokens()) { | |
374 f = new File(st.nextToken(), file); | |
375 if (f.exists()) { | |
376 return f.getPath(); | |
377 } | |
378 } | |
379 } | |
380 return null; | |
381 } | |
382 | |
383 private synchronized void addLoadObject(String file, long size, long base) { | |
384 String path = findFullPath(file); | |
385 if (path != null) { | |
386 DLL dll = null; | |
387 if (useNativeLookup) { | |
388 dll = new DLL(this, path, size,newAddress(base)) { | |
389 public ClosestSymbol closestSymbolToPC(Address pcAsAddr) { | |
390 long pc = getAddressValue(pcAsAddr); | |
391 ClosestSymbol sym = lookupByAddress0(pc); | |
392 if (sym == null) { | |
393 return super.closestSymbolToPC(pcAsAddr); | |
394 } else { | |
395 return sym; | |
396 } | |
397 } | |
398 }; | |
399 } else { | |
400 dll = new DLL(this, path, size, newAddress(base)); | |
401 } | |
402 loadObjects.add(dll); | |
403 nameToDllMap.put(new File(file).getName(), dll); | |
404 } | |
405 } | |
406 | |
407 //-------------------------------------------------------------------------------- | |
408 // Address access | |
409 // | |
410 | |
411 /** From the Debugger interface */ | |
412 public long getAddressValue(Address addr) { | |
413 if (addr == null) return 0; | |
414 return ((WindbgAddress) addr).getValue(); | |
415 } | |
416 | |
417 /** From the WindbgDebugger interface */ | |
418 public Address newAddress(long value) { | |
419 if (value == 0) return null; | |
420 return new WindbgAddress(this, value); | |
421 } | |
422 | |
423 //-------------------------------------------------------------------------------- | |
424 // Internals only below this point | |
425 // | |
426 | |
427 // attach/detach helpers | |
428 private void checkAttached() { | |
429 if (attached) { | |
430 String msg = (isCore)? "already attached to a Dr. Watson dump!" : | |
431 "already attached to a process!"; | |
432 throw new DebuggerException(msg); | |
433 } | |
434 } | |
435 | |
436 private void requireAttach() { | |
437 if (!attached) { | |
438 throw new RuntimeException("not attached to a process or Dr Watson dump"); | |
439 } | |
440 } | |
441 | |
442 private void attachInit() { | |
443 checkAttached(); | |
444 loadObjects = new ArrayList(); | |
445 nameToDllMap = new HashMap(); | |
446 threadIntegerRegisterSet = new HashMap(); | |
447 threadList = new ArrayList(); | |
448 } | |
449 | |
450 private void resetNativePointers() { | |
451 ptrIDebugClient = 0L; | |
452 ptrIDebugControl = 0L; | |
453 ptrIDebugDataSpaces = 0L; | |
454 ptrIDebugOutputCallbacks = 0L; | |
455 ptrIDebugAdvanced = 0L; | |
456 ptrIDebugSymbols = 0L; | |
457 ptrIDebugSystemObjects = 0L; | |
458 } | |
459 | |
460 synchronized long lookupByName(String objectName, String symbol) { | |
461 long res = 0L; | |
462 if (useNativeLookup) { | |
463 res = lookupByName0(objectName, symbol); | |
464 if (res != 0L) { | |
465 return res; | |
466 } // else fallthru... | |
467 } | |
468 | |
469 DLL dll = (DLL) nameToDllMap.get(objectName); | |
470 // The DLL can be null because we use this to search through known | |
471 // DLLs in HotSpotTypeDataBase (for example) | |
472 if (dll != null) { | |
473 WindbgAddress addr = (WindbgAddress) dll.lookupSymbol(symbol); | |
474 if (addr != null) { | |
475 return addr.getValue(); | |
476 } | |
477 } | |
478 return 0L; | |
479 } | |
480 | |
481 /** This reads bytes from the remote process. */ | |
482 public synchronized ReadResult readBytesFromProcess(long address, long numBytes) | |
483 throws UnmappedAddressException, DebuggerException { | |
484 requireAttach(); | |
485 byte[] res = readBytesFromProcess0(address, numBytes); | |
486 if(res != null) | |
487 return new ReadResult(res); | |
488 else | |
489 return new ReadResult(address); | |
490 } | |
491 | |
492 | |
493 private DLL findDLLByName(String fullPathName) { | |
494 for (Iterator iter = loadObjects.iterator(); iter.hasNext(); ) { | |
495 DLL dll = (DLL) iter.next(); | |
496 if (dll.getName().equals(fullPathName)) { | |
497 return dll; | |
498 } | |
499 } | |
500 return null; | |
501 } | |
502 | |
503 public void writeBytesToProcess(long address, long numBytes, byte[] data) | |
504 throws UnmappedAddressException, DebuggerException { | |
505 // FIXME | |
506 throw new DebuggerException("Unimplemented"); | |
507 } | |
508 | |
509 private static String DTFWHome; | |
510 private static String imagePath; | |
511 private static String symbolPath; | |
512 private static boolean useNativeLookup; | |
513 | |
514 static { | |
515 | |
516 /* | |
517 * sawindbg.dll depends on dbgeng.dll which | |
518 * itself depends on dbghelp.dll. dbgeng.dll and dbghelp.dll. | |
519 * On systems newer than Windows 2000, these two .dlls are | |
520 * in the standard system directory so we will find them there. | |
521 * On Windows 2000 and earlier, these files do not exist. | |
522 * The user must download Debugging Tools For Windows (DTFW) | |
523 * and install it in order to use SA. | |
524 * | |
525 * We have to make sure we use the two files from the same directory | |
526 * in case there are more than one copy on the system because | |
527 * one version of dbgeng.dll might not be compatible with a | |
528 * different version of dbghelp.dll. | |
529 * We first look for them in the directory pointed at by | |
530 * env. var. DEBUGGINGTOOLSFORWINDOWS, next in the default | |
531 * installation dir for DTFW, and lastly in the standard | |
532 * system directory. We expect that that we will find | |
533 * them in the standard system directory on all systems | |
534 * newer than Windows 2000. | |
535 */ | |
536 String dirName = null; | |
537 DTFWHome = System.getenv("DEBUGGINGTOOLSFORWINDOWS"); | |
538 | |
539 if (DTFWHome == null) { | |
540 // See if we have the files in the default location. | |
541 String sysRoot = System.getenv("SYSTEMROOT"); | |
542 DTFWHome = sysRoot + File.separator + | |
543 ".." + File.separator + "Program Files" + | |
544 File.separator + "Debugging Tools For Windows"; | |
545 } | |
546 | |
547 { | |
548 String dbghelp = DTFWHome + File.separator + "dbghelp.dll"; | |
549 String dbgeng = DTFWHome + File.separator + "dbgeng.dll"; | |
550 File fhelp = new File(dbghelp); | |
551 File feng = new File(dbgeng); | |
552 if (fhelp.exists() && feng.exists()) { | |
553 // found both, we are happy. | |
554 // NOTE: The order of loads is important! If we load dbgeng.dll | |
555 // first, then the dependency - dbghelp.dll - will be loaded | |
556 // from usual DLL search thereby defeating the purpose! | |
557 System.load(dbghelp); | |
558 System.load(dbgeng); | |
559 } else if (! fhelp.exists() && ! feng.exists()) { | |
560 // neither exist. We will ignore this dir and assume | |
561 // they are in the system dir. | |
562 DTFWHome = null; | |
563 } else { | |
564 // one exists but not the other | |
565 //System.err.println("Error: Both files dbghelp.dll and dbgeng.dll " | |
566 // "must exist in directory " + DTFWHome); | |
567 throw new UnsatisfiedLinkError("Both files dbghelp.dll and " + | |
568 "dbgeng.dll must exist in " + | |
569 "directory " + DTFWHome); | |
570 } | |
571 } | |
572 if (DTFWHome == null) { | |
573 // The files better be in the system dir. | |
574 String sysDir = System.getenv("SYSTEMROOT") + | |
575 File.separator + "system32"; | |
576 | |
577 File feng = new File(sysDir + File.separator + "dbgeng.dll"); | |
578 if (!feng.exists()) { | |
579 throw new UnsatisfiedLinkError("File dbgeng.dll does not exist in " + | |
580 sysDir + ". Please search microsoft.com " + | |
581 "for Debugging Tools For Windows, and " + | |
582 "either download it to the default " + | |
583 "location, or download it to a custom " + | |
584 "location and set environment variable " + | |
585 " DEBUGGINGTOOLSFORWINDOWS " + | |
586 "to the pathname of that location."); | |
587 } | |
588 } | |
589 | |
590 // Now, load sawindbg.dll | |
591 System.loadLibrary("sawindbg"); | |
592 // where do I find '.exe', '.dll' files? | |
593 imagePath = System.getProperty("sun.jvm.hotspot.debugger.windbg.imagePath"); | |
594 if (imagePath == null) { | |
595 imagePath = System.getenv("PATH"); | |
596 } | |
597 | |
598 // where do I find '.pdb', '.dbg' files? | |
599 symbolPath = System.getProperty("sun.jvm.hotspot.debugger.windbg.symbolPath"); | |
600 | |
601 // mostly, debug files would be find where .dll's, .exe's are found. | |
602 if (symbolPath == null) { | |
603 symbolPath = imagePath; | |
604 } | |
605 | |
606 // should we parse DLL symbol table in Java code or use | |
607 // Windbg's native lookup facility? By default, we use | |
608 // native lookup so that we can take advantage of '.pdb' | |
609 // files, if available. | |
610 useNativeLookup = true; | |
611 String str = System.getProperty("sun.jvm.hotspot.debugger.windbg.disableNativeLookup"); | |
612 if (str != null) { | |
613 useNativeLookup = false; | |
614 } | |
615 | |
616 initIDs(); | |
617 } | |
618 | |
619 // native methods | |
620 private static native void initIDs(); | |
621 private native void attach0(String executableName, String coreFileName); | |
622 private native void attach0(int processID); | |
623 private native void detach0(); | |
624 private native byte[] readBytesFromProcess0(long address, long numBytes) | |
625 throws UnmappedAddressException, DebuggerException; | |
626 private native long getThreadIdFromSysId0(long sysId); | |
627 private native String consoleExecuteCommand0(String cmd); | |
628 private native long lookupByName0(String objName, String symName); | |
629 private native ClosestSymbol lookupByAddress0(long address); | |
630 | |
631 // helper called lookupByAddress0 | |
632 private ClosestSymbol createClosestSymbol(String symbol, long diff) { | |
633 return new ClosestSymbol(symbol, diff); | |
634 } | |
635 } |