Mercurial > hg > truffle
annotate agent/src/os/win32/windbg/sawindbg.cpp @ 4117:a04a201f0f5a
7108383: JSR 292: JRuby bench_define_method_methods.rb: assert(slow_jvms != NULL) failed: miss path must not
Reviewed-by: kvn, never
author | twisti |
---|---|
date | Thu, 17 Nov 2011 04:07:30 -0800 |
parents | c18cbe5936b8 |
children | 9fae07c31641 |
rev | line source |
---|---|
0 | 1 /* |
1552
c18cbe5936b8
6941466: Oracle rebranding changes for Hotspot repositories
trims
parents:
0
diff
changeset
|
2 * Copyright (c) 2002, 2007, 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 // this is source code windbg based SA debugger agent to debug | |
26 // Dr. Watson dump files and process snapshots. | |
27 | |
28 #include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h" | |
29 | |
30 #ifdef _M_IA64 | |
31 #include "sun_jvm_hotspot_debugger_ia64_IA64ThreadContext.h" | |
32 #define NPRGREG sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_NPRGREG | |
33 #elif _M_IX86 | |
34 #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h" | |
35 #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG | |
36 #elif _M_AMD64 | |
37 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" | |
38 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG | |
39 #else | |
40 #error "SA windbg back-end is not supported for your cpu!" | |
41 #endif | |
42 | |
43 #include <limits.h> | |
44 #include <windows.h> | |
45 | |
46 #ifndef STDMETHODV | |
47 #define STDMETHODV(method) virtual HRESULT STDMETHODVCALLTYPE method | |
48 #endif | |
49 | |
50 #define DEBUG_NO_IMPLEMENTATION | |
51 #include <dbgeng.h> | |
52 #include <dbghelp.h> | |
53 | |
54 // simple template to manage array delete across early (error) returns | |
55 | |
56 template <class T> | |
57 class AutoArrayPtr { | |
58 T* m_ptr; | |
59 public: | |
60 AutoArrayPtr(T* ptr) : m_ptr(ptr) { | |
61 } | |
62 | |
63 ~AutoArrayPtr() { | |
64 delete [] m_ptr; | |
65 } | |
66 | |
67 T* asPtr() { | |
68 return m_ptr; | |
69 } | |
70 }; | |
71 | |
72 class AutoJavaString { | |
73 JNIEnv* m_env; | |
74 jstring m_str; | |
75 const char* m_buf; | |
76 | |
77 public: | |
78 AutoJavaString(JNIEnv* env, jstring str, const char* buf) | |
79 : m_env(env), m_str(str), m_buf(buf) { | |
80 } | |
81 | |
82 ~AutoJavaString() { | |
83 m_env->ReleaseStringUTFChars(m_str, m_buf); | |
84 } | |
85 | |
86 operator const char* () { | |
87 return m_buf; | |
88 } | |
89 }; | |
90 | |
91 // field and method IDs we want here | |
92 | |
93 static jfieldID imagePath_ID = 0; | |
94 static jfieldID symbolPath_ID = 0; | |
95 static jfieldID ptrIDebugClient_ID = 0; | |
96 static jfieldID ptrIDebugControl_ID = 0; | |
97 static jfieldID ptrIDebugDataSpaces_ID = 0; | |
98 static jfieldID ptrIDebugOutputCallbacks_ID = 0; | |
99 static jfieldID ptrIDebugAdvanced_ID = 0; | |
100 static jfieldID ptrIDebugSymbols_ID = 0; | |
101 static jfieldID ptrIDebugSystemObjects_ID = 0; | |
102 | |
103 static jmethodID addLoadObject_ID = 0; | |
104 static jmethodID addThread_ID = 0; | |
105 static jmethodID createClosestSymbol_ID = 0; | |
106 static jmethodID setThreadIntegerRegisterSet_ID = 0; | |
107 | |
108 #define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; } | |
109 #define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;} | |
110 | |
111 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { \ | |
112 throwNewDebuggerException(env, str); return value; } | |
113 | |
114 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); \ | |
115 return;} | |
116 | |
117 static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) { | |
118 env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg); | |
119 } | |
120 | |
121 /* | |
122 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
123 * Method: initIDs | |
124 * Signature: ()V | |
125 */ | |
126 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_initIDs | |
127 (JNIEnv *env, jclass clazz) { | |
128 imagePath_ID = env->GetStaticFieldID(clazz, "imagePath", "Ljava/lang/String;"); | |
129 CHECK_EXCEPTION; | |
130 | |
131 symbolPath_ID = env->GetStaticFieldID(clazz, "symbolPath", "Ljava/lang/String;"); | |
132 CHECK_EXCEPTION; | |
133 | |
134 ptrIDebugClient_ID = env->GetFieldID(clazz, "ptrIDebugClient", "J"); | |
135 CHECK_EXCEPTION; | |
136 | |
137 ptrIDebugControl_ID = env->GetFieldID(clazz, "ptrIDebugControl", "J"); | |
138 CHECK_EXCEPTION; | |
139 | |
140 ptrIDebugDataSpaces_ID = env->GetFieldID(clazz, "ptrIDebugDataSpaces", "J"); | |
141 CHECK_EXCEPTION; | |
142 | |
143 ptrIDebugOutputCallbacks_ID = env->GetFieldID(clazz, | |
144 "ptrIDebugOutputCallbacks", "J"); | |
145 CHECK_EXCEPTION; | |
146 | |
147 ptrIDebugAdvanced_ID = env->GetFieldID(clazz, "ptrIDebugAdvanced", "J"); | |
148 CHECK_EXCEPTION; | |
149 | |
150 ptrIDebugSymbols_ID = env->GetFieldID(clazz, | |
151 "ptrIDebugSymbols", "J"); | |
152 CHECK_EXCEPTION; | |
153 | |
154 ptrIDebugSystemObjects_ID = env->GetFieldID(clazz, | |
155 "ptrIDebugSystemObjects", "J"); | |
156 CHECK_EXCEPTION; | |
157 | |
158 addLoadObject_ID = env->GetMethodID(clazz, "addLoadObject", | |
159 "(Ljava/lang/String;JJ)V"); | |
160 CHECK_EXCEPTION; | |
161 | |
162 addThread_ID = env->GetMethodID(clazz, "addThread", "(J)V"); | |
163 CHECK_EXCEPTION; | |
164 | |
165 createClosestSymbol_ID = env->GetMethodID(clazz, "createClosestSymbol", | |
166 "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;"); | |
167 CHECK_EXCEPTION; | |
168 | |
169 setThreadIntegerRegisterSet_ID = env->GetMethodID(clazz, | |
170 "setThreadIntegerRegisterSet", "(J[J)V"); | |
171 CHECK_EXCEPTION; | |
172 | |
173 } | |
174 | |
175 // class for IDebugOutputCallbacks | |
176 | |
177 class SAOutputCallbacks : public IDebugOutputCallbacks { | |
178 LONG m_refCount; | |
179 char* m_msgBuffer; | |
180 | |
181 public: | |
182 SAOutputCallbacks() : m_refCount(0), m_msgBuffer(0) { | |
183 } | |
184 | |
185 ~SAOutputCallbacks() { | |
186 clearBuffer(); | |
187 } | |
188 | |
189 const char* getBuffer() const { | |
190 return m_msgBuffer; | |
191 } | |
192 | |
193 void clearBuffer() { | |
194 if (m_msgBuffer) { | |
195 free(m_msgBuffer); | |
196 m_msgBuffer = 0; | |
197 } | |
198 } | |
199 | |
200 STDMETHOD_(ULONG, AddRef)(THIS); | |
201 STDMETHOD_(ULONG, Release)(THIS); | |
202 STDMETHOD(QueryInterface)(THIS_ | |
203 IN REFIID interfaceId, | |
204 OUT PVOID* ppInterface); | |
205 STDMETHOD(Output)(THIS_ | |
206 IN ULONG mask, | |
207 IN PCSTR msg); | |
208 }; | |
209 | |
210 STDMETHODIMP_(ULONG) SAOutputCallbacks::AddRef(THIS) { | |
211 InterlockedIncrement(&m_refCount); | |
212 return m_refCount; | |
213 } | |
214 | |
215 STDMETHODIMP_(ULONG) SAOutputCallbacks::Release(THIS) { | |
216 LONG retVal; | |
217 InterlockedDecrement(&m_refCount); | |
218 retVal = m_refCount; | |
219 if (retVal == 0) { | |
220 delete this; | |
221 } | |
222 return retVal; | |
223 } | |
224 | |
225 STDMETHODIMP SAOutputCallbacks::QueryInterface(THIS_ | |
226 IN REFIID interfaceId, | |
227 OUT PVOID* ppInterface) { | |
228 *ppInterface = 0; | |
229 HRESULT res = E_NOINTERFACE; | |
230 if (TRUE == IsEqualIID(interfaceId, __uuidof(IUnknown)) || | |
231 TRUE == IsEqualIID(interfaceId, __uuidof(IDebugOutputCallbacks))) { | |
232 *ppInterface = (IDebugOutputCallbacks*) this; | |
233 AddRef(); | |
234 res = S_OK; | |
235 } | |
236 return res; | |
237 } | |
238 | |
239 STDMETHODIMP SAOutputCallbacks::Output(THIS_ | |
240 IN ULONG mask, | |
241 IN PCSTR msg) { | |
242 int len = (int) (strlen(msg) + 1); | |
243 if (m_msgBuffer == 0) { | |
244 m_msgBuffer = (char*) malloc(len); | |
245 if (m_msgBuffer == 0) { | |
246 fprintf(stderr, "out of memory debugger output!\n"); | |
247 return S_FALSE; | |
248 } | |
249 strcpy(m_msgBuffer, msg); | |
250 } else { | |
251 m_msgBuffer = (char*) realloc(m_msgBuffer, len + strlen(m_msgBuffer)); | |
252 if (m_msgBuffer == 0) { | |
253 fprintf(stderr, "out of memory debugger output!\n"); | |
254 return S_FALSE; | |
255 } | |
256 strcat(m_msgBuffer, msg); | |
257 } | |
258 return S_OK; | |
259 } | |
260 | |
261 static bool getWindbgInterfaces(JNIEnv* env, jobject obj) { | |
262 // get windbg interfaces .. | |
263 | |
264 IDebugClient* ptrIDebugClient = 0; | |
265 if (DebugCreate(__uuidof(IDebugClient), (PVOID*) &ptrIDebugClient) != S_OK) { | |
266 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to create IDebugClient object!", false); | |
267 } | |
268 env->SetLongField(obj, ptrIDebugClient_ID, (jlong) ptrIDebugClient); | |
269 | |
270 IDebugControl* ptrIDebugControl = 0; | |
271 if (ptrIDebugClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &ptrIDebugControl) | |
272 != S_OK) { | |
273 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugControl", false); | |
274 } | |
275 env->SetLongField(obj, ptrIDebugControl_ID, (jlong) ptrIDebugControl); | |
276 | |
277 IDebugDataSpaces* ptrIDebugDataSpaces = 0; | |
278 if (ptrIDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (PVOID*) &ptrIDebugDataSpaces) | |
279 != S_OK) { | |
280 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugDataSpaces object!", false); | |
281 } | |
282 env->SetLongField(obj, ptrIDebugDataSpaces_ID, (jlong) ptrIDebugDataSpaces); | |
283 | |
284 SAOutputCallbacks* ptrIDebugOutputCallbacks = new SAOutputCallbacks(); | |
285 ptrIDebugOutputCallbacks->AddRef(); | |
286 env->SetLongField(obj, ptrIDebugOutputCallbacks_ID, (jlong) ptrIDebugOutputCallbacks); | |
287 CHECK_EXCEPTION_(false); | |
288 | |
289 IDebugAdvanced* ptrIDebugAdvanced = 0; | |
290 if (ptrIDebugClient->QueryInterface(__uuidof(IDebugAdvanced), (PVOID*) &ptrIDebugAdvanced) | |
291 != S_OK) { | |
292 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugAdvanced object!", false); | |
293 } | |
294 env->SetLongField(obj, ptrIDebugAdvanced_ID, (jlong) ptrIDebugAdvanced); | |
295 | |
296 IDebugSymbols* ptrIDebugSymbols = 0; | |
297 if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSymbols), (PVOID*) &ptrIDebugSymbols) | |
298 != S_OK) { | |
299 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSymbols object!", false); | |
300 } | |
301 env->SetLongField(obj, ptrIDebugSymbols_ID, (jlong) ptrIDebugSymbols); | |
302 | |
303 IDebugSystemObjects* ptrIDebugSystemObjects = 0; | |
304 if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSystemObjects), (PVOID*) &ptrIDebugSystemObjects) | |
305 != S_OK) { | |
306 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSystemObjects object!", false); | |
307 } | |
308 env->SetLongField(obj, ptrIDebugSystemObjects_ID, (jlong) ptrIDebugSystemObjects); | |
309 | |
310 return true; | |
311 } | |
312 | |
313 static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) { | |
314 jboolean isCopy; | |
315 jclass clazz = env->GetObjectClass(obj); | |
316 jstring path; | |
317 const char* buf; | |
318 | |
319 path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID); | |
320 buf = env->GetStringUTFChars(path, &isCopy); | |
321 CHECK_EXCEPTION_(false); | |
322 AutoJavaString imagePath(env, path, buf); | |
323 | |
324 path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID); | |
325 buf = env->GetStringUTFChars(path, &isCopy); | |
326 CHECK_EXCEPTION_(false); | |
327 AutoJavaString symbolPath(env, path, buf); | |
328 | |
329 IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, | |
330 ptrIDebugSymbols_ID); | |
331 CHECK_EXCEPTION_(false); | |
332 | |
333 ptrIDebugSymbols->SetImagePath(imagePath); | |
334 ptrIDebugSymbols->SetSymbolPath(symbolPath); | |
335 return true; | |
336 } | |
337 | |
338 static bool openDumpFile(JNIEnv* env, jobject obj, jstring coreFileName) { | |
339 // open the dump file | |
340 jboolean isCopy; | |
341 const char* buf = env->GetStringUTFChars(coreFileName, &isCopy); | |
342 CHECK_EXCEPTION_(false); | |
343 AutoJavaString coreFile(env, coreFileName, buf); | |
344 if (setImageAndSymbolPath(env, obj) == false) { | |
345 return false; | |
346 } | |
347 | |
348 IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, | |
349 ptrIDebugClient_ID); | |
350 CHECK_EXCEPTION_(false); | |
351 if (ptrIDebugClient->OpenDumpFile(coreFile) != S_OK) { | |
352 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: OpenDumpFile failed!", false); | |
353 } | |
354 | |
355 IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, | |
356 ptrIDebugControl_ID); | |
357 CHECK_EXCEPTION_(false); | |
358 if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) { | |
359 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false); | |
360 } | |
361 | |
362 return true; | |
363 } | |
364 | |
365 | |
366 static bool attachToProcess(JNIEnv* env, jobject obj, jint pid) { | |
367 if (setImageAndSymbolPath(env, obj) == false) { | |
368 return false; | |
369 } | |
370 IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, | |
371 ptrIDebugClient_ID); | |
372 CHECK_EXCEPTION_(false); | |
373 | |
374 /*********************************************************************************** | |
375 | |
376 We are attaching to a process in 'read-only' mode. i.e., we do not want to | |
377 put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of | |
378 usage this should suffice. We are not intending to use this for full-fledged | |
379 ProcessControl implementation to be used with BugSpotAgent. | |
380 | |
381 Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h. | |
382 In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not | |
383 actually debugging at all. We can safely 'detach' from the process anytime | |
384 we want and debuggee process is left as is on all Windows variants. | |
385 | |
386 This also makes JDI-on-SA installation/usage simpler because with this we would | |
387 not need a tool like ServiceInstaller from http://www.kcmultimedia.com/smaster. | |
388 | |
389 ***********************************************************************************/ | |
390 | |
391 | |
392 if (ptrIDebugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE) != S_OK) { | |
393 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: AttachProcess failed!", false); | |
394 } | |
395 | |
396 IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, | |
397 ptrIDebugControl_ID); | |
398 CHECK_EXCEPTION_(false); | |
399 if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) { | |
400 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false); | |
401 } | |
402 | |
403 return true; | |
404 } | |
405 | |
406 | |
407 static bool addLoadObjects(JNIEnv* env, jobject obj) { | |
408 IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, | |
409 ptrIDebugSymbols_ID); | |
410 CHECK_EXCEPTION_(false); | |
411 ULONG loaded = 0, unloaded = 0; | |
412 if (ptrIDebugSymbols->GetNumberModules(&loaded, &unloaded) != S_OK) { | |
413 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberModules failed!", false); | |
414 } | |
415 | |
416 AutoArrayPtr<DEBUG_MODULE_PARAMETERS> params(new DEBUG_MODULE_PARAMETERS[loaded]); | |
417 | |
418 if (params.asPtr() == 0) { | |
419 THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate debug module params!", false); | |
420 } | |
421 | |
422 if (ptrIDebugSymbols->GetModuleParameters(loaded, 0, NULL, params.asPtr()) != S_OK) { | |
423 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleParameters failed!", false); | |
424 } | |
425 | |
426 for (int u = 0; u < (int)loaded; u++) { | |
427 TCHAR imageName[MAX_PATH]; | |
428 if (ptrIDebugSymbols->GetModuleNames(DEBUG_ANY_ID, params.asPtr()[u].Base, | |
429 imageName, MAX_PATH, NULL, NULL, | |
430 0, NULL, NULL, 0, NULL) != S_OK) { | |
431 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleNames failed!", false); | |
432 } | |
433 | |
434 jstring strName = env->NewStringUTF(imageName); | |
435 CHECK_EXCEPTION_(false); | |
436 env->CallVoidMethod(obj, addLoadObject_ID, strName, (jlong) params.asPtr()[u].Size, | |
437 (jlong) params.asPtr()[u].Base); | |
438 CHECK_EXCEPTION_(false); | |
439 } | |
440 | |
441 return true; | |
442 } | |
443 | |
444 static bool addThreads(JNIEnv* env, jobject obj) { | |
445 IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, | |
446 ptrIDebugSystemObjects_ID); | |
447 CHECK_EXCEPTION_(false); | |
448 | |
449 ULONG numThreads = 0; | |
450 if (ptrIDebugSystemObjects->GetNumberThreads(&numThreads) != S_OK) { | |
451 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberThreads failed!", false); | |
452 } | |
453 | |
454 AutoArrayPtr<ULONG> ptrSysThreadIds = new ULONG[numThreads]; | |
455 | |
456 if (ptrSysThreadIds.asPtr() == 0) { | |
457 THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false); | |
458 } | |
459 | |
460 AutoArrayPtr<ULONG> ptrThreadIds = new ULONG[numThreads]; | |
461 | |
462 if (ptrThreadIds.asPtr() == 0) { | |
463 THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false); | |
464 } | |
465 | |
466 if (ptrIDebugSystemObjects->GetThreadIdsByIndex(0, numThreads, | |
467 ptrThreadIds.asPtr(), ptrSysThreadIds.asPtr()) != S_OK) { | |
468 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdsByIndex failed!", false); | |
469 } | |
470 | |
471 | |
472 IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj, | |
473 ptrIDebugAdvanced_ID); | |
474 CHECK_EXCEPTION_(false); | |
475 | |
476 // for each thread, get register context and save it. | |
477 for (ULONG t = 0; t < numThreads; t++) { | |
478 if (ptrIDebugSystemObjects->SetCurrentThreadId(ptrThreadIds.asPtr()[t]) != S_OK) { | |
479 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetCurrentThread failed!", false); | |
480 } | |
481 | |
482 jlongArray regs = env->NewLongArray(NPRGREG); | |
483 CHECK_EXCEPTION_(false); | |
484 | |
485 jboolean isCopy = JNI_FALSE; | |
486 jlong* ptrRegs = env->GetLongArrayElements(regs, &isCopy); | |
487 CHECK_EXCEPTION_(false); | |
488 | |
489 // copy register values from the CONTEXT struct | |
490 CONTEXT context; | |
491 memset(&context, 0, sizeof(CONTEXT)); | |
492 | |
493 #undef REG_INDEX | |
494 #ifdef _M_IA64 | |
495 #define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x | |
496 | |
497 context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG; | |
498 ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); | |
499 | |
500 ptrRegs[REG_INDEX(GR0)] = 0; // always 0 | |
501 ptrRegs[REG_INDEX(GR1)] = context.IntGp; // r1 | |
502 ptrRegs[REG_INDEX(GR2)] = context.IntT0; // r2-r3 | |
503 ptrRegs[REG_INDEX(GR3)] = context.IntT1; | |
504 ptrRegs[REG_INDEX(GR4)] = context.IntS0; // r4-r7 | |
505 ptrRegs[REG_INDEX(GR5)] = context.IntS1; | |
506 ptrRegs[REG_INDEX(GR6)] = context.IntS2; | |
507 ptrRegs[REG_INDEX(GR7)] = context.IntS3; | |
508 ptrRegs[REG_INDEX(GR8)] = context.IntV0; // r8 | |
509 ptrRegs[REG_INDEX(GR9)] = context.IntT2; // r9-r11 | |
510 ptrRegs[REG_INDEX(GR10)] = context.IntT3; | |
511 ptrRegs[REG_INDEX(GR11)] = context.IntT4; | |
512 ptrRegs[REG_INDEX(GR12)] = context.IntSp; // r12 stack pointer | |
513 ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb | |
514 ptrRegs[REG_INDEX(GR14)] = context.IntT5; // r14-r31 | |
515 ptrRegs[REG_INDEX(GR15)] = context.IntT6; | |
516 ptrRegs[REG_INDEX(GR16)] = context.IntT7; | |
517 ptrRegs[REG_INDEX(GR17)] = context.IntT8; | |
518 ptrRegs[REG_INDEX(GR18)] = context.IntT9; | |
519 ptrRegs[REG_INDEX(GR19)] = context.IntT10; | |
520 ptrRegs[REG_INDEX(GR20)] = context.IntT11; | |
521 ptrRegs[REG_INDEX(GR21)] = context.IntT12; | |
522 ptrRegs[REG_INDEX(GR22)] = context.IntT13; | |
523 ptrRegs[REG_INDEX(GR23)] = context.IntT14; | |
524 ptrRegs[REG_INDEX(GR24)] = context.IntT15; | |
525 ptrRegs[REG_INDEX(GR25)] = context.IntT16; | |
526 ptrRegs[REG_INDEX(GR26)] = context.IntT17; | |
527 ptrRegs[REG_INDEX(GR27)] = context.IntT18; | |
528 ptrRegs[REG_INDEX(GR28)] = context.IntT19; | |
529 ptrRegs[REG_INDEX(GR29)] = context.IntT20; | |
530 ptrRegs[REG_INDEX(GR30)] = context.IntT21; | |
531 ptrRegs[REG_INDEX(GR31)] = context.IntT22; | |
532 | |
533 ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats; | |
534 ptrRegs[REG_INDEX(PREDS)] = context.Preds; | |
535 | |
536 ptrRegs[REG_INDEX(BR_RP)] = context.BrRp; | |
537 ptrRegs[REG_INDEX(BR1)] = context.BrS0; // b1-b5 | |
538 ptrRegs[REG_INDEX(BR2)] = context.BrS1; | |
539 ptrRegs[REG_INDEX(BR3)] = context.BrS2; | |
540 ptrRegs[REG_INDEX(BR4)] = context.BrS3; | |
541 ptrRegs[REG_INDEX(BR5)] = context.BrS4; | |
542 ptrRegs[REG_INDEX(BR6)] = context.BrT0; // b6-b7 | |
543 ptrRegs[REG_INDEX(BR7)] = context.BrT1; | |
544 | |
545 ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT; | |
546 ptrRegs[REG_INDEX(AP_LC)] = context.ApLC; | |
547 ptrRegs[REG_INDEX(AP_EC)] = context.ApEC; | |
548 ptrRegs[REG_INDEX(AP_CCV)] = context.ApCCV; | |
549 ptrRegs[REG_INDEX(AP_DCR)] = context.ApDCR; | |
550 | |
551 ptrRegs[REG_INDEX(RS_PFS)] = context.RsPFS; | |
552 ptrRegs[REG_INDEX(RS_BSP)] = context.RsBSP; | |
553 ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE; | |
554 ptrRegs[REG_INDEX(RS_RSC)] = context.RsRSC; | |
555 ptrRegs[REG_INDEX(RS_RNAT)] = context.RsRNAT; | |
556 | |
557 ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR; | |
558 ptrRegs[REG_INDEX(ST_IIP)] = context.StIIP; | |
559 ptrRegs[REG_INDEX(ST_IFS)] = context.StIFS; | |
560 | |
561 ptrRegs[REG_INDEX(DB_I0)] = context.DbI0; | |
562 ptrRegs[REG_INDEX(DB_I1)] = context.DbI1; | |
563 ptrRegs[REG_INDEX(DB_I2)] = context.DbI2; | |
564 ptrRegs[REG_INDEX(DB_I3)] = context.DbI3; | |
565 ptrRegs[REG_INDEX(DB_I4)] = context.DbI4; | |
566 ptrRegs[REG_INDEX(DB_I5)] = context.DbI5; | |
567 ptrRegs[REG_INDEX(DB_I6)] = context.DbI6; | |
568 ptrRegs[REG_INDEX(DB_I7)] = context.DbI7; | |
569 | |
570 ptrRegs[REG_INDEX(DB_D0)] = context.DbD0; | |
571 ptrRegs[REG_INDEX(DB_D1)] = context.DbD1; | |
572 ptrRegs[REG_INDEX(DB_D2)] = context.DbD2; | |
573 ptrRegs[REG_INDEX(DB_D3)] = context.DbD3; | |
574 ptrRegs[REG_INDEX(DB_D4)] = context.DbD4; | |
575 ptrRegs[REG_INDEX(DB_D5)] = context.DbD5; | |
576 ptrRegs[REG_INDEX(DB_D6)] = context.DbD6; | |
577 ptrRegs[REG_INDEX(DB_D7)] = context.DbD7; | |
578 | |
579 #elif _M_IX86 | |
580 #define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x | |
581 | |
582 context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; | |
583 ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); | |
584 | |
585 ptrRegs[REG_INDEX(GS)] = context.SegGs; | |
586 ptrRegs[REG_INDEX(FS)] = context.SegFs; | |
587 ptrRegs[REG_INDEX(ES)] = context.SegEs; | |
588 ptrRegs[REG_INDEX(DS)] = context.SegDs; | |
589 | |
590 ptrRegs[REG_INDEX(EDI)] = context.Edi; | |
591 ptrRegs[REG_INDEX(ESI)] = context.Esi; | |
592 ptrRegs[REG_INDEX(EBX)] = context.Ebx; | |
593 ptrRegs[REG_INDEX(EDX)] = context.Edx; | |
594 ptrRegs[REG_INDEX(ECX)] = context.Ecx; | |
595 ptrRegs[REG_INDEX(EAX)] = context.Eax; | |
596 | |
597 ptrRegs[REG_INDEX(FP)] = context.Ebp; | |
598 ptrRegs[REG_INDEX(PC)] = context.Eip; | |
599 ptrRegs[REG_INDEX(CS)] = context.SegCs; | |
600 ptrRegs[REG_INDEX(EFL)] = context.EFlags; | |
601 ptrRegs[REG_INDEX(SP)] = context.Esp; | |
602 ptrRegs[REG_INDEX(SS)] = context.SegSs; | |
603 | |
604 ptrRegs[REG_INDEX(DR0)] = context.Dr0; | |
605 ptrRegs[REG_INDEX(DR1)] = context.Dr1; | |
606 ptrRegs[REG_INDEX(DR2)] = context.Dr2; | |
607 ptrRegs[REG_INDEX(DR3)] = context.Dr3; | |
608 ptrRegs[REG_INDEX(DR6)] = context.Dr6; | |
609 ptrRegs[REG_INDEX(DR7)] = context.Dr7; | |
610 | |
611 #elif _M_AMD64 | |
612 #define REG_INDEX(x) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##x | |
613 | |
614 context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; | |
615 ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); | |
616 | |
617 // Segment Registers and processor flags | |
618 ptrRegs[REG_INDEX(CS)] = context.SegCs; | |
619 ptrRegs[REG_INDEX(DS)] = context.SegDs; | |
620 ptrRegs[REG_INDEX(ES)] = context.SegEs; | |
621 ptrRegs[REG_INDEX(FS)] = context.SegFs; | |
622 ptrRegs[REG_INDEX(GS)] = context.SegGs; | |
623 ptrRegs[REG_INDEX(SS)] = context.SegSs; | |
624 ptrRegs[REG_INDEX(RFL)] = context.EFlags; | |
625 | |
626 // Integer registers | |
627 ptrRegs[REG_INDEX(RDI)] = context.Rdi; | |
628 ptrRegs[REG_INDEX(RSI)] = context.Rsi; | |
629 ptrRegs[REG_INDEX(RAX)] = context.Rax; | |
630 ptrRegs[REG_INDEX(RCX)] = context.Rcx; | |
631 ptrRegs[REG_INDEX(RDX)] = context.Rdx; | |
632 ptrRegs[REG_INDEX(RBX)] = context.Rbx; | |
633 ptrRegs[REG_INDEX(RBP)] = context.Rbp; | |
634 ptrRegs[REG_INDEX(RSP)] = context.Rsp; | |
635 | |
636 ptrRegs[REG_INDEX(R8)] = context.R8; | |
637 ptrRegs[REG_INDEX(R9)] = context.R9; | |
638 ptrRegs[REG_INDEX(R10)] = context.R10; | |
639 ptrRegs[REG_INDEX(R11)] = context.R11; | |
640 ptrRegs[REG_INDEX(R12)] = context.R12; | |
641 ptrRegs[REG_INDEX(R13)] = context.R13; | |
642 ptrRegs[REG_INDEX(R14)] = context.R14; | |
643 ptrRegs[REG_INDEX(R15)] = context.R15; | |
644 | |
645 // Program counter | |
646 ptrRegs[REG_INDEX(RIP)] = context.Rip; | |
647 #endif | |
648 | |
649 env->ReleaseLongArrayElements(regs, ptrRegs, JNI_COMMIT); | |
650 CHECK_EXCEPTION_(false); | |
651 | |
652 env->CallVoidMethod(obj, setThreadIntegerRegisterSet_ID, | |
653 (jlong) ptrThreadIds.asPtr()[t], regs); | |
654 CHECK_EXCEPTION_(false); | |
655 | |
656 ULONG sysId; | |
657 if (ptrIDebugSystemObjects->GetCurrentThreadSystemId(&sysId) != S_OK) { | |
658 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetCurrentThreadSystemId failed!", false); | |
659 } | |
660 | |
661 env->CallVoidMethod(obj, addThread_ID, (jlong) sysId); | |
662 CHECK_EXCEPTION_(false); | |
663 } | |
664 | |
665 return true; | |
666 } | |
667 | |
668 /* | |
669 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
670 * Method: attach0 | |
671 * Signature: (Ljava/lang/String;Ljava/lang/String;)V | |
672 */ | |
673 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 | |
674 (JNIEnv *env, jobject obj, jstring execName, jstring coreFileName) { | |
675 | |
676 if (getWindbgInterfaces(env, obj) == false) { | |
677 return; | |
678 } | |
679 | |
680 if (openDumpFile(env, obj, coreFileName) == false) { | |
681 return; | |
682 } | |
683 | |
684 if (addLoadObjects(env, obj) == false) { | |
685 return; | |
686 } | |
687 | |
688 if (addThreads(env, obj) == false) { | |
689 return; | |
690 } | |
691 } | |
692 | |
693 /* | |
694 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
695 * Method: attach0 | |
696 * Signature: (I)V | |
697 */ | |
698 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__I | |
699 (JNIEnv *env, jobject obj, jint pid) { | |
700 | |
701 if (getWindbgInterfaces(env, obj) == false) { | |
702 return; | |
703 } | |
704 | |
705 if (attachToProcess(env, obj, pid) == false) { | |
706 return; | |
707 } | |
708 | |
709 if (addLoadObjects(env, obj) == false) { | |
710 return; | |
711 } | |
712 | |
713 if (addThreads(env, obj) == false) { | |
714 return; | |
715 } | |
716 } | |
717 | |
718 | |
719 static bool releaseWindbgInterfaces(JNIEnv* env, jobject obj) { | |
720 IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj, | |
721 ptrIDebugDataSpaces_ID); | |
722 CHECK_EXCEPTION_(false); | |
723 if (ptrIDebugDataSpaces != 0) { | |
724 ptrIDebugDataSpaces->Release(); | |
725 } | |
726 | |
727 IDebugOutputCallbacks* ptrIDebugOutputCallbacks = (IDebugOutputCallbacks*) | |
728 env->GetLongField(obj, ptrIDebugOutputCallbacks_ID); | |
729 CHECK_EXCEPTION_(false); | |
730 if (ptrIDebugOutputCallbacks != 0) { | |
731 ptrIDebugOutputCallbacks->Release(); | |
732 } | |
733 | |
734 IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj, | |
735 ptrIDebugAdvanced_ID); | |
736 CHECK_EXCEPTION_(false); | |
737 | |
738 if (ptrIDebugAdvanced != 0) { | |
739 ptrIDebugAdvanced->Release(); | |
740 } | |
741 | |
742 IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, | |
743 ptrIDebugSymbols_ID); | |
744 CHECK_EXCEPTION_(false); | |
745 if (ptrIDebugSymbols != 0) { | |
746 ptrIDebugSymbols->Release(); | |
747 } | |
748 | |
749 IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, | |
750 ptrIDebugSystemObjects_ID); | |
751 CHECK_EXCEPTION_(false); | |
752 if (ptrIDebugSystemObjects != 0) { | |
753 ptrIDebugSystemObjects->Release(); | |
754 } | |
755 | |
756 IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, | |
757 ptrIDebugControl_ID); | |
758 CHECK_EXCEPTION_(false); | |
759 if (ptrIDebugControl != 0) { | |
760 ptrIDebugControl->Release(); | |
761 } | |
762 | |
763 IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, | |
764 ptrIDebugClient_ID); | |
765 CHECK_EXCEPTION_(false); | |
766 if (ptrIDebugClient != 0) { | |
767 ptrIDebugClient->Release(); | |
768 } | |
769 | |
770 return true; | |
771 } | |
772 | |
773 /* | |
774 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
775 * Method: detach0 | |
776 * Signature: ()V | |
777 */ | |
778 JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_detach0 | |
779 (JNIEnv *env, jobject obj) { | |
780 IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, | |
781 ptrIDebugClient_ID); | |
782 CHECK_EXCEPTION; | |
783 ptrIDebugClient->DetachProcesses(); | |
784 releaseWindbgInterfaces(env, obj); | |
785 } | |
786 | |
787 | |
788 /* | |
789 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
790 * Method: readBytesFromProcess0 | |
791 * Signature: (JJ)[B | |
792 */ | |
793 JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_readBytesFromProcess0 | |
794 (JNIEnv *env, jobject obj, jlong address, jlong numBytes) { | |
795 jbyteArray byteArray = env->NewByteArray((long) numBytes); | |
796 CHECK_EXCEPTION_(0); | |
797 | |
798 jboolean isCopy = JNI_FALSE; | |
799 jbyte* bytePtr = env->GetByteArrayElements(byteArray, &isCopy); | |
800 CHECK_EXCEPTION_(0); | |
801 | |
802 IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj, | |
803 ptrIDebugDataSpaces_ID); | |
804 CHECK_EXCEPTION_(0); | |
805 | |
806 ULONG bytesRead; | |
807 if (ptrIDebugDataSpaces->ReadVirtual((ULONG64) address, (PVOID) bytePtr, | |
808 (ULONG)numBytes, &bytesRead) != S_OK) { | |
809 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: ReadVirtual failed!", 0); | |
810 } | |
811 | |
812 if (bytesRead != numBytes) { | |
813 return 0; | |
814 } | |
815 | |
816 env->ReleaseByteArrayElements(byteArray, bytePtr, 0); | |
817 CHECK_EXCEPTION_(0); | |
818 | |
819 return byteArray; | |
820 } | |
821 | |
822 /* | |
823 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
824 * Method: getThreadIdFromSysId0 | |
825 * Signature: (J)J | |
826 */ | |
827 JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_getThreadIdFromSysId0 | |
828 (JNIEnv *env, jobject obj, jlong sysId) { | |
829 IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, | |
830 ptrIDebugSystemObjects_ID); | |
831 CHECK_EXCEPTION_(0); | |
832 | |
833 ULONG id = 0; | |
834 if (ptrIDebugSystemObjects->GetThreadIdBySystemId((ULONG)sysId, &id) != S_OK) { | |
835 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdBySystemId failed!", 0); | |
836 } | |
837 | |
838 return (jlong) id; | |
839 } | |
840 | |
841 // manage COM 'auto' pointers (to avoid multiple Release | |
842 // calls at every early (exception) returns). Similar to AutoArrayPtr. | |
843 | |
844 template <class T> | |
845 class AutoCOMPtr { | |
846 T* m_ptr; | |
847 | |
848 public: | |
849 AutoCOMPtr(T* ptr) : m_ptr(ptr) { | |
850 } | |
851 | |
852 ~AutoCOMPtr() { | |
853 if (m_ptr) { | |
854 m_ptr->Release(); | |
855 } | |
856 } | |
857 | |
858 T* operator->() { | |
859 return m_ptr; | |
860 } | |
861 }; | |
862 | |
863 /* | |
864 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
865 * Method: consoleExecuteCommand0 | |
866 * Signature: (Ljava/lang/String;)Ljava/lang/String; | |
867 */ | |
868 JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_consoleExecuteCommand0 | |
869 (JNIEnv *env, jobject obj, jstring cmd) { | |
870 jboolean isCopy = JNI_FALSE; | |
871 const char* buf = env->GetStringUTFChars(cmd, &isCopy); | |
872 CHECK_EXCEPTION_(0); | |
873 AutoJavaString command(env, cmd, buf); | |
874 | |
875 IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID); | |
876 CHECK_EXCEPTION_(0); | |
877 | |
878 IDebugClient* tmpClientPtr = 0; | |
879 if (ptrIDebugClient->CreateClient(&tmpClientPtr) != S_OK) { | |
880 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: CreateClient failed!", 0); | |
881 } | |
882 AutoCOMPtr<IDebugClient> tmpClient(tmpClientPtr); | |
883 | |
884 IDebugControl* tmpControlPtr = 0; | |
885 if (tmpClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &tmpControlPtr) != S_OK) { | |
886 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: QueryInterface (IDebugControl) failed", 0); | |
887 } | |
888 AutoCOMPtr<IDebugControl> tmpControl(tmpControlPtr); | |
889 | |
890 SAOutputCallbacks* saOutputCallbacks = (SAOutputCallbacks*) env->GetLongField(obj, | |
891 ptrIDebugOutputCallbacks_ID); | |
892 CHECK_EXCEPTION_(0); | |
893 | |
894 saOutputCallbacks->clearBuffer(); | |
895 | |
896 if (tmpClient->SetOutputCallbacks(saOutputCallbacks) != S_OK) { | |
897 THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetOutputCallbacks failed!", 0); | |
898 } | |
899 | |
900 tmpControl->Execute(DEBUG_OUTPUT_VERBOSE, command, DEBUG_EXECUTE_DEFAULT); | |
901 | |
902 const char* output = saOutputCallbacks->getBuffer(); | |
903 if (output == 0) { | |
904 output = ""; | |
905 } | |
906 | |
907 jstring res = env->NewStringUTF(output); | |
908 saOutputCallbacks->clearBuffer(); | |
909 return res; | |
910 } | |
911 | |
912 /* | |
913 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
914 * Method: lookupByName0 | |
915 * Signature: (Ljava/lang/String;Ljava/lang/String;)J | |
916 */ | |
917 | |
918 JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByName0 | |
919 (JNIEnv *env, jobject obj, jstring objName, jstring sym) { | |
920 IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, | |
921 ptrIDebugSymbols_ID); | |
922 CHECK_EXCEPTION_(0); | |
923 | |
924 jboolean isCopy; | |
925 const char* buf = env->GetStringUTFChars(sym, &isCopy); | |
926 CHECK_EXCEPTION_(0); | |
927 AutoJavaString name(env, sym, buf); | |
928 | |
929 ULONG64 offset = 0L; | |
930 if (strstr(name, "::") != 0) { | |
931 ptrIDebugSymbols->AddSymbolOptions(SYMOPT_UNDNAME); | |
932 } else { | |
933 ptrIDebugSymbols->RemoveSymbolOptions(SYMOPT_UNDNAME); | |
934 } | |
935 if (ptrIDebugSymbols->GetOffsetByName(name, &offset) != S_OK) { | |
936 return (jlong) 0; | |
937 } | |
938 return (jlong) offset; | |
939 } | |
940 | |
941 #define SYMBOL_BUFSIZE 512 | |
942 /* | |
943 * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal | |
944 * Method: lookupByAddress0 | |
945 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; | |
946 */ | |
947 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByAddress0 | |
948 (JNIEnv *env, jobject obj, jlong address) { | |
949 IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, | |
950 ptrIDebugSymbols_ID); | |
951 CHECK_EXCEPTION_(0); | |
952 | |
953 ULONG64 disp = 0L; | |
954 char buf[SYMBOL_BUFSIZE]; | |
955 memset(buf, 0, sizeof(buf)); | |
956 | |
957 if (ptrIDebugSymbols->GetNameByOffset(address, buf, sizeof(buf),0,&disp) | |
958 != S_OK) { | |
959 return 0; | |
960 } | |
961 | |
962 jstring sym = env->NewStringUTF(buf); | |
963 CHECK_EXCEPTION_(0); | |
964 jobject res = env->CallObjectMethod(obj, createClosestSymbol_ID, sym, disp); | |
965 CHECK_EXCEPTION_(0); | |
966 return res; | |
967 } |