Пример #1
0
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;
}
Пример #2
0
/*
 * Class:       sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal
 * Method:      getThreadIntegerRegisterSet0
 * Signature:   (J)[J
 * Description: get gregset for a given thread specified by thread id
 */
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_proc_ProcDebuggerLocal_getThreadIntegerRegisterSet0
  (JNIEnv *env, jobject this_obj, jlong tid) {
  // map the thread id to thread handle
  p_td_ta_map_id2thr_t p_td_ta_map_id2thr = (p_td_ta_map_id2thr_t) env->GetLongField(this_obj, p_td_ta_map_id2thr_ID);

  td_thragent_t* p_td_thragent_t = (td_thragent_t*) env->GetLongField(this_obj, p_td_thragent_t_ID);
  if (p_td_thragent_t == 0) {
     return 0;
  }

  td_thrhandle_t thr_handle;
  if (p_td_ta_map_id2thr(p_td_thragent_t, (thread_t) tid, &thr_handle) != TD_OK) {
     THROW_NEW_DEBUGGER_EXCEPTION_("can't map thread id to thread handle!", 0);
  }

  p_td_thr_getgregs_t p_td_thr_getgregs = (p_td_thr_getgregs_t) env->GetLongField(this_obj, p_td_thr_getgregs_ID);
  prgregset_t gregs;
  p_td_thr_getgregs(&thr_handle, gregs);

  jlongArray res = env->NewLongArray(NPRGREG);
  CHECK_EXCEPTION_(0);
  jboolean isCopy;
  jlong* ptr = env->GetLongArrayElements(res, &isCopy);
  CHECK_EXCEPTION_(NULL);
  for (int i = 0; i < NPRGREG; i++) {
    ptr[i] = (jlong) (uintptr_t) gregs[i];
  }
  env->ReleaseLongArrayElements(res, ptr, JNI_COMMIT);
  return res;
}
Пример #3
0
/*
 * 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;
}
Пример #4
0
/*
 * 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;
}
Пример #5
0
/*
 * 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;
}
Пример #6
0
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. We are not intending to use this for full-fledged
     ProcessControl implementation to be used with BugSpotAgent.

     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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
int iterate_map(void *cd, const prmap_t* pmp, const char* obj_name) {

    /*
     * we are iterating over load maps of the process/core.
     * look for first mapping of libjvm[_g].so. If we get this mapping
     * store the initial virtual address of the libjvm[_g].so and libjvm[_g].so
     * size in the debugger object.
     */

    if (obj_name != 0) {
       if (strstr(obj_name, "libjvm.so") != 0 || strstr(obj_name, "libjvm_g.so") != 0) {

           Debugger* dbg = (Debugger*) cd;
           JNIEnv*   env = dbg->env;

           /*
            * get libjvm[_g].so's starting text virtual address. We just take the
            * starting virtual address of libjvm[_g].so's mapping.
            */
 
           dbg->env->SetLongField(dbg->obj, libjvm_text_start_ID, pmp->pr_vaddr);

           // open the libjvm.so
           int fd = open(obj_name, O_RDONLY);
           if (fd < 0) {
               char errMsg[PATH_MAX + 128];
               sprintf(errMsg, "Can't open %s!", obj_name);
               THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
           }

           dbg->env->SetIntField(dbg->obj, libjvm_fd_ID, fd);
           return 1;
       }
    }

    return 0;
}
Пример #10
0
JNIEXPORT jlongArray JNICALL Java_sun_jvm_hotspot_debugger_linux_LinuxDebuggerLocal_getThreadIntegerRegisterSet0
  (JNIEnv *env, jobject this_obj, jint lwp_id) {

  struct user_regs_struct gregs;
  jboolean isCopy;
  jlongArray array;
  jlong *regs;
  int i;

  struct ps_prochandle* ph = get_proc_handle(env, this_obj);
  if (get_lwp_regs(ph, lwp_id, &gregs) != true) {
     THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0);
  }

#undef NPRGREG
#ifdef i386
#define NPRGREG sun_jvm_hotspot_debugger_x86_X86ThreadContext_NPRGREG
#endif
#ifdef ia64
#define NPRGREG IA64_REG_COUNT
#endif
#ifdef amd64
#define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG
#endif
#if defined(sparc) || defined(sparcv9)
#define NPRGREG sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_NPRGREG
#endif

  array = (*env)->NewLongArray(env, NPRGREG);
  CHECK_EXCEPTION_(0);
  regs = (*env)->GetLongArrayElements(env, array, &isCopy);

#undef REG_INDEX

#ifdef i386
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_x86_X86ThreadContext_##reg

  regs[REG_INDEX(GS)]  = (uintptr_t) gregs.xgs;
  regs[REG_INDEX(FS)]  = (uintptr_t) gregs.xfs;
  regs[REG_INDEX(ES)]  = (uintptr_t) gregs.xes;
  regs[REG_INDEX(DS)]  = (uintptr_t) gregs.xds;
  regs[REG_INDEX(EDI)] = (uintptr_t) gregs.edi;
  regs[REG_INDEX(ESI)] = (uintptr_t) gregs.esi;
  regs[REG_INDEX(FP)] = (uintptr_t) gregs.ebp;
  regs[REG_INDEX(SP)] = (uintptr_t) gregs.esp;
  regs[REG_INDEX(EBX)] = (uintptr_t) gregs.ebx;
  regs[REG_INDEX(EDX)] = (uintptr_t) gregs.edx;
  regs[REG_INDEX(ECX)] = (uintptr_t) gregs.ecx;
  regs[REG_INDEX(EAX)] = (uintptr_t) gregs.eax;
  regs[REG_INDEX(PC)] = (uintptr_t) gregs.eip;
  regs[REG_INDEX(CS)]  = (uintptr_t) gregs.xcs;
  regs[REG_INDEX(SS)]  = (uintptr_t) gregs.xss;

#endif /* i386 */

#if ia64
  regs = (*env)->GetLongArrayElements(env, array, &isCopy);
  for (i = 0; i < NPRGREG; i++ ) {
    regs[i] = 0xDEADDEAD;
  }
#endif /* ia64 */

#ifdef amd64
#define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg

  regs[REG_INDEX(R15)] = gregs.r15;
  regs[REG_INDEX(R14)] = gregs.r14;
  regs[REG_INDEX(R13)] = gregs.r13;
  regs[REG_INDEX(R12)] = gregs.r12;
  regs[REG_INDEX(RBP)] = gregs.rbp;
  regs[REG_INDEX(RBX)] = gregs.rbx;
  regs[REG_INDEX(R11)] = gregs.r11;
  regs[REG_INDEX(R10)] = gregs.r10;
  regs[REG_INDEX(R9)] = gregs.r9;
  regs[REG_INDEX(R8)] = gregs.r8;
  regs[REG_INDEX(RAX)] = gregs.rax;
  regs[REG_INDEX(RCX)] = gregs.rcx;
  regs[REG_INDEX(RDX)] = gregs.rdx;
  regs[REG_INDEX(RSI)] = gregs.rsi;
  regs[REG_INDEX(RDI)] = gregs.rdi;
  regs[REG_INDEX(RIP)] = gregs.rip;
  regs[REG_INDEX(CS)] = gregs.cs;
  regs[REG_INDEX(RSP)] = gregs.rsp;
  regs[REG_INDEX(SS)] = gregs.ss;
  regs[REG_INDEX(FSBASE)] = gregs.fs_base;
  regs[REG_INDEX(GSBASE)] = gregs.gs_base;
  regs[REG_INDEX(DS)] = gregs.ds;
  regs[REG_INDEX(ES)] = gregs.es;
  regs[REG_INDEX(FS)] = gregs.fs;
  regs[REG_INDEX(GS)] = gregs.gs;

#endif /* amd64 */

#if defined(sparc) || defined(sparcv9)

#define REG_INDEX(reg) sun_jvm_hotspot_debugger_sparc_SPARCThreadContext_##reg

#ifdef _LP64
  regs[REG_INDEX(R_PSR)] = gregs.tstate;
  regs[REG_INDEX(R_PC)]  = gregs.tpc;
  regs[REG_INDEX(R_nPC)] = gregs.tnpc;
  regs[REG_INDEX(R_Y)]   = gregs.y;
#else
  regs[REG_INDEX(R_PSR)] = gregs.psr;
  regs[REG_INDEX(R_PC)]  = gregs.pc;
  regs[REG_INDEX(R_nPC)] = gregs.npc;
  regs[REG_INDEX(R_Y)]   = gregs.y;
#endif
  regs[REG_INDEX(R_G0)]  =            0 ;
  regs[REG_INDEX(R_G1)]  = gregs.u_regs[0];
  regs[REG_INDEX(R_G2)]  = gregs.u_regs[1];
  regs[REG_INDEX(R_G3)]  = gregs.u_regs[2];
  regs[REG_INDEX(R_G4)]  = gregs.u_regs[3];
  regs[REG_INDEX(R_G5)]  = gregs.u_regs[4];
  regs[REG_INDEX(R_G6)]  = gregs.u_regs[5];
  regs[REG_INDEX(R_G7)]  = gregs.u_regs[6];
  regs[REG_INDEX(R_O0)]  = gregs.u_regs[7];
  regs[REG_INDEX(R_O1)]  = gregs.u_regs[8];
  regs[REG_INDEX(R_O2)]  = gregs.u_regs[ 9];
  regs[REG_INDEX(R_O3)]  = gregs.u_regs[10];
  regs[REG_INDEX(R_O4)]  = gregs.u_regs[11];
  regs[REG_INDEX(R_O5)]  = gregs.u_regs[12];
  regs[REG_INDEX(R_O6)]  = gregs.u_regs[13];
  regs[REG_INDEX(R_O7)]  = gregs.u_regs[14];
#endif /* sparc */


  (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT);
  return array;
}
Пример #11
0
static int
init_classsharing_workaround(void *cd, const prmap_t* pmap, const char* obj_name) {
  Debugger* dbg = (Debugger*) cd;
  JNIEnv*   env = dbg->env;
  jobject this_obj = dbg->this_obj;
  const char* jvm_name = 0;
  if ((jvm_name = strstr(obj_name, "libjvm.so")) != NULL) {
    jvm_name = obj_name;
  } else {
    return 0;
  }

  struct ps_prochandle* ph = (struct ps_prochandle*) env->GetLongField(this_obj, p_ps_prochandle_ID);

  // initialize classes.jsa file descriptor field.
  dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, -1);

  // check whether class sharing is on by reading variable "UseSharedSpaces"
  psaddr_t useSharedSpacesAddr = 0;
  ps_pglobal_lookup(ph, jvm_name, USE_SHARED_SPACES_SYM, &useSharedSpacesAddr);
  if (useSharedSpacesAddr == 0) {
    THROW_NEW_DEBUGGER_EXCEPTION_("can't find 'UseSharedSpaces' flag\n", 1);
  }

  // read the value of the flag "UseSharedSpaces"
  // Since hotspot types are not available to build this library. So
  // equivalent type "jboolean" is used to read the value of "UseSharedSpaces"
  // which is same as hotspot type "bool".
  jboolean value = 0;
  if (read_jboolean(ph, useSharedSpacesAddr, &value) != true) {
    THROW_NEW_DEBUGGER_EXCEPTION_("can't read 'UseSharedSpaces' flag", 1);
  } else if ((int)value == 0) {
    print_debug("UseSharedSpaces is false, assuming -Xshare:off!\n");
    return 1;
  }

  char classes_jsa[PATH_MAX];
  psaddr_t sharedArchivePathAddrAddr = 0;
  ps_pglobal_lookup(ph, jvm_name, SHARED_ARCHIVE_PATH_SYM, &sharedArchivePathAddrAddr);
  if (sharedArchivePathAddrAddr == 0) {
    print_debug("can't find symbol 'Arguments::SharedArchivePath'\n");
    THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
  }

  uintptr_t sharedArchivePathAddr = 0;
  if (read_pointer(ph, sharedArchivePathAddrAddr, &sharedArchivePathAddr) != true) {
    print_debug("can't find read pointer 'Arguments::SharedArchivePath'\n");
    THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
  }

  if (read_string(ph, (psaddr_t)sharedArchivePathAddr, classes_jsa, sizeof(classes_jsa)) != true) {
    print_debug("can't find read 'Arguments::SharedArchivePath' value\n");
    THROW_NEW_DEBUGGER_EXCEPTION_("can't get shared archive path from debuggee", 1);
  }

  print_debug("looking for %s\n", classes_jsa);

  // open the classes.jsa
  int fd = libsaproc_open(classes_jsa, O_RDONLY);
  if (fd < 0) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "can't open shared archive file %s", classes_jsa);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  } else {
    print_debug("opened shared archive file %s\n", classes_jsa);
  }

  // parse classes.jsa
  struct FileMapHeader* pheader = (struct FileMapHeader*) malloc(sizeof(struct FileMapHeader));
  if (pheader == NULL) {
    close(fd);
    THROW_NEW_DEBUGGER_EXCEPTION_("can't allocate memory for shared file map header", 1);
  }

  memset(pheader, 0, sizeof(struct FileMapHeader));
  // read FileMapHeader
  size_t n = read(fd, pheader, sizeof(struct FileMapHeader));
  if (n != sizeof(struct FileMapHeader)) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "unable to read shared archive file map header from %s", classes_jsa);
    close(fd);
    free(pheader);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  }

  // check file magic
  if (pheader->_magic != 0xf00baba2) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "%s has bad shared archive magic 0x%x, expecting 0xf00baba2",
                   classes_jsa, pheader->_magic);
    close(fd);
    free(pheader);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  }

  // check version
  if (pheader->_version != CURRENT_ARCHIVE_VERSION) {
    char errMsg[ERR_MSG_SIZE];
    sprintf(errMsg, "%s has wrong shared archive version %d, expecting %d",
                   classes_jsa, pheader->_version, CURRENT_ARCHIVE_VERSION);
    close(fd);
    free(pheader);
    THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 1);
  }

  if (_libsaproc_debug) {
    for (int m = 0; m < NUM_SHARED_MAPS; m++) {
       print_debug("shared file offset %d mapped at 0x%lx, size = %ld, read only? = %d\n",
          pheader->_space[m]._file_offset, pheader->_space[m]._base,
          pheader->_space[m]._used, pheader->_space[m]._read_only);
    }
  }

  // FIXME: For now, omitting other checks such as VM version etc.

  // store class archive file fd and map header in debugger object fields
  dbg->env->SetIntField(this_obj, classes_jsa_fd_ID, fd);
  dbg->env->SetLongField(this_obj, p_file_map_header_ID, (jlong)(uintptr_t) pheader);
  return 1;
}
Пример #12
0
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_IA64
     #define REG_INDEX(x) sun_jvm_hotspot_debugger_ia64_IA64ThreadContext_##x

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

     ptrRegs[REG_INDEX(GR0)]  = 0; // always 0
     ptrRegs[REG_INDEX(GR1)]  = context.IntGp;  // r1
     ptrRegs[REG_INDEX(GR2)]  = context.IntT0;  // r2-r3
     ptrRegs[REG_INDEX(GR3)]  = context.IntT1;
     ptrRegs[REG_INDEX(GR4)]  = context.IntS0;  // r4-r7
     ptrRegs[REG_INDEX(GR5)]  = context.IntS1;
     ptrRegs[REG_INDEX(GR6)]  = context.IntS2;
     ptrRegs[REG_INDEX(GR7)]  = context.IntS3;
     ptrRegs[REG_INDEX(GR8)]  = context.IntV0;  // r8
     ptrRegs[REG_INDEX(GR9)]  = context.IntT2;  // r9-r11
     ptrRegs[REG_INDEX(GR10)] = context.IntT3;
     ptrRegs[REG_INDEX(GR11)] = context.IntT4;
     ptrRegs[REG_INDEX(GR12)] = context.IntSp;  // r12 stack pointer
     ptrRegs[REG_INDEX(GR13)] = context.IntTeb; // r13 teb
     ptrRegs[REG_INDEX(GR14)] = context.IntT5;  // r14-r31
     ptrRegs[REG_INDEX(GR15)] = context.IntT6;
     ptrRegs[REG_INDEX(GR16)] = context.IntT7;
     ptrRegs[REG_INDEX(GR17)] = context.IntT8;
     ptrRegs[REG_INDEX(GR18)] = context.IntT9;
     ptrRegs[REG_INDEX(GR19)] = context.IntT10;
     ptrRegs[REG_INDEX(GR20)] = context.IntT11;
     ptrRegs[REG_INDEX(GR21)] = context.IntT12;
     ptrRegs[REG_INDEX(GR22)] = context.IntT13;
     ptrRegs[REG_INDEX(GR23)] = context.IntT14;
     ptrRegs[REG_INDEX(GR24)] = context.IntT15;
     ptrRegs[REG_INDEX(GR25)] = context.IntT16;
     ptrRegs[REG_INDEX(GR26)] = context.IntT17;
     ptrRegs[REG_INDEX(GR27)] = context.IntT18;
     ptrRegs[REG_INDEX(GR28)] = context.IntT19;
     ptrRegs[REG_INDEX(GR29)] = context.IntT20;
     ptrRegs[REG_INDEX(GR30)] = context.IntT21;
     ptrRegs[REG_INDEX(GR31)] = context.IntT22;

     ptrRegs[REG_INDEX(INT_NATS)] = context.IntNats;
     ptrRegs[REG_INDEX(PREDS)]    = context.Preds;

     ptrRegs[REG_INDEX(BR_RP)] = context.BrRp;
     ptrRegs[REG_INDEX(BR1)]   = context.BrS0;  // b1-b5
     ptrRegs[REG_INDEX(BR2)]   = context.BrS1;
     ptrRegs[REG_INDEX(BR3)]   = context.BrS2;
     ptrRegs[REG_INDEX(BR4)]   = context.BrS3;
     ptrRegs[REG_INDEX(BR5)]   = context.BrS4;
     ptrRegs[REG_INDEX(BR6)]   = context.BrT0;  // b6-b7
     ptrRegs[REG_INDEX(BR7)]   = context.BrT1;

     ptrRegs[REG_INDEX(AP_UNAT)] = context.ApUNAT;
     ptrRegs[REG_INDEX(AP_LC)]   = context.ApLC;
     ptrRegs[REG_INDEX(AP_EC)]   = context.ApEC;
     ptrRegs[REG_INDEX(AP_CCV)]  = context.ApCCV;
     ptrRegs[REG_INDEX(AP_DCR)]  = context.ApDCR;

     ptrRegs[REG_INDEX(RS_PFS)]      = context.RsPFS;
     ptrRegs[REG_INDEX(RS_BSP)]      = context.RsBSP;
     ptrRegs[REG_INDEX(RS_BSPSTORE)] = context.RsBSPSTORE;
     ptrRegs[REG_INDEX(RS_RSC)]      = context.RsRSC;
     ptrRegs[REG_INDEX(RS_RNAT)]     = context.RsRNAT;

     ptrRegs[REG_INDEX(ST_IPSR)] = context.StIPSR;
     ptrRegs[REG_INDEX(ST_IIP)]  = context.StIIP;
     ptrRegs[REG_INDEX(ST_IFS)]  = context.StIFS;

     ptrRegs[REG_INDEX(DB_I0)] = context.DbI0;
     ptrRegs[REG_INDEX(DB_I1)] = context.DbI1;
     ptrRegs[REG_INDEX(DB_I2)] = context.DbI2;
     ptrRegs[REG_INDEX(DB_I3)] = context.DbI3;
     ptrRegs[REG_INDEX(DB_I4)] = context.DbI4;
     ptrRegs[REG_INDEX(DB_I5)] = context.DbI5;
     ptrRegs[REG_INDEX(DB_I6)] = context.DbI6;
     ptrRegs[REG_INDEX(DB_I7)] = context.DbI7;

     ptrRegs[REG_INDEX(DB_D0)] = context.DbD0;
     ptrRegs[REG_INDEX(DB_D1)] = context.DbD1;
     ptrRegs[REG_INDEX(DB_D2)] = context.DbD2;
     ptrRegs[REG_INDEX(DB_D3)] = context.DbD3;
     ptrRegs[REG_INDEX(DB_D4)] = context.DbD4;
     ptrRegs[REG_INDEX(DB_D5)] = context.DbD5;
     ptrRegs[REG_INDEX(DB_D6)] = context.DbD6;
     ptrRegs[REG_INDEX(DB_D7)] = context.DbD7;

#elif _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;
}
Пример #13
0
static int
object_iter(void *cd, const prmap_t *pmp, const char *object_name) {
  Debugger* dbg = (Debugger*) cd;
  JNIEnv* env = dbg->env;
  jobject this_obj = dbg->obj;

  ps_prochandle* Pr = 0;
  Pr = (ps_prochandle*) env->GetLongField(this_obj, ps_prochandle_ptr_ID);

  char *s1 = 0, *s2 = 0;
  char libthread_db[PATH_MAX];

  if (strstr(object_name, "/libthread.so.") == NULL)
     return (0);

  /*
   * We found a libthread.
   * dlopen() the matching libthread_db and get the thread agent handle.
   */
  if (Pstatus(Pr)->pr_dmodel == PR_MODEL_NATIVE) {
     (void) strcpy(libthread_db, object_name);
     s1 = (char*) strstr(object_name, ".so.");
     s2 = (char*) strstr(libthread_db, ".so.");
     (void) strcpy(s2, "_db");
     s2 += 3;
     (void) strcpy(s2, s1);
  } else {
#ifdef _SYSCALL32
     /*
      * The victim process is 32-bit, we are 64-bit.
      * We have to find the 64-bit version of libthread_db
      * that matches the victim's 32-bit version of libthread.
      */
     (void) strcpy(libthread_db, object_name);
     s1 = (char*) strstr(object_name, "/libthread.so.");
     s2 = (char*) strstr(libthread_db, "/libthread.so.");
     (void) strcpy(s2, "/64");
     s2 += 3;
     (void) strcpy(s2, s1);
     s1 = (char*) strstr(s1, ".so.");
     s2 = (char*) strstr(s2, ".so.");
     (void) strcpy(s2, "_db");
     s2 += 3;
     (void) strcpy(s2, s1);
#else
     return (0);
#endif  /* _SYSCALL32 */
  }

  void* tdb_handle = 0;
  if ((tdb_handle = dlopen(libthread_db, RTLD_LAZY|RTLD_LOCAL)) == NULL) {
     char errMsg[PATH_MAX + 256];
     sprintf(errMsg, "Can't load %s!", libthread_db);
     THROW_NEW_DEBUGGER_EXCEPTION_(errMsg, 0);
  }
  env->SetLongField(this_obj, tdb_handle_ID, (jlong) tdb_handle);

  void* tmpPtr = 0;
  tmpPtr = dlsym(tdb_handle, "td_init");
  if (tmpPtr == 0)
     THROW_NEW_DEBUGGER_EXCEPTION_("dlsym failed on td_init!", 0);
  env->SetLongField(this_obj, p_td_init_ID, (jlong) tmpPtr);

  tmpPtr =dlsym(tdb_handle, "td_ta_new");
  if (tmpPtr == 0)
     THROW_NEW_DEBUGGER_EXCEPTION_("dlsym failed on td_ta_new!", 0);
  env->SetLongField(this_obj, p_td_ta_new_ID, (jlong) tmpPtr);

  tmpPtr = dlsym(tdb_handle, "td_ta_delete");
  if (tmpPtr == 0)
     THROW_NEW_DEBUGGER_EXCEPTION_("dlsym failed on td_ta_delete!", 0);
  env->SetLongField(this_obj, p_td_ta_delete_ID, (jlong) tmpPtr);

  tmpPtr = dlsym(tdb_handle, "td_ta_thr_iter");
  if (tmpPtr == 0)
     THROW_NEW_DEBUGGER_EXCEPTION_("dlsym failed on td_ta_thr_iter!", 0);
  env->SetLongField(this_obj, p_td_ta_thr_iter_ID, (jlong) tmpPtr);

  tmpPtr = dlsym(tdb_handle, "td_thr_get_info");
  if (tmpPtr == 0)
     THROW_NEW_DEBUGGER_EXCEPTION_("dlsym failed on td_thr_get_info!", 0);
  env->SetLongField(this_obj, p_td_thr_get_info_ID, (jlong) tmpPtr);

  tmpPtr = dlsym(tdb_handle, "td_thr_getgregs");
  if (tmpPtr == 0)
     THROW_NEW_DEBUGGER_EXCEPTION_("dlsym failed on td_thr_getgregs!", 0);
  env->SetLongField(this_obj, p_td_thr_getgregs_ID, (jlong) tmpPtr);

  return 1;
}