/*
 * Copyright (c) 2002, 2013, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 *
 */

// this is source code windbg based SA debugger agent to debug
// Dr. Watson dump files and process snapshots.

#include "sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal.h"

#ifdef _M_IX86
  #include "sun_jvm_hotspot_debugger_x86_X86ThreadContext.h"
  #define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
#elif _M_AMD64
  #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h"
  #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
#else
  #error "SA windbg back-end is not supported for your cpu!"
#endif

#include <limits.h>
#include <windows.h>

#ifndef STDMETHODV
#define STDMETHODV(method) virtual HRESULT STDMETHODVCALLTYPE method
#endif

#define DEBUG_NO_IMPLEMENTATION
#include <dbgeng.h>
#include <dbghelp.h>

// simple template to manage array delete across early (error) returns

template <class T>
class AutoArrayPtr {
      T* m_ptr;
   public:
      AutoArrayPtr(T* ptr) : m_ptr(ptr) {
      }

      ~AutoArrayPtr() {
         delete [] m_ptr;
      }

      T* asPtr() {
         return m_ptr;
      }
};

class AutoJavaString {
      JNIEnv* m_env;
      jstring m_str;
      const char* m_buf;

   public:
      AutoJavaString(JNIEnv* env, jstring str, const char* buf)
        : m_env(env), m_str(str), m_buf(buf) {
      }

      ~AutoJavaString() {
         m_env->ReleaseStringUTFChars(m_str, m_buf);
      }

      operator const char* () {
         return m_buf;
      }
};

// field and method IDs we want here

static jfieldID imagePath_ID                    = 0;
static jfieldID symbolPath_ID                   = 0;
static jfieldID ptrIDebugClient_ID              = 0;
static jfieldID ptrIDebugControl_ID             = 0;
static jfieldID ptrIDebugDataSpaces_ID          = 0;
static jfieldID ptrIDebugOutputCallbacks_ID     = 0;
static jfieldID ptrIDebugAdvanced_ID            = 0;
static jfieldID ptrIDebugSymbols_ID             = 0;
static jfieldID ptrIDebugSystemObjects_ID       = 0;

static jmethodID addLoadObject_ID               = 0;
static jmethodID addThread_ID                   = 0;
static jmethodID createClosestSymbol_ID         = 0;
static jmethodID setThreadIntegerRegisterSet_ID = 0;

#define CHECK_EXCEPTION_(value) if(env->ExceptionOccurred()) { return value; }
#define CHECK_EXCEPTION if(env->ExceptionOccurred()) { return;}

#define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { \
                          throwNewDebuggerException(env, str); return value; }

#define THROW_NEW_DEBUGGER_EXCEPTION(str) { throwNewDebuggerException(env, str); \
 return;}

static void throwNewDebuggerException(JNIEnv* env, const char* errMsg) {
  env->ThrowNew(env->FindClass("sun/jvm/hotspot/debugger/DebuggerException"), errMsg);
}

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    initIDs
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_initIDs
  (JNIEnv *env, jclass clazz) {
  imagePath_ID = env->GetStaticFieldID(clazz, "imagePath", "Ljava/lang/String;");
  CHECK_EXCEPTION;

  symbolPath_ID = env->GetStaticFieldID(clazz, "symbolPath", "Ljava/lang/String;");
  CHECK_EXCEPTION;

  ptrIDebugClient_ID = env->GetFieldID(clazz, "ptrIDebugClient", "J");
  CHECK_EXCEPTION;

  ptrIDebugControl_ID = env->GetFieldID(clazz, "ptrIDebugControl", "J");
  CHECK_EXCEPTION;

  ptrIDebugDataSpaces_ID = env->GetFieldID(clazz, "ptrIDebugDataSpaces", "J");
  CHECK_EXCEPTION;

  ptrIDebugOutputCallbacks_ID = env->GetFieldID(clazz,
                                            "ptrIDebugOutputCallbacks", "J");
  CHECK_EXCEPTION;

  ptrIDebugAdvanced_ID = env->GetFieldID(clazz, "ptrIDebugAdvanced", "J");
  CHECK_EXCEPTION;

  ptrIDebugSymbols_ID = env->GetFieldID(clazz,
                                         "ptrIDebugSymbols", "J");
  CHECK_EXCEPTION;

  ptrIDebugSystemObjects_ID = env->GetFieldID(clazz,
                                         "ptrIDebugSystemObjects", "J");
  CHECK_EXCEPTION;

  addLoadObject_ID = env->GetMethodID(clazz, "addLoadObject",
                                         "(Ljava/lang/String;JJ)V");
  CHECK_EXCEPTION;

  addThread_ID = env->GetMethodID(clazz, "addThread", "(J)V");
  CHECK_EXCEPTION;

  createClosestSymbol_ID = env->GetMethodID(clazz, "createClosestSymbol",
    "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;");
  CHECK_EXCEPTION;

  setThreadIntegerRegisterSet_ID = env->GetMethodID(clazz,
                                         "setThreadIntegerRegisterSet", "(J[J)V");
  CHECK_EXCEPTION;

}

// class for IDebugOutputCallbacks

class SAOutputCallbacks : public IDebugOutputCallbacks {
   LONG  m_refCount;
   char* m_msgBuffer;

   public:
      SAOutputCallbacks() : m_refCount(0), m_msgBuffer(0) {
      }

      ~SAOutputCallbacks() {
         clearBuffer();
      }

      const char* getBuffer() const {
         return m_msgBuffer;
      }

      void clearBuffer() {
         if (m_msgBuffer) {
            free(m_msgBuffer);
            m_msgBuffer = 0;
         }
      }

      STDMETHOD_(ULONG, AddRef)(THIS);
      STDMETHOD_(ULONG, Release)(THIS);
      STDMETHOD(QueryInterface)(THIS_
                                IN REFIID interfaceId,
                                OUT PVOID* ppInterface);
      STDMETHOD(Output)(THIS_
                        IN ULONG mask,
                        IN PCSTR msg);
};

STDMETHODIMP_(ULONG) SAOutputCallbacks::AddRef(THIS) {
   InterlockedIncrement(&m_refCount);
   return m_refCount;
}

STDMETHODIMP_(ULONG) SAOutputCallbacks::Release(THIS) {
   LONG retVal;
   InterlockedDecrement(&m_refCount);
   retVal = m_refCount;
   if (retVal == 0) {
      delete this;
   }
   return retVal;
}

STDMETHODIMP SAOutputCallbacks::QueryInterface(THIS_
                                          IN REFIID interfaceId,
                                          OUT PVOID* ppInterface) {
   *ppInterface = 0;
   HRESULT res = E_NOINTERFACE;
   if (TRUE == IsEqualIID(interfaceId, __uuidof(IUnknown)) ||
       TRUE == IsEqualIID(interfaceId, __uuidof(IDebugOutputCallbacks))) {
      *ppInterface = (IDebugOutputCallbacks*) this;
      AddRef();
      res = S_OK;
   }
   return res;
}

STDMETHODIMP SAOutputCallbacks::Output(THIS_
                                       IN ULONG mask,
                                       IN PCSTR msg) {
   int len = (int) (strlen(msg) + 1);
   if (m_msgBuffer == 0) {
      m_msgBuffer = (char*) malloc(len);
      if (m_msgBuffer == 0) {
         fprintf(stderr, "out of memory debugger output!\n");
         return S_FALSE;
      }
      strcpy(m_msgBuffer, msg);
   } else {
      m_msgBuffer = (char*) realloc(m_msgBuffer, len + strlen(m_msgBuffer));
      if (m_msgBuffer == 0) {
         fprintf(stderr, "out of memory debugger output!\n");
         return S_FALSE;
      }
      strcat(m_msgBuffer, msg);
   }
   return S_OK;
}

static bool getWindbgInterfaces(JNIEnv* env, jobject obj) {
  // get windbg interfaces ..

  IDebugClient* ptrIDebugClient = 0;
  if (DebugCreate(__uuidof(IDebugClient), (PVOID*) &ptrIDebugClient) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to create IDebugClient object!", false);
  }
  env->SetLongField(obj, ptrIDebugClient_ID, (jlong) ptrIDebugClient);

  IDebugControl* ptrIDebugControl = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &ptrIDebugControl)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugControl", false);
  }
  env->SetLongField(obj, ptrIDebugControl_ID, (jlong) ptrIDebugControl);

  IDebugDataSpaces* ptrIDebugDataSpaces = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugDataSpaces), (PVOID*) &ptrIDebugDataSpaces)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugDataSpaces object!", false);
  }
  env->SetLongField(obj, ptrIDebugDataSpaces_ID, (jlong) ptrIDebugDataSpaces);

  SAOutputCallbacks* ptrIDebugOutputCallbacks = new SAOutputCallbacks();
  ptrIDebugOutputCallbacks->AddRef();
  env->SetLongField(obj, ptrIDebugOutputCallbacks_ID, (jlong) ptrIDebugOutputCallbacks);
  CHECK_EXCEPTION_(false);

  IDebugAdvanced* ptrIDebugAdvanced = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugAdvanced), (PVOID*) &ptrIDebugAdvanced)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugAdvanced object!", false);
  }
  env->SetLongField(obj, ptrIDebugAdvanced_ID, (jlong) ptrIDebugAdvanced);

  IDebugSymbols* ptrIDebugSymbols = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSymbols), (PVOID*) &ptrIDebugSymbols)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSymbols object!", false);
  }
  env->SetLongField(obj, ptrIDebugSymbols_ID, (jlong) ptrIDebugSymbols);

  IDebugSystemObjects* ptrIDebugSystemObjects = 0;
  if (ptrIDebugClient->QueryInterface(__uuidof(IDebugSystemObjects), (PVOID*) &ptrIDebugSystemObjects)
     != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: not able to get IDebugSystemObjects object!", false);
  }
  env->SetLongField(obj, ptrIDebugSystemObjects_ID, (jlong) ptrIDebugSystemObjects);

  return true;
}

static bool setImageAndSymbolPath(JNIEnv* env, jobject obj) {
  jboolean isCopy;
  jclass clazz = env->GetObjectClass(obj);
  jstring path;
  const char* buf;

  path = (jstring) env->GetStaticObjectField(clazz, imagePath_ID);
  buf = env->GetStringUTFChars(path, &isCopy);
  CHECK_EXCEPTION_(false);
  AutoJavaString imagePath(env, path, buf);

  path = (jstring) env->GetStaticObjectField(clazz, symbolPath_ID);
  buf = env->GetStringUTFChars(path, &isCopy);
  CHECK_EXCEPTION_(false);
  AutoJavaString symbolPath(env, path, buf);

  IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,
                                                      ptrIDebugSymbols_ID);
  CHECK_EXCEPTION_(false);

  ptrIDebugSymbols->SetImagePath(imagePath);
  ptrIDebugSymbols->SetSymbolPath(symbolPath);
  return true;
}

static bool openDumpFile(JNIEnv* env, jobject obj, jstring coreFileName) {
  // open the dump file
  jboolean isCopy;
  const char* buf = env->GetStringUTFChars(coreFileName, &isCopy);
  CHECK_EXCEPTION_(false);
  AutoJavaString coreFile(env, coreFileName, buf);
  if (setImageAndSymbolPath(env, obj) == false) {
     return false;
  }

  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugClient->OpenDumpFile(coreFile) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: OpenDumpFile failed!", false);
  }

  IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,
                                                     ptrIDebugControl_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false);
  }

  return true;
}


static bool attachToProcess(JNIEnv* env, jobject obj, jint pid) {
  if (setImageAndSymbolPath(env, obj) == false) {
     return false;
  }
  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION_(false);

  /***********************************************************************************

     We are attaching to a process in 'read-only' mode. i.e., we do not want to
     put breakpoints, suspend/resume threads etc. For read-only JDI and HSDB kind of
     usage this should suffice.

     Please refer to DEBUG_ATTACH_NONINVASIVE mode source comments from dbgeng.h.
     In this mode, debug engine does not call DebugActiveProrcess. i.e., we are not
     actually debugging at all. We can safely 'detach' from the process anytime
     we want and debuggee process is left as is on all Windows variants.

     This also makes JDI-on-SA installation/usage simpler because with this we would
     not need a tool like ServiceInstaller from http://www.kcmultimedia.com/smaster.

  ***********************************************************************************/


  if (ptrIDebugClient->AttachProcess(0, pid, DEBUG_ATTACH_NONINVASIVE) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: AttachProcess failed!", false);
  }

  IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,
                                                     ptrIDebugControl_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugControl->WaitForEvent(DEBUG_WAIT_DEFAULT, INFINITE) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: WaitForEvent failed!", false);
  }

  return true;
}


static bool addLoadObjects(JNIEnv* env, jobject obj) {
  IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,
                                                      ptrIDebugSymbols_ID);
  CHECK_EXCEPTION_(false);
  ULONG loaded = 0, unloaded = 0;
  if (ptrIDebugSymbols->GetNumberModules(&loaded, &unloaded) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberModules failed!", false);
  }

  AutoArrayPtr<DEBUG_MODULE_PARAMETERS> params(new DEBUG_MODULE_PARAMETERS[loaded]);

  if (params.asPtr() == 0) {
      THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate debug module params!", false);
  }

  if (ptrIDebugSymbols->GetModuleParameters(loaded, 0, NULL, params.asPtr()) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleParameters failed!", false);
  }

  for (int u = 0; u < (int)loaded; u++) {
     TCHAR imageName[MAX_PATH];
     if (ptrIDebugSymbols->GetModuleNames(DEBUG_ANY_ID, params.asPtr()[u].Base,
                                      imageName, MAX_PATH, NULL, NULL,
                                      0, NULL, NULL, 0, NULL) != S_OK) {
        THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetModuleNames failed!", false);
     }

     jstring strName = env->NewStringUTF(imageName);
     CHECK_EXCEPTION_(false);
     env->CallVoidMethod(obj, addLoadObject_ID, strName, (jlong) params.asPtr()[u].Size,
                               (jlong) params.asPtr()[u].Base);
     CHECK_EXCEPTION_(false);
  }

  return true;
}

static bool addThreads(JNIEnv* env, jobject obj) {
  IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,
                                                      ptrIDebugSystemObjects_ID);
  CHECK_EXCEPTION_(false);

  ULONG numThreads = 0;
  if (ptrIDebugSystemObjects->GetNumberThreads(&numThreads) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetNumberThreads failed!", false);
  }

  AutoArrayPtr<ULONG> ptrSysThreadIds = new ULONG[numThreads];

  if (ptrSysThreadIds.asPtr() == 0) {
     THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false);
  }

  AutoArrayPtr<ULONG> ptrThreadIds = new ULONG[numThreads];

  if (ptrThreadIds.asPtr() == 0) {
     THROW_NEW_DEBUGGER_EXCEPTION_("out of memory to allocate thread ids!", false);
  }

  if (ptrIDebugSystemObjects->GetThreadIdsByIndex(0, numThreads,
                                      ptrThreadIds.asPtr(), ptrSysThreadIds.asPtr()) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdsByIndex failed!", false);
  }


  IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj,
                                                      ptrIDebugAdvanced_ID);
  CHECK_EXCEPTION_(false);

  // for each thread, get register context and save it.
  for (ULONG t = 0; t < numThreads; t++) {
     if (ptrIDebugSystemObjects->SetCurrentThreadId(ptrThreadIds.asPtr()[t]) != S_OK) {
        THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetCurrentThread failed!", false);
     }

     jlongArray regs = env->NewLongArray(NPRGREG);
     CHECK_EXCEPTION_(false);

     jboolean isCopy = JNI_FALSE;
     jlong* ptrRegs = env->GetLongArrayElements(regs, &isCopy);
     CHECK_EXCEPTION_(false);

     // copy register values from the CONTEXT struct
     CONTEXT context;
     memset(&context, 0, sizeof(CONTEXT));

#undef REG_INDEX
#ifdef _M_IX86
     #define REG_INDEX(x) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##x

     context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
     ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT));

     ptrRegs[REG_INDEX(GS)]  = context.SegGs;
     ptrRegs[REG_INDEX(FS)]  = context.SegFs;
     ptrRegs[REG_INDEX(ES)]  = context.SegEs;
     ptrRegs[REG_INDEX(DS)]  = context.SegDs;

     ptrRegs[REG_INDEX(EDI)] = context.Edi;
     ptrRegs[REG_INDEX(ESI)] = context.Esi;
     ptrRegs[REG_INDEX(EBX)] = context.Ebx;
     ptrRegs[REG_INDEX(EDX)] = context.Edx;
     ptrRegs[REG_INDEX(ECX)] = context.Ecx;
     ptrRegs[REG_INDEX(EAX)] = context.Eax;

     ptrRegs[REG_INDEX(FP)] = context.Ebp;
     ptrRegs[REG_INDEX(PC)] = context.Eip;
     ptrRegs[REG_INDEX(CS)]  = context.SegCs;
     ptrRegs[REG_INDEX(EFL)] = context.EFlags;
     ptrRegs[REG_INDEX(SP)] = context.Esp;
     ptrRegs[REG_INDEX(SS)]  = context.SegSs;

     ptrRegs[REG_INDEX(DR0)] = context.Dr0;
     ptrRegs[REG_INDEX(DR1)] = context.Dr1;
     ptrRegs[REG_INDEX(DR2)] = context.Dr2;
     ptrRegs[REG_INDEX(DR3)] = context.Dr3;
     ptrRegs[REG_INDEX(DR6)] = context.Dr6;
     ptrRegs[REG_INDEX(DR7)] = context.Dr7;

#elif _M_AMD64
     #define REG_INDEX(x) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##x

     context.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
     ptrIDebugAdvanced->GetThreadContext(&context, sizeof(CONTEXT));

     // Segment Registers and processor flags
     ptrRegs[REG_INDEX(CS)]  = context.SegCs;
     ptrRegs[REG_INDEX(DS)]  = context.SegDs;
     ptrRegs[REG_INDEX(ES)]  = context.SegEs;
     ptrRegs[REG_INDEX(FS)]  = context.SegFs;
     ptrRegs[REG_INDEX(GS)]  = context.SegGs;
     ptrRegs[REG_INDEX(SS)]  = context.SegSs;
     ptrRegs[REG_INDEX(RFL)] = context.EFlags;

     // Integer registers
     ptrRegs[REG_INDEX(RDI)] = context.Rdi;
     ptrRegs[REG_INDEX(RSI)] = context.Rsi;
     ptrRegs[REG_INDEX(RAX)] = context.Rax;
     ptrRegs[REG_INDEX(RCX)] = context.Rcx;
     ptrRegs[REG_INDEX(RDX)] = context.Rdx;
     ptrRegs[REG_INDEX(RBX)] = context.Rbx;
     ptrRegs[REG_INDEX(RBP)] = context.Rbp;
     ptrRegs[REG_INDEX(RSP)] = context.Rsp;

     ptrRegs[REG_INDEX(R8)]  = context.R8;
     ptrRegs[REG_INDEX(R9)]  = context.R9;
     ptrRegs[REG_INDEX(R10)] = context.R10;
     ptrRegs[REG_INDEX(R11)] = context.R11;
     ptrRegs[REG_INDEX(R12)] = context.R12;
     ptrRegs[REG_INDEX(R13)] = context.R13;
     ptrRegs[REG_INDEX(R14)] = context.R14;
     ptrRegs[REG_INDEX(R15)] = context.R15;

     // Program counter
     ptrRegs[REG_INDEX(RIP)] = context.Rip;
#endif

     env->ReleaseLongArrayElements(regs, ptrRegs, JNI_COMMIT);
     CHECK_EXCEPTION_(false);

     env->CallVoidMethod(obj, setThreadIntegerRegisterSet_ID,
                        (jlong) ptrThreadIds.asPtr()[t], regs);
     CHECK_EXCEPTION_(false);

     ULONG sysId;
     if (ptrIDebugSystemObjects->GetCurrentThreadSystemId(&sysId) != S_OK) {
        THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetCurrentThreadSystemId failed!", false);
     }

     env->CallVoidMethod(obj, addThread_ID, (jlong) sysId);
     CHECK_EXCEPTION_(false);
  }

  return true;
}

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    attach0
 * Signature: (Ljava/lang/String;Ljava/lang/String;)V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2
  (JNIEnv *env, jobject obj, jstring execName, jstring coreFileName) {

  if (getWindbgInterfaces(env, obj) == false) {
     return;
  }

  if (openDumpFile(env, obj, coreFileName) == false) {
     return;
  }

  if (addLoadObjects(env, obj) == false) {
     return;
  }

  if (addThreads(env, obj) == false) {
     return;
  }
}

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    attach0
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_attach0__I
  (JNIEnv *env, jobject obj, jint pid) {

  if (getWindbgInterfaces(env, obj) == false) {
     return;
  }

  if (attachToProcess(env, obj, pid) == false) {
     return;
  }

  if (addLoadObjects(env, obj) == false) {
     return;
  }

  if (addThreads(env, obj) == false) {
     return;
  }
}


static bool releaseWindbgInterfaces(JNIEnv* env, jobject obj) {
  IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj,
                                                      ptrIDebugDataSpaces_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugDataSpaces != 0) {
     ptrIDebugDataSpaces->Release();
  }

  IDebugOutputCallbacks* ptrIDebugOutputCallbacks = (IDebugOutputCallbacks*)
                          env->GetLongField(obj, ptrIDebugOutputCallbacks_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugOutputCallbacks != 0) {
     ptrIDebugOutputCallbacks->Release();
  }

  IDebugAdvanced* ptrIDebugAdvanced = (IDebugAdvanced*) env->GetLongField(obj,
                                                      ptrIDebugAdvanced_ID);
  CHECK_EXCEPTION_(false);

  if (ptrIDebugAdvanced != 0) {
     ptrIDebugAdvanced->Release();
  }

  IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,
                                                      ptrIDebugSymbols_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugSymbols != 0) {
     ptrIDebugSymbols->Release();
  }

  IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,
                                                      ptrIDebugSystemObjects_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugSystemObjects != 0) {
     ptrIDebugSystemObjects->Release();
  }

  IDebugControl* ptrIDebugControl = (IDebugControl*) env->GetLongField(obj,
                                                     ptrIDebugControl_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugControl != 0) {
     ptrIDebugControl->Release();
  }

  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION_(false);
  if (ptrIDebugClient != 0) {
     ptrIDebugClient->Release();
  }

  return true;
}

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    detach0
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_detach0
  (JNIEnv *env, jobject obj) {
  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj,
                                                      ptrIDebugClient_ID);
  CHECK_EXCEPTION;
  ptrIDebugClient->DetachProcesses();
  releaseWindbgInterfaces(env, obj);
}


/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    readBytesFromProcess0
 * Signature: (JJ)[B
 */
JNIEXPORT jbyteArray JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_readBytesFromProcess0
  (JNIEnv *env, jobject obj, jlong address, jlong numBytes) {
  jbyteArray byteArray = env->NewByteArray((long) numBytes);
  CHECK_EXCEPTION_(0);

  jboolean isCopy = JNI_FALSE;
  jbyte* bytePtr = env->GetByteArrayElements(byteArray, &isCopy);
  CHECK_EXCEPTION_(0);

  IDebugDataSpaces* ptrIDebugDataSpaces = (IDebugDataSpaces*) env->GetLongField(obj,
                                                       ptrIDebugDataSpaces_ID);
  CHECK_EXCEPTION_(0);

  ULONG bytesRead;
  if (ptrIDebugDataSpaces->ReadVirtual((ULONG64) address, (PVOID) bytePtr,
                                  (ULONG)numBytes, &bytesRead) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: ReadVirtual failed!", 0);
  }

  if (bytesRead != numBytes) {
     return 0;
  }

  env->ReleaseByteArrayElements(byteArray, bytePtr, 0);
  CHECK_EXCEPTION_(0);

  return byteArray;
}

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    getThreadIdFromSysId0
 * Signature: (J)J
 */
JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_getThreadIdFromSysId0
  (JNIEnv *env, jobject obj, jlong sysId) {
  IDebugSystemObjects* ptrIDebugSystemObjects = (IDebugSystemObjects*) env->GetLongField(obj,
                                                    ptrIDebugSystemObjects_ID);
  CHECK_EXCEPTION_(0);

  ULONG id = 0;
  if (ptrIDebugSystemObjects->GetThreadIdBySystemId((ULONG)sysId, &id) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: GetThreadIdBySystemId failed!", 0);
  }

  return (jlong) id;
}

// manage COM 'auto' pointers (to avoid multiple Release
// calls at every early (exception) returns). Similar to AutoArrayPtr.

template <class T>
class AutoCOMPtr {
      T* m_ptr;

   public:
      AutoCOMPtr(T* ptr) : m_ptr(ptr) {
      }

      ~AutoCOMPtr() {
         if (m_ptr) {
            m_ptr->Release();
         }
      }

      T* operator->() {
         return m_ptr;
      }
};

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    consoleExecuteCommand0
 * Signature: (Ljava/lang/String;)Ljava/lang/String;
 */
JNIEXPORT jstring JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_consoleExecuteCommand0
  (JNIEnv *env, jobject obj, jstring cmd) {
  jboolean isCopy = JNI_FALSE;
  const char* buf = env->GetStringUTFChars(cmd, &isCopy);
  CHECK_EXCEPTION_(0);
  AutoJavaString command(env, cmd, buf);

  IDebugClient* ptrIDebugClient = (IDebugClient*) env->GetLongField(obj, ptrIDebugClient_ID);
  CHECK_EXCEPTION_(0);

  IDebugClient*  tmpClientPtr = 0;
  if (ptrIDebugClient->CreateClient(&tmpClientPtr) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: CreateClient failed!", 0);
  }
  AutoCOMPtr<IDebugClient> tmpClient(tmpClientPtr);

  IDebugControl* tmpControlPtr = 0;
  if (tmpClient->QueryInterface(__uuidof(IDebugControl), (PVOID*) &tmpControlPtr) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: QueryInterface (IDebugControl) failed", 0);
  }
  AutoCOMPtr<IDebugControl> tmpControl(tmpControlPtr);

  SAOutputCallbacks* saOutputCallbacks = (SAOutputCallbacks*) env->GetLongField(obj,
                                                                   ptrIDebugOutputCallbacks_ID);
  CHECK_EXCEPTION_(0);

  saOutputCallbacks->clearBuffer();

  if (tmpClient->SetOutputCallbacks(saOutputCallbacks) != S_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("Windbg Error: SetOutputCallbacks failed!", 0);
  }

  tmpControl->Execute(DEBUG_OUTPUT_VERBOSE, command, DEBUG_EXECUTE_DEFAULT);

  const char* output = saOutputCallbacks->getBuffer();
  if (output == 0) {
     output = "";
  }

  jstring res = env->NewStringUTF(output);
  saOutputCallbacks->clearBuffer();
  return res;
}

/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    lookupByName0
 * Signature: (Ljava/lang/String;Ljava/lang/String;)J
 */

JNIEXPORT jlong JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByName0
(JNIEnv *env, jobject obj, jstring objName, jstring sym) {
  IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,
                                                      ptrIDebugSymbols_ID);
  CHECK_EXCEPTION_(0);

  jboolean isCopy;
  const char* buf = env->GetStringUTFChars(sym, &isCopy);
  CHECK_EXCEPTION_(0);
  AutoJavaString name(env, sym, buf);

  ULONG64 offset = 0L;
  if (strstr(name, "::") != 0) {
    ptrIDebugSymbols->AddSymbolOptions(SYMOPT_UNDNAME);
  } else {
    ptrIDebugSymbols->RemoveSymbolOptions(SYMOPT_UNDNAME);
  }
  if (ptrIDebugSymbols->GetOffsetByName(name, &offset) != S_OK) {
    return (jlong) 0;
  }
  return (jlong) offset;
}

#define SYMBOL_BUFSIZE 512
/*
 * Class:     sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal
 * Method:    lookupByAddress0
 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;
 */
JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_windbg_WindbgDebuggerLocal_lookupByAddress0
(JNIEnv *env, jobject obj, jlong address) {
  IDebugSymbols* ptrIDebugSymbols = (IDebugSymbols*) env->GetLongField(obj,
                                                      ptrIDebugSymbols_ID);
  CHECK_EXCEPTION_(0);

  ULONG64 disp = 0L;
  char buf[SYMBOL_BUFSIZE];
  memset(buf, 0, sizeof(buf));

  if (ptrIDebugSymbols->GetNameByOffset(address, buf, sizeof(buf),0,&disp)
      != S_OK) {
    return 0;
  }

  jstring sym = env->NewStringUTF(buf);
  CHECK_EXCEPTION_(0);
  jobject res = env->CallObjectMethod(obj, createClosestSymbol_ID, sym, disp);
  CHECK_EXCEPTION_(0);
  return res;
}
