Path: blob/aarch64-shenandoah-jdk8u272-b10/hotspot/agent/src/os/win32/windbg/sawindbg.cpp
38841 views
/*1* Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*22*/2324// this is source code windbg based SA debugger agent to debug25// Dr. Watson dump files and process snapshots.2627#include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h"2829#ifdef _M_IX8630#include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"31#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG32#elif _M_AMD6433#include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"34#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG35#else36#error "SA windbg back-end is not supported for your cpu!"37#endif3839#include <limits.h>40#include <windows.h>4142#ifndef STDMETHODV43#define STDMETHODV(method) virtual HRESULT STDMETHODVCALLTYPE method44#endif4546#define DEBUG_NO_IMPLEMENTATION47#include <dbgeng.h>48#include <dbghelp.h>4950// simple template to manage array delete across early (error) returns5152template <class T>53class AutoArrayPtr {54T* m_ptr;55public:56AutoArrayPtr(T* ptr) : m_ptr(ptr) {57}5859~AutoArrayPtr() {60delete [] m_ptr;61}6263T* asPtr() {64return m_ptr;65}66};6768class AutoJavaString {69JNIEnv* m_env;70jstring m_str;71const char* m_buf;7273public:74AutoJavaString(JNIEnv* env, jstring str, const char* buf)75: m_env(env), m_str(str), m_buf(buf) {76}7778~AutoJavaString() {79m_env->ReleaseStringUTFChars(m_str, m_buf);80}8182operator const char* () {83return m_buf;84}85};8687// field and method IDs we want here8889static jfieldID imagePath_ID = 0;90static jfieldID symbolPath_ID = 0;91static jfieldID ptrIDebugClient_ID = 0;92static jfieldID ptrIDebugControl_ID = 0;93static jfieldID ptrIDebugDataSpaces_ID = 0;94static jfieldID ptrIDebugOutputCallbacks_ID = 0;95static jfieldID ptrIDebugAdvanced_ID = 0;96static jfieldID ptrIDebugSymbols_ID = 0;97static jfieldID ptrIDebugSystemObjects_ID = 0;9899static jmethodID addLoadObject_ID = 0;100static jmethodID addThread_ID = 0;101static jmethodID createClosestSymbol_ID = 0;102static jmethodID setThreadIntegerRegisterSet_ID = 0;103104#define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }105#define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}106107#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { \108throwNewDebuggerException(env, str); return value; }109110#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); \111return;}112113static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {114env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);115}116117/*118* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal119* Method: initIDs120* Signature: ()V121*/122JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_initIDs123(JNIEnv *env, jclass clazz) {124imagePath_ID = env->GetStaticFieldID(clazz, "imagePath", "Ljava/lang/String;");125CHECK_EXCEPTION;126127symbolPath_ID = env->GetStaticFieldID(clazz, "symbolPath", "Ljava/lang/String;");128CHECK_EXCEPTION;129130ptrIDebugClient_ID = env->GetFieldID(clazz, "ptrIDebugClient", "J");131CHECK_EXCEPTION;132133ptrIDebugControl_ID = env->GetFieldID(clazz, "ptrIDebugControl", "J");134CHECK_EXCEPTION;135136ptrIDebugDataSpaces_ID = env->GetFieldID(clazz, "ptrIDebugDataSpaces", "J");137CHECK_EXCEPTION;138139ptrIDebugOutputCallbacks_ID = env->GetFieldID(clazz,140"ptrIDebugOutputCallbacks", "J");141CHECK_EXCEPTION;142143ptrIDebugAdvanced_ID = env->GetFieldID(clazz, "ptrIDebugAdvanced", "J");144CHECK_EXCEPTION;145146ptrIDebugSymbols_ID = env->GetFieldID(clazz,147"ptrIDebugSymbols", "J");148CHECK_EXCEPTION;149150ptrIDebugSystemObjects_ID = env->GetFieldID(clazz,151"ptrIDebugSystemObjects", "J");152CHECK_EXCEPTION;153154addLoadObject_ID = env->GetMethodID(clazz, "addLoadObject",155"(Ljava/lang/String;JJ)V");156CHECK_EXCEPTION;157158addThread_ID = env->GetMethodID(clazz, "addThread", "(J)V");159CHECK_EXCEPTION;160161createClosestSymbol_ID = env->GetMethodID(clazz, "createClosestSymbol",162"(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");163CHECK_EXCEPTION;164165setThreadIntegerRegisterSet_ID = env->GetMethodID(clazz,166"setThreadIntegerRegisterSet", "(J[J)V");167CHECK_EXCEPTION;168169}170171// class for IDebugOutputCallbacks172173class SAOutputCallbacks : public IDebugOutputCallbacks {174LONG m_refCount;175char* m_msgBuffer;176177public:178SAOutputCallbacks() : m_refCount(0), m_msgBuffer(0) {179}180181~SAOutputCallbacks() {182clearBuffer();183}184185const char* getBuffer() const {186return m_msgBuffer;187}188189void clearBuffer() {190if (m_msgBuffer) {191free(m_msgBuffer);192m_msgBuffer = 0;193}194}195196STDMETHOD_(ULONG, AddRef)(THIS);197STDMETHOD_(ULONG, Release)(THIS);198STDMETHOD(QueryInterface)(THIS_199IN REFIID interfaceId,200OUT PVOID* ppInterface);201STDMETHOD(Output)(THIS_202IN ULONG mask,203IN PCSTR msg);204};205206STDMETHODIMP_(ULONG) SAOutputCallbacks::AddRef(THIS) {207InterlockedIncrement(&m_refCount);208return m_refCount;209}210211STDMETHODIMP_(ULONG) SAOutputCallbacks::Release(THIS) {212LONG retVal;213InterlockedDecrement(&m_refCount);214retVal = m_refCount;215if (retVal == 0) {216delete this;217}218return retVal;219}220221STDMETHODIMP SAOutputCallbacks::QueryInterface(THIS_222IN REFIID interfaceId,223OUT PVOID* ppInterface) {224*ppInterface = 0;225HRESULT res = E_NOINTERFACE;226if (TRUE == IsEqualIID(interfaceId, __uuidof(IUnknown)) ||227TRUE == IsEqualIID(interfaceId, __uuidof(IDebugOutputCallbacks))) {228*ppInterface = (IDebugOutputCallbacks*) this;229AddRef();230res = S_OK;231}232return res;233}234235STDMETHODIMP SAOutputCallbacks::Output(THIS_236IN ULONG mask,237IN PCSTR msg) {238int len = (int) (strlen(msg) + 1);239if (m_msgBuffer == 0) {240m_msgBuffer = (char*) malloc(len);241if (m_msgBuffer == 0) {242fprintf(stderr, "out of memory debugger output!\n");243return S_FALSE;244}245strcpy(m_msgBuffer, msg);246} else {247m_msgBuffer = (char*) realloc(m_msgBuffer, len + strlen(m_msgBuffer));248if (m_msgBuffer == 0) {249fprintf(stderr, "out of memory debugger output!\n");250return S_FALSE;251}252strcat(m_msgBuffer, msg);253}254return S_OK;255}256257static bool getWindbgInterfaces(JNIEnv* env, jobject obj) {258// get windbg interfaces ..259260IDebugClient* ptrIDebugClient = 0;261if (DebugCreate(__uuidof(IDebugClient), (PVOID*) &ptrIDebugClient) != S_OK) {262THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to create IDebugClient object!", false);263}264env->SetLongField(obj, ptrIDebugClient_ID, (jlong) ptrIDebugClient);265266IDebugControl* ptrIDebugControl = 0;267if (ptrIDebugClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &ptrIDebugControl)268!= S_OK) {269THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugControl", false);270}271env->SetLongField(obj, ptrIDebugControl_ID, (jlong) ptrIDebugControl);272273IDebugDataSpaces* ptrIDebugDataSpaces = 0;274if (ptrIDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (PVOID*) &ptrIDebugDataSpaces)275!= S_OK) {276THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugDataSpaces object!", false);277}278env->SetLongField(obj, ptrIDebugDataSpaces_ID, (jlong) ptrIDebugDataSpaces);279280SAOutputCallbacks* ptrIDebugOutputCallbacks = new SAOutputCallbacks();281ptrIDebugOutputCallbacks->AddRef();282env->SetLongField(obj, ptrIDebugOutputCallbacks_ID, (jlong) ptrIDebugOutputCallbacks);283CHECK_EXCEPTION_(false);284285IDebugAdvanced* ptrIDebugAdvanced = 0;286if (ptrIDebugClient->QueryInterface(__uuidof(IDebugAdvanced), (PVOID*) &ptrIDebugAdvanced)287!= S_OK) {288THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugAdvanced object!", false);289}290env->SetLongField(obj, ptrIDebugAdvanced_ID, (jlong) ptrIDebugAdvanced);291292IDebugSymbols* ptrIDebugSymbols = 0;293if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSymbols), (PVOID*) &ptrIDebugSymbols)294!= S_OK) {295THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSymbols object!", false);296}297env->SetLongField(obj, ptrIDebugSymbols_ID, (jlong) ptrIDebugSymbols);298299IDebugSystemObjects* ptrIDebugSystemObjects = 0;300if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSystemObjects), (PVOID*) &ptrIDebugSystemObjects)301!= S_OK) {302THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSystemObjects object!", false);303}304env->SetLongField(obj, ptrIDebugSystemObjects_ID, (jlong) ptrIDebugSystemObjects);305306return true;307}308309static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) {310jboolean isCopy;311jclass clazz = env->GetObjectClass(obj);312jstring path;313const char* buf;314315path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID);316buf = env->GetStringUTFChars(path, &isCopy);317CHECK_EXCEPTION_(false);318AutoJavaString imagePath(env, path, buf);319320path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID);321buf = env->GetStringUTFChars(path, &isCopy);322CHECK_EXCEPTION_(false);323AutoJavaString symbolPath(env, path, buf);324325IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,326ptrIDebugSymbols_ID);327CHECK_EXCEPTION_(false);328329ptrIDebugSymbols->SetImagePath(imagePath);330ptrIDebugSymbols->SetSymbolPath(symbolPath);331return true;332}333334static bool openDumpFile(JNIEnv* env, jobject obj, jstring coreFileName) {335// open the dump file336jboolean isCopy;337const char* buf = env->GetStringUTFChars(coreFileName, &isCopy);338CHECK_EXCEPTION_(false);339AutoJavaString coreFile(env, coreFileName, buf);340if (setImageAndSymbolPath(env, obj) == false) {341return false;342}343344IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,345ptrIDebugClient_ID);346CHECK_EXCEPTION_(false);347if (ptrIDebugClient->OpenDumpFile(coreFile) != S_OK) {348THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: OpenDumpFile failed!", false);349}350351IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,352ptrIDebugControl_ID);353CHECK_EXCEPTION_(false);354if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) {355THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false);356}357358return true;359}360361362static bool attachToProcess(JNIEnv* env, jobject obj, jint pid) {363if (setImageAndSymbolPath(env, obj) == false) {364return false;365}366IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,367ptrIDebugClient_ID);368CHECK_EXCEPTION_(false);369370/***********************************************************************************371372We are attaching to a process in 'read-only' mode. i.e., we do not want to373put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of374usage this should suffice.375376Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h.377In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not378actually debugging at all. We can safely 'detach' from the process anytime379we want and debuggee process is left as is on all Windows variants.380381This also makes JDI-on-SA installation/usage simpler because with this we would382not need a tool like ServiceInstaller from http://www.kcmultimedia.com/smaster.383384***********************************************************************************/385386387if (ptrIDebugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE) != S_OK) {388THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: AttachProcess failed!", false);389}390391IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,392ptrIDebugControl_ID);393CHECK_EXCEPTION_(false);394if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) {395THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false);396}397398return true;399}400401402static bool addLoadObjects(JNIEnv* env, jobject obj) {403IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,404ptrIDebugSymbols_ID);405CHECK_EXCEPTION_(false);406ULONG loaded = 0, unloaded = 0;407if (ptrIDebugSymbols->GetNumberModules(&loaded, &unloaded) != S_OK) {408THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberModules failed!", false);409}410411AutoArrayPtr<DEBUG_MODULE_PARAMETERS> params(new DEBUG_MODULE_PARAMETERS[loaded]);412413if (params.asPtr() == 0) {414THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate debug module params!", false);415}416417if (ptrIDebugSymbols->GetModuleParameters(loaded, 0, NULL, params.asPtr()) != S_OK) {418THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleParameters failed!", false);419}420421for (int u = 0; u < (int)loaded; u++) {422TCHAR imageName[MAX_PATH];423if (ptrIDebugSymbols->GetModuleNames(DEBUG_ANY_ID, params.asPtr()[u].Base,424imageName, MAX_PATH, NULL, NULL,4250, NULL, NULL, 0, NULL) != S_OK) {426THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleNames failed!", false);427}428429jstring strName = env->NewStringUTF(imageName);430CHECK_EXCEPTION_(false);431env->CallVoidMethod(obj, addLoadObject_ID, strName, (jlong) params.asPtr()[u].Size,432(jlong) params.asPtr()[u].Base);433CHECK_EXCEPTION_(false);434}435436return true;437}438439static bool addThreads(JNIEnv* env, jobject obj) {440IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,441ptrIDebugSystemObjects_ID);442CHECK_EXCEPTION_(false);443444ULONG numThreads = 0;445if (ptrIDebugSystemObjects->GetNumberThreads(&numThreads) != S_OK) {446THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberThreads failed!", false);447}448449AutoArrayPtr<ULONG> ptrSysThreadIds = new ULONG[numThreads];450451if (ptrSysThreadIds.asPtr() == 0) {452THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false);453}454455AutoArrayPtr<ULONG> ptrThreadIds = new ULONG[numThreads];456457if (ptrThreadIds.asPtr() == 0) {458THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false);459}460461if (ptrIDebugSystemObjects->GetThreadIdsByIndex(0, numThreads,462ptrThreadIds.asPtr(), ptrSysThreadIds.asPtr()) != S_OK) {463THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdsByIndex failed!", false);464}465466467IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj,468ptrIDebugAdvanced_ID);469CHECK_EXCEPTION_(false);470471// for each thread, get register context and save it.472for (ULONG t = 0; t < numThreads; t++) {473if (ptrIDebugSystemObjects->SetCurrentThreadId(ptrThreadIds.asPtr()[t]) != S_OK) {474THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetCurrentThread failed!", false);475}476477jlongArray regs = env->NewLongArray(NPRGREG);478CHECK_EXCEPTION_(false);479480jboolean isCopy = JNI_FALSE;481jlong* ptrRegs = env->GetLongArrayElements(regs, &isCopy);482CHECK_EXCEPTION_(false);483484// copy register values from the CONTEXT struct485CONTEXT context;486memset(&context, 0, sizeof(CONTEXT));487488#undef REG_INDEX489#ifdef _M_IX86490#define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x491492context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;493ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT));494495ptrRegs[REG_INDEX(GS)] = context.SegGs;496ptrRegs[REG_INDEX(FS)] = context.SegFs;497ptrRegs[REG_INDEX(ES)] = context.SegEs;498ptrRegs[REG_INDEX(DS)] = context.SegDs;499500ptrRegs[REG_INDEX(EDI)] = context.Edi;501ptrRegs[REG_INDEX(ESI)] = context.Esi;502ptrRegs[REG_INDEX(EBX)] = context.Ebx;503ptrRegs[REG_INDEX(EDX)] = context.Edx;504ptrRegs[REG_INDEX(ECX)] = context.Ecx;505ptrRegs[REG_INDEX(EAX)] = context.Eax;506507ptrRegs[REG_INDEX(FP)] = context.Ebp;508ptrRegs[REG_INDEX(PC)] = context.Eip;509ptrRegs[REG_INDEX(CS)] = context.SegCs;510ptrRegs[REG_INDEX(EFL)] = context.EFlags;511ptrRegs[REG_INDEX(SP)] = context.Esp;512ptrRegs[REG_INDEX(SS)] = context.SegSs;513514ptrRegs[REG_INDEX(DR0)] = context.Dr0;515ptrRegs[REG_INDEX(DR1)] = context.Dr1;516ptrRegs[REG_INDEX(DR2)] = context.Dr2;517ptrRegs[REG_INDEX(DR3)] = context.Dr3;518ptrRegs[REG_INDEX(DR6)] = context.Dr6;519ptrRegs[REG_INDEX(DR7)] = context.Dr7;520521#elif _M_AMD64522#define REG_INDEX(x) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##x523524context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;525ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT));526527// Segment Registers and processor flags528ptrRegs[REG_INDEX(CS)] = context.SegCs;529ptrRegs[REG_INDEX(DS)] = context.SegDs;530ptrRegs[REG_INDEX(ES)] = context.SegEs;531ptrRegs[REG_INDEX(FS)] = context.SegFs;532ptrRegs[REG_INDEX(GS)] = context.SegGs;533ptrRegs[REG_INDEX(SS)] = context.SegSs;534ptrRegs[REG_INDEX(RFL)] = context.EFlags;535536// Integer registers537ptrRegs[REG_INDEX(RDI)] = context.Rdi;538ptrRegs[REG_INDEX(RSI)] = context.Rsi;539ptrRegs[REG_INDEX(RAX)] = context.Rax;540ptrRegs[REG_INDEX(RCX)] = context.Rcx;541ptrRegs[REG_INDEX(RDX)] = context.Rdx;542ptrRegs[REG_INDEX(RBX)] = context.Rbx;543ptrRegs[REG_INDEX(RBP)] = context.Rbp;544ptrRegs[REG_INDEX(RSP)] = context.Rsp;545546ptrRegs[REG_INDEX(R8)] = context.R8;547ptrRegs[REG_INDEX(R9)] = context.R9;548ptrRegs[REG_INDEX(R10)] = context.R10;549ptrRegs[REG_INDEX(R11)] = context.R11;550ptrRegs[REG_INDEX(R12)] = context.R12;551ptrRegs[REG_INDEX(R13)] = context.R13;552ptrRegs[REG_INDEX(R14)] = context.R14;553ptrRegs[REG_INDEX(R15)] = context.R15;554555// Program counter556ptrRegs[REG_INDEX(RIP)] = context.Rip;557#endif558559env->ReleaseLongArrayElements(regs, ptrRegs, JNI_COMMIT);560CHECK_EXCEPTION_(false);561562env->CallVoidMethod(obj, setThreadIntegerRegisterSet_ID,563(jlong) ptrThreadIds.asPtr()[t], regs);564CHECK_EXCEPTION_(false);565566ULONG sysId;567if (ptrIDebugSystemObjects->GetCurrentThreadSystemId(&sysId) != S_OK) {568THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetCurrentThreadSystemId failed!", false);569}570571env->CallVoidMethod(obj, addThread_ID, (jlong) sysId);572CHECK_EXCEPTION_(false);573}574575return true;576}577578/*579* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal580* Method: attach0581* Signature: (Ljava/lang/String;Ljava/lang/String;)V582*/583JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2584(JNIEnv *env, jobject obj, jstring execName, jstring coreFileName) {585586if (getWindbgInterfaces(env, obj) == false) {587return;588}589590if (openDumpFile(env, obj, coreFileName) == false) {591return;592}593594if (addLoadObjects(env, obj) == false) {595return;596}597598if (addThreads(env, obj) == false) {599return;600}601}602603/*604* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal605* Method: attach0606* Signature: (I)V607*/608JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__I609(JNIEnv *env, jobject obj, jint pid) {610611if (getWindbgInterfaces(env, obj) == false) {612return;613}614615if (attachToProcess(env, obj, pid) == false) {616return;617}618619if (addLoadObjects(env, obj) == false) {620return;621}622623if (addThreads(env, obj) == false) {624return;625}626}627628629static bool releaseWindbgInterfaces(JNIEnv* env, jobject obj) {630IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj,631ptrIDebugDataSpaces_ID);632CHECK_EXCEPTION_(false);633if (ptrIDebugDataSpaces != 0) {634ptrIDebugDataSpaces->Release();635}636637IDebugOutputCallbacks* ptrIDebugOutputCallbacks = (IDebugOutputCallbacks*)638env->GetLongField(obj, ptrIDebugOutputCallbacks_ID);639CHECK_EXCEPTION_(false);640if (ptrIDebugOutputCallbacks != 0) {641ptrIDebugOutputCallbacks->Release();642}643644IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj,645ptrIDebugAdvanced_ID);646CHECK_EXCEPTION_(false);647648if (ptrIDebugAdvanced != 0) {649ptrIDebugAdvanced->Release();650}651652IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,653ptrIDebugSymbols_ID);654CHECK_EXCEPTION_(false);655if (ptrIDebugSymbols != 0) {656ptrIDebugSymbols->Release();657}658659IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,660ptrIDebugSystemObjects_ID);661CHECK_EXCEPTION_(false);662if (ptrIDebugSystemObjects != 0) {663ptrIDebugSystemObjects->Release();664}665666IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,667ptrIDebugControl_ID);668CHECK_EXCEPTION_(false);669if (ptrIDebugControl != 0) {670ptrIDebugControl->Release();671}672673IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,674ptrIDebugClient_ID);675CHECK_EXCEPTION_(false);676if (ptrIDebugClient != 0) {677ptrIDebugClient->Release();678}679680return true;681}682683/*684* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal685* Method: detach0686* Signature: ()V687*/688JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_detach0689(JNIEnv *env, jobject obj) {690IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,691ptrIDebugClient_ID);692CHECK_EXCEPTION;693ptrIDebugClient->DetachProcesses();694releaseWindbgInterfaces(env, obj);695}696697698/*699* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal700* Method: readBytesFromProcess0701* Signature: (JJ)[B702*/703JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_readBytesFromProcess0704(JNIEnv *env, jobject obj, jlong address, jlong numBytes) {705jbyteArray byteArray = env->NewByteArray((long) numBytes);706CHECK_EXCEPTION_(0);707708jboolean isCopy = JNI_FALSE;709jbyte* bytePtr = env->GetByteArrayElements(byteArray, &isCopy);710CHECK_EXCEPTION_(0);711712IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj,713ptrIDebugDataSpaces_ID);714CHECK_EXCEPTION_(0);715716ULONG bytesRead;717if (ptrIDebugDataSpaces->ReadVirtual((ULONG64) address, (PVOID) bytePtr,718(ULONG)numBytes, &bytesRead) != S_OK) {719THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: ReadVirtual failed!", 0);720}721722if (bytesRead != numBytes) {723return 0;724}725726env->ReleaseByteArrayElements(byteArray, bytePtr, 0);727CHECK_EXCEPTION_(0);728729return byteArray;730}731732/*733* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal734* Method: getThreadIdFromSysId0735* Signature: (J)J736*/737JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_getThreadIdFromSysId0738(JNIEnv *env, jobject obj, jlong sysId) {739IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,740ptrIDebugSystemObjects_ID);741CHECK_EXCEPTION_(0);742743ULONG id = 0;744if (ptrIDebugSystemObjects->GetThreadIdBySystemId((ULONG)sysId, &id) != S_OK) {745THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdBySystemId failed!", 0);746}747748return (jlong) id;749}750751// manage COM 'auto' pointers (to avoid multiple Release752// calls at every early (exception) returns). Similar to AutoArrayPtr.753754template <class T>755class AutoCOMPtr {756T* m_ptr;757758public:759AutoCOMPtr(T* ptr) : m_ptr(ptr) {760}761762~AutoCOMPtr() {763if (m_ptr) {764m_ptr->Release();765}766}767768T* operator->() {769return m_ptr;770}771};772773/*774* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal775* Method: consoleExecuteCommand0776* Signature: (Ljava/lang/String;)Ljava/lang/String;777*/778JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_consoleExecuteCommand0779(JNIEnv *env, jobject obj, jstring cmd) {780jboolean isCopy = JNI_FALSE;781const char* buf = env->GetStringUTFChars(cmd, &isCopy);782CHECK_EXCEPTION_(0);783AutoJavaString command(env, cmd, buf);784785IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID);786CHECK_EXCEPTION_(0);787788IDebugClient* tmpClientPtr = 0;789if (ptrIDebugClient->CreateClient(&tmpClientPtr) != S_OK) {790THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: CreateClient failed!", 0);791}792AutoCOMPtr<IDebugClient> tmpClient(tmpClientPtr);793794IDebugControl* tmpControlPtr = 0;795if (tmpClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &tmpControlPtr) != S_OK) {796THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: QueryInterface (IDebugControl) failed", 0);797}798AutoCOMPtr<IDebugControl> tmpControl(tmpControlPtr);799800SAOutputCallbacks* saOutputCallbacks = (SAOutputCallbacks*) env->GetLongField(obj,801ptrIDebugOutputCallbacks_ID);802CHECK_EXCEPTION_(0);803804saOutputCallbacks->clearBuffer();805806if (tmpClient->SetOutputCallbacks(saOutputCallbacks) != S_OK) {807THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetOutputCallbacks failed!", 0);808}809810tmpControl->Execute(DEBUG_OUTPUT_VERBOSE, command, DEBUG_EXECUTE_DEFAULT);811812const char* output = saOutputCallbacks->getBuffer();813if (output == 0) {814output = "";815}816817jstring res = env->NewStringUTF(output);818saOutputCallbacks->clearBuffer();819return res;820}821822/*823* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal824* Method: lookupByName0825* Signature: (Ljava/lang/String;Ljava/lang/String;)J826*/827828JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByName0829(JNIEnv *env, jobject obj, jstring objName, jstring sym) {830IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,831ptrIDebugSymbols_ID);832CHECK_EXCEPTION_(0);833834jboolean isCopy;835const char* buf = env->GetStringUTFChars(sym, &isCopy);836CHECK_EXCEPTION_(0);837AutoJavaString name(env, sym, buf);838839ULONG64 offset = 0L;840if (strstr(name, "::") != 0) {841ptrIDebugSymbols->AddSymbolOptions(SYMOPT_UNDNAME);842} else {843ptrIDebugSymbols->RemoveSymbolOptions(SYMOPT_UNDNAME);844}845if (ptrIDebugSymbols->GetOffsetByName(name, &offset) != S_OK) {846return (jlong) 0;847}848return (jlong) offset;849}850851#define SYMBOL_BUFSIZE 512852/*853* Class: sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal854* Method: lookupByAddress0855* Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;856*/857JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByAddress0858(JNIEnv *env, jobject obj, jlong address) {859IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,860ptrIDebugSymbols_ID);861CHECK_EXCEPTION_(0);862863ULONG64 disp = 0L;864char buf[SYMBOL_BUFSIZE];865memset(buf, 0, sizeof(buf));866867if (ptrIDebugSymbols->GetNameByOffset(address, buf, sizeof(buf),0,&disp)868!= S_OK) {869return 0;870}871872jstring sym = env->NewStringUTF(buf);873CHECK_EXCEPTION_(0);874jobject res = env->CallObjectMethod(obj, createClosestSymbol_ID, sym, disp);875CHECK_EXCEPTION_(0);876return res;877}878879880