1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/agent/src/os/win32/windbg/sawindbg.cpp Sat Dec 01 00:00:00 2007 +0000 1.3 @@ -0,0 +1,967 @@ 1.4 +/* 1.5 + * Copyright 2002-2007 Sun Microsystems, Inc. All Rights Reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. 1.11 + * 1.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.15 + * version 2 for more details (a copy is included in the LICENSE file that 1.16 + * accompanied this code). 1.17 + * 1.18 + * You should have received a copy of the GNU General Public License version 1.19 + * 2 along with this work; if not, write to the Free Software Foundation, 1.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.21 + * 1.22 + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 1.23 + * CA 95054 USA or visit www.sun.com if you need additional information or 1.24 + * have any questions. 1.25 + * 1.26 + */ 1.27 + 1.28 +// this is source code windbg based SA debugger agent to debug 1.29 +// Dr. Watson dump files and process snapshots. 1.30 + 1.31 +#include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h" 1.32 + 1.33 +#ifdef _M_IA64 1.34 + #include "sun_jvm_hotspot_debugger_ia64_IA64ThreadContext.h" 1.35 + #define NPRGREG sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_NPRGREG 1.36 +#elif _M_IX86 1.37 + #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h" 1.38 + #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG 1.39 +#elif _M_AMD64 1.40 + #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" 1.41 + #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG 1.42 +#else 1.43 + #error "SA windbg back-end is not supported for your cpu!" 1.44 +#endif 1.45 + 1.46 +#include <limits.h> 1.47 +#include <windows.h> 1.48 + 1.49 +#ifndef STDMETHODV 1.50 +#define STDMETHODV(method) virtual HRESULT STDMETHODVCALLTYPE method 1.51 +#endif 1.52 + 1.53 +#define DEBUG_NO_IMPLEMENTATION 1.54 +#include <dbgeng.h> 1.55 +#include <dbghelp.h> 1.56 + 1.57 +// simple template to manage array delete across early (error) returns 1.58 + 1.59 +template <class T> 1.60 +class AutoArrayPtr { 1.61 + T* m_ptr; 1.62 + public: 1.63 + AutoArrayPtr(T* ptr) : m_ptr(ptr) { 1.64 + } 1.65 + 1.66 + ~AutoArrayPtr() { 1.67 + delete [] m_ptr; 1.68 + } 1.69 + 1.70 + T* asPtr() { 1.71 + return m_ptr; 1.72 + } 1.73 +}; 1.74 + 1.75 +class AutoJavaString { 1.76 + JNIEnv* m_env; 1.77 + jstring m_str; 1.78 + const char* m_buf; 1.79 + 1.80 + public: 1.81 + AutoJavaString(JNIEnv* env, jstring str, const char* buf) 1.82 + : m_env(env), m_str(str), m_buf(buf) { 1.83 + } 1.84 + 1.85 + ~AutoJavaString() { 1.86 + m_env->ReleaseStringUTFChars(m_str, m_buf); 1.87 + } 1.88 + 1.89 + operator const char* () { 1.90 + return m_buf; 1.91 + } 1.92 +}; 1.93 + 1.94 +// field and method IDs we want here 1.95 + 1.96 +static jfieldID imagePath_ID = 0; 1.97 +static jfieldID symbolPath_ID = 0; 1.98 +static jfieldID ptrIDebugClient_ID = 0; 1.99 +static jfieldID ptrIDebugControl_ID = 0; 1.100 +static jfieldID ptrIDebugDataSpaces_ID = 0; 1.101 +static jfieldID ptrIDebugOutputCallbacks_ID = 0; 1.102 +static jfieldID ptrIDebugAdvanced_ID = 0; 1.103 +static jfieldID ptrIDebugSymbols_ID = 0; 1.104 +static jfieldID ptrIDebugSystemObjects_ID = 0; 1.105 + 1.106 +static jmethodID addLoadObject_ID = 0; 1.107 +static jmethodID addThread_ID = 0; 1.108 +static jmethodID createClosestSymbol_ID = 0; 1.109 +static jmethodID setThreadIntegerRegisterSet_ID = 0; 1.110 + 1.111 +#define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; } 1.112 +#define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;} 1.113 + 1.114 +#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { \ 1.115 + throwNewDebuggerException(env, str); return value; } 1.116 + 1.117 +#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); \ 1.118 + return;} 1.119 + 1.120 +static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) { 1.121 + env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg); 1.122 +} 1.123 + 1.124 +/* 1.125 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.126 + * Method: initIDs 1.127 + * Signature: ()V 1.128 + */ 1.129 +JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_initIDs 1.130 + (JNIEnv *env, jclass clazz) { 1.131 + imagePath_ID = env->GetStaticFieldID(clazz, "imagePath", "Ljava/lang/String;"); 1.132 + CHECK_EXCEPTION; 1.133 + 1.134 + symbolPath_ID = env->GetStaticFieldID(clazz, "symbolPath", "Ljava/lang/String;"); 1.135 + CHECK_EXCEPTION; 1.136 + 1.137 + ptrIDebugClient_ID = env->GetFieldID(clazz, "ptrIDebugClient", "J"); 1.138 + CHECK_EXCEPTION; 1.139 + 1.140 + ptrIDebugControl_ID = env->GetFieldID(clazz, "ptrIDebugControl", "J"); 1.141 + CHECK_EXCEPTION; 1.142 + 1.143 + ptrIDebugDataSpaces_ID = env->GetFieldID(clazz, "ptrIDebugDataSpaces", "J"); 1.144 + CHECK_EXCEPTION; 1.145 + 1.146 + ptrIDebugOutputCallbacks_ID = env->GetFieldID(clazz, 1.147 + "ptrIDebugOutputCallbacks", "J"); 1.148 + CHECK_EXCEPTION; 1.149 + 1.150 + ptrIDebugAdvanced_ID = env->GetFieldID(clazz, "ptrIDebugAdvanced", "J"); 1.151 + CHECK_EXCEPTION; 1.152 + 1.153 + ptrIDebugSymbols_ID = env->GetFieldID(clazz, 1.154 + "ptrIDebugSymbols", "J"); 1.155 + CHECK_EXCEPTION; 1.156 + 1.157 + ptrIDebugSystemObjects_ID = env->GetFieldID(clazz, 1.158 + "ptrIDebugSystemObjects", "J"); 1.159 + CHECK_EXCEPTION; 1.160 + 1.161 + addLoadObject_ID = env->GetMethodID(clazz, "addLoadObject", 1.162 + "(Ljava/lang/String;JJ)V"); 1.163 + CHECK_EXCEPTION; 1.164 + 1.165 + addThread_ID = env->GetMethodID(clazz, "addThread", "(J)V"); 1.166 + CHECK_EXCEPTION; 1.167 + 1.168 + createClosestSymbol_ID = env->GetMethodID(clazz, "createClosestSymbol", 1.169 + "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;"); 1.170 + CHECK_EXCEPTION; 1.171 + 1.172 + setThreadIntegerRegisterSet_ID = env->GetMethodID(clazz, 1.173 + "setThreadIntegerRegisterSet", "(J[J)V"); 1.174 + CHECK_EXCEPTION; 1.175 + 1.176 +} 1.177 + 1.178 +// class for IDebugOutputCallbacks 1.179 + 1.180 +class SAOutputCallbacks : public IDebugOutputCallbacks { 1.181 + LONG m_refCount; 1.182 + char* m_msgBuffer; 1.183 + 1.184 + public: 1.185 + SAOutputCallbacks() : m_refCount(0), m_msgBuffer(0) { 1.186 + } 1.187 + 1.188 + ~SAOutputCallbacks() { 1.189 + clearBuffer(); 1.190 + } 1.191 + 1.192 + const char* getBuffer() const { 1.193 + return m_msgBuffer; 1.194 + } 1.195 + 1.196 + void clearBuffer() { 1.197 + if (m_msgBuffer) { 1.198 + free(m_msgBuffer); 1.199 + m_msgBuffer = 0; 1.200 + } 1.201 + } 1.202 + 1.203 + STDMETHOD_(ULONG, AddRef)(THIS); 1.204 + STDMETHOD_(ULONG, Release)(THIS); 1.205 + STDMETHOD(QueryInterface)(THIS_ 1.206 + IN REFIID interfaceId, 1.207 + OUT PVOID* ppInterface); 1.208 + STDMETHOD(Output)(THIS_ 1.209 + IN ULONG mask, 1.210 + IN PCSTR msg); 1.211 +}; 1.212 + 1.213 +STDMETHODIMP_(ULONG) SAOutputCallbacks::AddRef(THIS) { 1.214 + InterlockedIncrement(&m_refCount); 1.215 + return m_refCount; 1.216 +} 1.217 + 1.218 +STDMETHODIMP_(ULONG) SAOutputCallbacks::Release(THIS) { 1.219 + LONG retVal; 1.220 + InterlockedDecrement(&m_refCount); 1.221 + retVal = m_refCount; 1.222 + if (retVal == 0) { 1.223 + delete this; 1.224 + } 1.225 + return retVal; 1.226 +} 1.227 + 1.228 +STDMETHODIMP SAOutputCallbacks::QueryInterface(THIS_ 1.229 + IN REFIID interfaceId, 1.230 + OUT PVOID* ppInterface) { 1.231 + *ppInterface = 0; 1.232 + HRESULT res = E_NOINTERFACE; 1.233 + if (TRUE == IsEqualIID(interfaceId, __uuidof(IUnknown)) || 1.234 + TRUE == IsEqualIID(interfaceId, __uuidof(IDebugOutputCallbacks))) { 1.235 + *ppInterface = (IDebugOutputCallbacks*) this; 1.236 + AddRef(); 1.237 + res = S_OK; 1.238 + } 1.239 + return res; 1.240 +} 1.241 + 1.242 +STDMETHODIMP SAOutputCallbacks::Output(THIS_ 1.243 + IN ULONG mask, 1.244 + IN PCSTR msg) { 1.245 + int len = (int) (strlen(msg) + 1); 1.246 + if (m_msgBuffer == 0) { 1.247 + m_msgBuffer = (char*) malloc(len); 1.248 + if (m_msgBuffer == 0) { 1.249 + fprintf(stderr, "out of memory debugger output!\n"); 1.250 + return S_FALSE; 1.251 + } 1.252 + strcpy(m_msgBuffer, msg); 1.253 + } else { 1.254 + m_msgBuffer = (char*) realloc(m_msgBuffer, len + strlen(m_msgBuffer)); 1.255 + if (m_msgBuffer == 0) { 1.256 + fprintf(stderr, "out of memory debugger output!\n"); 1.257 + return S_FALSE; 1.258 + } 1.259 + strcat(m_msgBuffer, msg); 1.260 + } 1.261 + return S_OK; 1.262 +} 1.263 + 1.264 +static bool getWindbgInterfaces(JNIEnv* env, jobject obj) { 1.265 + // get windbg interfaces .. 1.266 + 1.267 + IDebugClient* ptrIDebugClient = 0; 1.268 + if (DebugCreate(__uuidof(IDebugClient), (PVOID*) &ptrIDebugClient) != S_OK) { 1.269 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to create IDebugClient object!", false); 1.270 + } 1.271 + env->SetLongField(obj, ptrIDebugClient_ID, (jlong) ptrIDebugClient); 1.272 + 1.273 + IDebugControl* ptrIDebugControl = 0; 1.274 + if (ptrIDebugClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &ptrIDebugControl) 1.275 + != S_OK) { 1.276 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugControl", false); 1.277 + } 1.278 + env->SetLongField(obj, ptrIDebugControl_ID, (jlong) ptrIDebugControl); 1.279 + 1.280 + IDebugDataSpaces* ptrIDebugDataSpaces = 0; 1.281 + if (ptrIDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (PVOID*) &ptrIDebugDataSpaces) 1.282 + != S_OK) { 1.283 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugDataSpaces object!", false); 1.284 + } 1.285 + env->SetLongField(obj, ptrIDebugDataSpaces_ID, (jlong) ptrIDebugDataSpaces); 1.286 + 1.287 + SAOutputCallbacks* ptrIDebugOutputCallbacks = new SAOutputCallbacks(); 1.288 + ptrIDebugOutputCallbacks->AddRef(); 1.289 + env->SetLongField(obj, ptrIDebugOutputCallbacks_ID, (jlong) ptrIDebugOutputCallbacks); 1.290 + CHECK_EXCEPTION_(false); 1.291 + 1.292 + IDebugAdvanced* ptrIDebugAdvanced = 0; 1.293 + if (ptrIDebugClient->QueryInterface(__uuidof(IDebugAdvanced), (PVOID*) &ptrIDebugAdvanced) 1.294 + != S_OK) { 1.295 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugAdvanced object!", false); 1.296 + } 1.297 + env->SetLongField(obj, ptrIDebugAdvanced_ID, (jlong) ptrIDebugAdvanced); 1.298 + 1.299 + IDebugSymbols* ptrIDebugSymbols = 0; 1.300 + if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSymbols), (PVOID*) &ptrIDebugSymbols) 1.301 + != S_OK) { 1.302 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSymbols object!", false); 1.303 + } 1.304 + env->SetLongField(obj, ptrIDebugSymbols_ID, (jlong) ptrIDebugSymbols); 1.305 + 1.306 + IDebugSystemObjects* ptrIDebugSystemObjects = 0; 1.307 + if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSystemObjects), (PVOID*) &ptrIDebugSystemObjects) 1.308 + != S_OK) { 1.309 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSystemObjects object!", false); 1.310 + } 1.311 + env->SetLongField(obj, ptrIDebugSystemObjects_ID, (jlong) ptrIDebugSystemObjects); 1.312 + 1.313 + return true; 1.314 +} 1.315 + 1.316 +static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) { 1.317 + jboolean isCopy; 1.318 + jclass clazz = env->GetObjectClass(obj); 1.319 + jstring path; 1.320 + const char* buf; 1.321 + 1.322 + path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID); 1.323 + buf = env->GetStringUTFChars(path, &isCopy); 1.324 + CHECK_EXCEPTION_(false); 1.325 + AutoJavaString imagePath(env, path, buf); 1.326 + 1.327 + path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID); 1.328 + buf = env->GetStringUTFChars(path, &isCopy); 1.329 + CHECK_EXCEPTION_(false); 1.330 + AutoJavaString symbolPath(env, path, buf); 1.331 + 1.332 + IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, 1.333 + ptrIDebugSymbols_ID); 1.334 + CHECK_EXCEPTION_(false); 1.335 + 1.336 + ptrIDebugSymbols->SetImagePath(imagePath); 1.337 + ptrIDebugSymbols->SetSymbolPath(symbolPath); 1.338 + return true; 1.339 +} 1.340 + 1.341 +static bool openDumpFile(JNIEnv* env, jobject obj, jstring coreFileName) { 1.342 + // open the dump file 1.343 + jboolean isCopy; 1.344 + const char* buf = env->GetStringUTFChars(coreFileName, &isCopy); 1.345 + CHECK_EXCEPTION_(false); 1.346 + AutoJavaString coreFile(env, coreFileName, buf); 1.347 + if (setImageAndSymbolPath(env, obj) == false) { 1.348 + return false; 1.349 + } 1.350 + 1.351 + IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, 1.352 + ptrIDebugClient_ID); 1.353 + CHECK_EXCEPTION_(false); 1.354 + if (ptrIDebugClient->OpenDumpFile(coreFile) != S_OK) { 1.355 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: OpenDumpFile failed!", false); 1.356 + } 1.357 + 1.358 + IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, 1.359 + ptrIDebugControl_ID); 1.360 + CHECK_EXCEPTION_(false); 1.361 + if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) { 1.362 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false); 1.363 + } 1.364 + 1.365 + return true; 1.366 +} 1.367 + 1.368 + 1.369 +static bool attachToProcess(JNIEnv* env, jobject obj, jint pid) { 1.370 + if (setImageAndSymbolPath(env, obj) == false) { 1.371 + return false; 1.372 + } 1.373 + IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, 1.374 + ptrIDebugClient_ID); 1.375 + CHECK_EXCEPTION_(false); 1.376 + 1.377 + /*********************************************************************************** 1.378 + 1.379 + We are attaching to a process in 'read-only' mode. i.e., we do not want to 1.380 + put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of 1.381 + usage this should suffice. We are not intending to use this for full-fledged 1.382 + ProcessControl implementation to be used with BugSpotAgent. 1.383 + 1.384 + Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h. 1.385 + In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not 1.386 + actually debugging at all. We can safely 'detach' from the process anytime 1.387 + we want and debuggee process is left as is on all Windows variants. 1.388 + 1.389 + This also makes JDI-on-SA installation/usage simpler because with this we would 1.390 + not need a tool like ServiceInstaller from http://www.kcmultimedia.com/smaster. 1.391 + 1.392 + ***********************************************************************************/ 1.393 + 1.394 + 1.395 + if (ptrIDebugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE) != S_OK) { 1.396 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: AttachProcess failed!", false); 1.397 + } 1.398 + 1.399 + IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, 1.400 + ptrIDebugControl_ID); 1.401 + CHECK_EXCEPTION_(false); 1.402 + if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) { 1.403 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false); 1.404 + } 1.405 + 1.406 + return true; 1.407 +} 1.408 + 1.409 + 1.410 +static bool addLoadObjects(JNIEnv* env, jobject obj) { 1.411 + IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, 1.412 + ptrIDebugSymbols_ID); 1.413 + CHECK_EXCEPTION_(false); 1.414 + ULONG loaded = 0, unloaded = 0; 1.415 + if (ptrIDebugSymbols->GetNumberModules(&loaded, &unloaded) != S_OK) { 1.416 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberModules failed!", false); 1.417 + } 1.418 + 1.419 + AutoArrayPtr<DEBUG_MODULE_PARAMETERS> params(new DEBUG_MODULE_PARAMETERS[loaded]); 1.420 + 1.421 + if (params.asPtr() == 0) { 1.422 + THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate debug module params!", false); 1.423 + } 1.424 + 1.425 + if (ptrIDebugSymbols->GetModuleParameters(loaded, 0, NULL, params.asPtr()) != S_OK) { 1.426 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleParameters failed!", false); 1.427 + } 1.428 + 1.429 + for (int u = 0; u < (int)loaded; u++) { 1.430 + TCHAR imageName[MAX_PATH]; 1.431 + if (ptrIDebugSymbols->GetModuleNames(DEBUG_ANY_ID, params.asPtr()[u].Base, 1.432 + imageName, MAX_PATH, NULL, NULL, 1.433 + 0, NULL, NULL, 0, NULL) != S_OK) { 1.434 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleNames failed!", false); 1.435 + } 1.436 + 1.437 + jstring strName = env->NewStringUTF(imageName); 1.438 + CHECK_EXCEPTION_(false); 1.439 + env->CallVoidMethod(obj, addLoadObject_ID, strName, (jlong) params.asPtr()[u].Size, 1.440 + (jlong) params.asPtr()[u].Base); 1.441 + CHECK_EXCEPTION_(false); 1.442 + } 1.443 + 1.444 + return true; 1.445 +} 1.446 + 1.447 +static bool addThreads(JNIEnv* env, jobject obj) { 1.448 + IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, 1.449 + ptrIDebugSystemObjects_ID); 1.450 + CHECK_EXCEPTION_(false); 1.451 + 1.452 + ULONG numThreads = 0; 1.453 + if (ptrIDebugSystemObjects->GetNumberThreads(&numThreads) != S_OK) { 1.454 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberThreads failed!", false); 1.455 + } 1.456 + 1.457 + AutoArrayPtr<ULONG> ptrSysThreadIds = new ULONG[numThreads]; 1.458 + 1.459 + if (ptrSysThreadIds.asPtr() == 0) { 1.460 + THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false); 1.461 + } 1.462 + 1.463 + AutoArrayPtr<ULONG> ptrThreadIds = new ULONG[numThreads]; 1.464 + 1.465 + if (ptrThreadIds.asPtr() == 0) { 1.466 + THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false); 1.467 + } 1.468 + 1.469 + if (ptrIDebugSystemObjects->GetThreadIdsByIndex(0, numThreads, 1.470 + ptrThreadIds.asPtr(), ptrSysThreadIds.asPtr()) != S_OK) { 1.471 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdsByIndex failed!", false); 1.472 + } 1.473 + 1.474 + 1.475 + IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj, 1.476 + ptrIDebugAdvanced_ID); 1.477 + CHECK_EXCEPTION_(false); 1.478 + 1.479 + // for each thread, get register context and save it. 1.480 + for (ULONG t = 0; t < numThreads; t++) { 1.481 + if (ptrIDebugSystemObjects->SetCurrentThreadId(ptrThreadIds.asPtr()[t]) != S_OK) { 1.482 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetCurrentThread failed!", false); 1.483 + } 1.484 + 1.485 + jlongArray regs = env->NewLongArray(NPRGREG); 1.486 + CHECK_EXCEPTION_(false); 1.487 + 1.488 + jboolean isCopy = JNI_FALSE; 1.489 + jlong* ptrRegs = env->GetLongArrayElements(regs, &isCopy); 1.490 + CHECK_EXCEPTION_(false); 1.491 + 1.492 + // copy register values from the CONTEXT struct 1.493 + CONTEXT context; 1.494 + memset(&context, 0, sizeof(CONTEXT)); 1.495 + 1.496 +#undef REG_INDEX 1.497 +#ifdef _M_IA64 1.498 + #define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x 1.499 + 1.500 + context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG; 1.501 + ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); 1.502 + 1.503 + ptrRegs[REG_INDEX(GR0)] = 0; // always 0 1.504 + ptrRegs[REG_INDEX(GR1)] = context.IntGp; // r1 1.505 + ptrRegs[REG_INDEX(GR2)] = context.IntT0; // r2-r3 1.506 + ptrRegs[REG_INDEX(GR3)] = context.IntT1; 1.507 + ptrRegs[REG_INDEX(GR4)] = context.IntS0; // r4-r7 1.508 + ptrRegs[REG_INDEX(GR5)] = context.IntS1; 1.509 + ptrRegs[REG_INDEX(GR6)] = context.IntS2; 1.510 + ptrRegs[REG_INDEX(GR7)] = context.IntS3; 1.511 + ptrRegs[REG_INDEX(GR8)] = context.IntV0; // r8 1.512 + ptrRegs[REG_INDEX(GR9)] = context.IntT2; // r9-r11 1.513 + ptrRegs[REG_INDEX(GR10)] = context.IntT3; 1.514 + ptrRegs[REG_INDEX(GR11)] = context.IntT4; 1.515 + ptrRegs[REG_INDEX(GR12)] = context.IntSp; // r12 stack pointer 1.516 + ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb 1.517 + ptrRegs[REG_INDEX(GR14)] = context.IntT5; // r14-r31 1.518 + ptrRegs[REG_INDEX(GR15)] = context.IntT6; 1.519 + ptrRegs[REG_INDEX(GR16)] = context.IntT7; 1.520 + ptrRegs[REG_INDEX(GR17)] = context.IntT8; 1.521 + ptrRegs[REG_INDEX(GR18)] = context.IntT9; 1.522 + ptrRegs[REG_INDEX(GR19)] = context.IntT10; 1.523 + ptrRegs[REG_INDEX(GR20)] = context.IntT11; 1.524 + ptrRegs[REG_INDEX(GR21)] = context.IntT12; 1.525 + ptrRegs[REG_INDEX(GR22)] = context.IntT13; 1.526 + ptrRegs[REG_INDEX(GR23)] = context.IntT14; 1.527 + ptrRegs[REG_INDEX(GR24)] = context.IntT15; 1.528 + ptrRegs[REG_INDEX(GR25)] = context.IntT16; 1.529 + ptrRegs[REG_INDEX(GR26)] = context.IntT17; 1.530 + ptrRegs[REG_INDEX(GR27)] = context.IntT18; 1.531 + ptrRegs[REG_INDEX(GR28)] = context.IntT19; 1.532 + ptrRegs[REG_INDEX(GR29)] = context.IntT20; 1.533 + ptrRegs[REG_INDEX(GR30)] = context.IntT21; 1.534 + ptrRegs[REG_INDEX(GR31)] = context.IntT22; 1.535 + 1.536 + ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats; 1.537 + ptrRegs[REG_INDEX(PREDS)] = context.Preds; 1.538 + 1.539 + ptrRegs[REG_INDEX(BR_RP)] = context.BrRp; 1.540 + ptrRegs[REG_INDEX(BR1)] = context.BrS0; // b1-b5 1.541 + ptrRegs[REG_INDEX(BR2)] = context.BrS1; 1.542 + ptrRegs[REG_INDEX(BR3)] = context.BrS2; 1.543 + ptrRegs[REG_INDEX(BR4)] = context.BrS3; 1.544 + ptrRegs[REG_INDEX(BR5)] = context.BrS4; 1.545 + ptrRegs[REG_INDEX(BR6)] = context.BrT0; // b6-b7 1.546 + ptrRegs[REG_INDEX(BR7)] = context.BrT1; 1.547 + 1.548 + ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT; 1.549 + ptrRegs[REG_INDEX(AP_LC)] = context.ApLC; 1.550 + ptrRegs[REG_INDEX(AP_EC)] = context.ApEC; 1.551 + ptrRegs[REG_INDEX(AP_CCV)] = context.ApCCV; 1.552 + ptrRegs[REG_INDEX(AP_DCR)] = context.ApDCR; 1.553 + 1.554 + ptrRegs[REG_INDEX(RS_PFS)] = context.RsPFS; 1.555 + ptrRegs[REG_INDEX(RS_BSP)] = context.RsBSP; 1.556 + ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE; 1.557 + ptrRegs[REG_INDEX(RS_RSC)] = context.RsRSC; 1.558 + ptrRegs[REG_INDEX(RS_RNAT)] = context.RsRNAT; 1.559 + 1.560 + ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR; 1.561 + ptrRegs[REG_INDEX(ST_IIP)] = context.StIIP; 1.562 + ptrRegs[REG_INDEX(ST_IFS)] = context.StIFS; 1.563 + 1.564 + ptrRegs[REG_INDEX(DB_I0)] = context.DbI0; 1.565 + ptrRegs[REG_INDEX(DB_I1)] = context.DbI1; 1.566 + ptrRegs[REG_INDEX(DB_I2)] = context.DbI2; 1.567 + ptrRegs[REG_INDEX(DB_I3)] = context.DbI3; 1.568 + ptrRegs[REG_INDEX(DB_I4)] = context.DbI4; 1.569 + ptrRegs[REG_INDEX(DB_I5)] = context.DbI5; 1.570 + ptrRegs[REG_INDEX(DB_I6)] = context.DbI6; 1.571 + ptrRegs[REG_INDEX(DB_I7)] = context.DbI7; 1.572 + 1.573 + ptrRegs[REG_INDEX(DB_D0)] = context.DbD0; 1.574 + ptrRegs[REG_INDEX(DB_D1)] = context.DbD1; 1.575 + ptrRegs[REG_INDEX(DB_D2)] = context.DbD2; 1.576 + ptrRegs[REG_INDEX(DB_D3)] = context.DbD3; 1.577 + ptrRegs[REG_INDEX(DB_D4)] = context.DbD4; 1.578 + ptrRegs[REG_INDEX(DB_D5)] = context.DbD5; 1.579 + ptrRegs[REG_INDEX(DB_D6)] = context.DbD6; 1.580 + ptrRegs[REG_INDEX(DB_D7)] = context.DbD7; 1.581 + 1.582 +#elif _M_IX86 1.583 + #define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x 1.584 + 1.585 + context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; 1.586 + ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); 1.587 + 1.588 + ptrRegs[REG_INDEX(GS)] = context.SegGs; 1.589 + ptrRegs[REG_INDEX(FS)] = context.SegFs; 1.590 + ptrRegs[REG_INDEX(ES)] = context.SegEs; 1.591 + ptrRegs[REG_INDEX(DS)] = context.SegDs; 1.592 + 1.593 + ptrRegs[REG_INDEX(EDI)] = context.Edi; 1.594 + ptrRegs[REG_INDEX(ESI)] = context.Esi; 1.595 + ptrRegs[REG_INDEX(EBX)] = context.Ebx; 1.596 + ptrRegs[REG_INDEX(EDX)] = context.Edx; 1.597 + ptrRegs[REG_INDEX(ECX)] = context.Ecx; 1.598 + ptrRegs[REG_INDEX(EAX)] = context.Eax; 1.599 + 1.600 + ptrRegs[REG_INDEX(FP)] = context.Ebp; 1.601 + ptrRegs[REG_INDEX(PC)] = context.Eip; 1.602 + ptrRegs[REG_INDEX(CS)] = context.SegCs; 1.603 + ptrRegs[REG_INDEX(EFL)] = context.EFlags; 1.604 + ptrRegs[REG_INDEX(SP)] = context.Esp; 1.605 + ptrRegs[REG_INDEX(SS)] = context.SegSs; 1.606 + 1.607 + ptrRegs[REG_INDEX(DR0)] = context.Dr0; 1.608 + ptrRegs[REG_INDEX(DR1)] = context.Dr1; 1.609 + ptrRegs[REG_INDEX(DR2)] = context.Dr2; 1.610 + ptrRegs[REG_INDEX(DR3)] = context.Dr3; 1.611 + ptrRegs[REG_INDEX(DR6)] = context.Dr6; 1.612 + ptrRegs[REG_INDEX(DR7)] = context.Dr7; 1.613 + 1.614 +#elif _M_AMD64 1.615 + #define REG_INDEX(x) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##x 1.616 + 1.617 + context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS; 1.618 + ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT)); 1.619 + 1.620 + // Segment Registers and processor flags 1.621 + ptrRegs[REG_INDEX(CS)] = context.SegCs; 1.622 + ptrRegs[REG_INDEX(DS)] = context.SegDs; 1.623 + ptrRegs[REG_INDEX(ES)] = context.SegEs; 1.624 + ptrRegs[REG_INDEX(FS)] = context.SegFs; 1.625 + ptrRegs[REG_INDEX(GS)] = context.SegGs; 1.626 + ptrRegs[REG_INDEX(SS)] = context.SegSs; 1.627 + ptrRegs[REG_INDEX(RFL)] = context.EFlags; 1.628 + 1.629 + // Integer registers 1.630 + ptrRegs[REG_INDEX(RDI)] = context.Rdi; 1.631 + ptrRegs[REG_INDEX(RSI)] = context.Rsi; 1.632 + ptrRegs[REG_INDEX(RAX)] = context.Rax; 1.633 + ptrRegs[REG_INDEX(RCX)] = context.Rcx; 1.634 + ptrRegs[REG_INDEX(RDX)] = context.Rdx; 1.635 + ptrRegs[REG_INDEX(RBX)] = context.Rbx; 1.636 + ptrRegs[REG_INDEX(RBP)] = context.Rbp; 1.637 + ptrRegs[REG_INDEX(RSP)] = context.Rsp; 1.638 + 1.639 + ptrRegs[REG_INDEX(R8)] = context.R8; 1.640 + ptrRegs[REG_INDEX(R9)] = context.R9; 1.641 + ptrRegs[REG_INDEX(R10)] = context.R10; 1.642 + ptrRegs[REG_INDEX(R11)] = context.R11; 1.643 + ptrRegs[REG_INDEX(R12)] = context.R12; 1.644 + ptrRegs[REG_INDEX(R13)] = context.R13; 1.645 + ptrRegs[REG_INDEX(R14)] = context.R14; 1.646 + ptrRegs[REG_INDEX(R15)] = context.R15; 1.647 + 1.648 + // Program counter 1.649 + ptrRegs[REG_INDEX(RIP)] = context.Rip; 1.650 +#endif 1.651 + 1.652 + env->ReleaseLongArrayElements(regs, ptrRegs, JNI_COMMIT); 1.653 + CHECK_EXCEPTION_(false); 1.654 + 1.655 + env->CallVoidMethod(obj, setThreadIntegerRegisterSet_ID, 1.656 + (jlong) ptrThreadIds.asPtr()[t], regs); 1.657 + CHECK_EXCEPTION_(false); 1.658 + 1.659 + ULONG sysId; 1.660 + if (ptrIDebugSystemObjects->GetCurrentThreadSystemId(&sysId) != S_OK) { 1.661 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetCurrentThreadSystemId failed!", false); 1.662 + } 1.663 + 1.664 + env->CallVoidMethod(obj, addThread_ID, (jlong) sysId); 1.665 + CHECK_EXCEPTION_(false); 1.666 + } 1.667 + 1.668 + return true; 1.669 +} 1.670 + 1.671 +/* 1.672 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.673 + * Method: attach0 1.674 + * Signature: (Ljava/lang/String;Ljava/lang/String;)V 1.675 + */ 1.676 +JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 1.677 + (JNIEnv *env, jobject obj, jstring execName, jstring coreFileName) { 1.678 + 1.679 + if (getWindbgInterfaces(env, obj) == false) { 1.680 + return; 1.681 + } 1.682 + 1.683 + if (openDumpFile(env, obj, coreFileName) == false) { 1.684 + return; 1.685 + } 1.686 + 1.687 + if (addLoadObjects(env, obj) == false) { 1.688 + return; 1.689 + } 1.690 + 1.691 + if (addThreads(env, obj) == false) { 1.692 + return; 1.693 + } 1.694 +} 1.695 + 1.696 +/* 1.697 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.698 + * Method: attach0 1.699 + * Signature: (I)V 1.700 + */ 1.701 +JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__I 1.702 + (JNIEnv *env, jobject obj, jint pid) { 1.703 + 1.704 + if (getWindbgInterfaces(env, obj) == false) { 1.705 + return; 1.706 + } 1.707 + 1.708 + if (attachToProcess(env, obj, pid) == false) { 1.709 + return; 1.710 + } 1.711 + 1.712 + if (addLoadObjects(env, obj) == false) { 1.713 + return; 1.714 + } 1.715 + 1.716 + if (addThreads(env, obj) == false) { 1.717 + return; 1.718 + } 1.719 +} 1.720 + 1.721 + 1.722 +static bool releaseWindbgInterfaces(JNIEnv* env, jobject obj) { 1.723 + IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj, 1.724 + ptrIDebugDataSpaces_ID); 1.725 + CHECK_EXCEPTION_(false); 1.726 + if (ptrIDebugDataSpaces != 0) { 1.727 + ptrIDebugDataSpaces->Release(); 1.728 + } 1.729 + 1.730 + IDebugOutputCallbacks* ptrIDebugOutputCallbacks = (IDebugOutputCallbacks*) 1.731 + env->GetLongField(obj, ptrIDebugOutputCallbacks_ID); 1.732 + CHECK_EXCEPTION_(false); 1.733 + if (ptrIDebugOutputCallbacks != 0) { 1.734 + ptrIDebugOutputCallbacks->Release(); 1.735 + } 1.736 + 1.737 + IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj, 1.738 + ptrIDebugAdvanced_ID); 1.739 + CHECK_EXCEPTION_(false); 1.740 + 1.741 + if (ptrIDebugAdvanced != 0) { 1.742 + ptrIDebugAdvanced->Release(); 1.743 + } 1.744 + 1.745 + IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, 1.746 + ptrIDebugSymbols_ID); 1.747 + CHECK_EXCEPTION_(false); 1.748 + if (ptrIDebugSymbols != 0) { 1.749 + ptrIDebugSymbols->Release(); 1.750 + } 1.751 + 1.752 + IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, 1.753 + ptrIDebugSystemObjects_ID); 1.754 + CHECK_EXCEPTION_(false); 1.755 + if (ptrIDebugSystemObjects != 0) { 1.756 + ptrIDebugSystemObjects->Release(); 1.757 + } 1.758 + 1.759 + IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj, 1.760 + ptrIDebugControl_ID); 1.761 + CHECK_EXCEPTION_(false); 1.762 + if (ptrIDebugControl != 0) { 1.763 + ptrIDebugControl->Release(); 1.764 + } 1.765 + 1.766 + IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, 1.767 + ptrIDebugClient_ID); 1.768 + CHECK_EXCEPTION_(false); 1.769 + if (ptrIDebugClient != 0) { 1.770 + ptrIDebugClient->Release(); 1.771 + } 1.772 + 1.773 + return true; 1.774 +} 1.775 + 1.776 +/* 1.777 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.778 + * Method: detach0 1.779 + * Signature: ()V 1.780 + */ 1.781 +JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_detach0 1.782 + (JNIEnv *env, jobject obj) { 1.783 + IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, 1.784 + ptrIDebugClient_ID); 1.785 + CHECK_EXCEPTION; 1.786 + ptrIDebugClient->DetachProcesses(); 1.787 + releaseWindbgInterfaces(env, obj); 1.788 +} 1.789 + 1.790 + 1.791 +/* 1.792 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.793 + * Method: readBytesFromProcess0 1.794 + * Signature: (JJ)[B 1.795 + */ 1.796 +JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_readBytesFromProcess0 1.797 + (JNIEnv *env, jobject obj, jlong address, jlong numBytes) { 1.798 + jbyteArray byteArray = env->NewByteArray((long) numBytes); 1.799 + CHECK_EXCEPTION_(0); 1.800 + 1.801 + jboolean isCopy = JNI_FALSE; 1.802 + jbyte* bytePtr = env->GetByteArrayElements(byteArray, &isCopy); 1.803 + CHECK_EXCEPTION_(0); 1.804 + 1.805 + IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj, 1.806 + ptrIDebugDataSpaces_ID); 1.807 + CHECK_EXCEPTION_(0); 1.808 + 1.809 + ULONG bytesRead; 1.810 + if (ptrIDebugDataSpaces->ReadVirtual((ULONG64) address, (PVOID) bytePtr, 1.811 + (ULONG)numBytes, &bytesRead) != S_OK) { 1.812 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: ReadVirtual failed!", 0); 1.813 + } 1.814 + 1.815 + if (bytesRead != numBytes) { 1.816 + return 0; 1.817 + } 1.818 + 1.819 + env->ReleaseByteArrayElements(byteArray, bytePtr, 0); 1.820 + CHECK_EXCEPTION_(0); 1.821 + 1.822 + return byteArray; 1.823 +} 1.824 + 1.825 +/* 1.826 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.827 + * Method: getThreadIdFromSysId0 1.828 + * Signature: (J)J 1.829 + */ 1.830 +JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_getThreadIdFromSysId0 1.831 + (JNIEnv *env, jobject obj, jlong sysId) { 1.832 + IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj, 1.833 + ptrIDebugSystemObjects_ID); 1.834 + CHECK_EXCEPTION_(0); 1.835 + 1.836 + ULONG id = 0; 1.837 + if (ptrIDebugSystemObjects->GetThreadIdBySystemId((ULONG)sysId, &id) != S_OK) { 1.838 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdBySystemId failed!", 0); 1.839 + } 1.840 + 1.841 + return (jlong) id; 1.842 +} 1.843 + 1.844 +// manage COM 'auto' pointers (to avoid multiple Release 1.845 +// calls at every early (exception) returns). Similar to AutoArrayPtr. 1.846 + 1.847 +template <class T> 1.848 +class AutoCOMPtr { 1.849 + T* m_ptr; 1.850 + 1.851 + public: 1.852 + AutoCOMPtr(T* ptr) : m_ptr(ptr) { 1.853 + } 1.854 + 1.855 + ~AutoCOMPtr() { 1.856 + if (m_ptr) { 1.857 + m_ptr->Release(); 1.858 + } 1.859 + } 1.860 + 1.861 + T* operator->() { 1.862 + return m_ptr; 1.863 + } 1.864 +}; 1.865 + 1.866 +/* 1.867 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.868 + * Method: consoleExecuteCommand0 1.869 + * Signature: (Ljava/lang/String;)Ljava/lang/String; 1.870 + */ 1.871 +JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_consoleExecuteCommand0 1.872 + (JNIEnv *env, jobject obj, jstring cmd) { 1.873 + jboolean isCopy = JNI_FALSE; 1.874 + const char* buf = env->GetStringUTFChars(cmd, &isCopy); 1.875 + CHECK_EXCEPTION_(0); 1.876 + AutoJavaString command(env, cmd, buf); 1.877 + 1.878 + IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID); 1.879 + CHECK_EXCEPTION_(0); 1.880 + 1.881 + IDebugClient* tmpClientPtr = 0; 1.882 + if (ptrIDebugClient->CreateClient(&tmpClientPtr) != S_OK) { 1.883 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: CreateClient failed!", 0); 1.884 + } 1.885 + AutoCOMPtr<IDebugClient> tmpClient(tmpClientPtr); 1.886 + 1.887 + IDebugControl* tmpControlPtr = 0; 1.888 + if (tmpClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &tmpControlPtr) != S_OK) { 1.889 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: QueryInterface (IDebugControl) failed", 0); 1.890 + } 1.891 + AutoCOMPtr<IDebugControl> tmpControl(tmpControlPtr); 1.892 + 1.893 + SAOutputCallbacks* saOutputCallbacks = (SAOutputCallbacks*) env->GetLongField(obj, 1.894 + ptrIDebugOutputCallbacks_ID); 1.895 + CHECK_EXCEPTION_(0); 1.896 + 1.897 + saOutputCallbacks->clearBuffer(); 1.898 + 1.899 + if (tmpClient->SetOutputCallbacks(saOutputCallbacks) != S_OK) { 1.900 + THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetOutputCallbacks failed!", 0); 1.901 + } 1.902 + 1.903 + tmpControl->Execute(DEBUG_OUTPUT_VERBOSE, command, DEBUG_EXECUTE_DEFAULT); 1.904 + 1.905 + const char* output = saOutputCallbacks->getBuffer(); 1.906 + if (output == 0) { 1.907 + output = ""; 1.908 + } 1.909 + 1.910 + jstring res = env->NewStringUTF(output); 1.911 + saOutputCallbacks->clearBuffer(); 1.912 + return res; 1.913 +} 1.914 + 1.915 +/* 1.916 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.917 + * Method: lookupByName0 1.918 + * Signature: (Ljava/lang/String;Ljava/lang/String;)J 1.919 + */ 1.920 + 1.921 +JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByName0 1.922 +(JNIEnv *env, jobject obj, jstring objName, jstring sym) { 1.923 + IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, 1.924 + ptrIDebugSymbols_ID); 1.925 + CHECK_EXCEPTION_(0); 1.926 + 1.927 + jboolean isCopy; 1.928 + const char* buf = env->GetStringUTFChars(sym, &isCopy); 1.929 + CHECK_EXCEPTION_(0); 1.930 + AutoJavaString name(env, sym, buf); 1.931 + 1.932 + ULONG64 offset = 0L; 1.933 + if (strstr(name, "::") != 0) { 1.934 + ptrIDebugSymbols->AddSymbolOptions(SYMOPT_UNDNAME); 1.935 + } else { 1.936 + ptrIDebugSymbols->RemoveSymbolOptions(SYMOPT_UNDNAME); 1.937 + } 1.938 + if (ptrIDebugSymbols->GetOffsetByName(name, &offset) != S_OK) { 1.939 + return (jlong) 0; 1.940 + } 1.941 + return (jlong) offset; 1.942 +} 1.943 + 1.944 +#define SYMBOL_BUFSIZE 512 1.945 +/* 1.946 + * Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal 1.947 + * Method: lookupByAddress0 1.948 + * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; 1.949 + */ 1.950 +JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByAddress0 1.951 +(JNIEnv *env, jobject obj, jlong address) { 1.952 + IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj, 1.953 + ptrIDebugSymbols_ID); 1.954 + CHECK_EXCEPTION_(0); 1.955 + 1.956 + ULONG64 disp = 0L; 1.957 + char buf[SYMBOL_BUFSIZE]; 1.958 + memset(buf, 0, sizeof(buf)); 1.959 + 1.960 + if (ptrIDebugSymbols->GetNameByOffset(address, buf, sizeof(buf),0,&disp) 1.961 + != S_OK) { 1.962 + return 0; 1.963 + } 1.964 + 1.965 + jstring sym = env->NewStringUTF(buf); 1.966 + CHECK_EXCEPTION_(0); 1.967 + jobject res = env->CallObjectMethod(obj, createClosestSymbol_ID, sym, disp); 1.968 + CHECK_EXCEPTION_(0); 1.969 + return res; 1.970 +}