src/jdk.hotspot.agent/macosx/native/libsaproc/MacosxDebuggerLocal.m
changeset 50818 e46b9e514479
parent 47635 dfb375d231fb
child 52713 8586613959f0
equal deleted inserted replaced
50817:fa1e04811ff6 50818:e46b9e514479
     1 /*
     1 /*
     2  * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2002, 2018, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     7  * published by the Free Software Foundation.
    31 
    31 
    32 #import <mach/mach.h>
    32 #import <mach/mach.h>
    33 #import <mach/mach_types.h>
    33 #import <mach/mach_types.h>
    34 #import <sys/sysctl.h>
    34 #import <sys/sysctl.h>
    35 #import <stdio.h>
    35 #import <stdio.h>
       
    36 #import <string.h>
    36 #import <stdarg.h>
    37 #import <stdarg.h>
    37 #import <stdlib.h>
    38 #import <stdlib.h>
    38 #import <strings.h>
    39 #import <strings.h>
    39 #import <dlfcn.h>
    40 #import <dlfcn.h>
    40 #import <limits.h>
    41 #import <limits.h>
    67 static jmethodID getJavaThreadsInfo_ID = 0;
    68 static jmethodID getJavaThreadsInfo_ID = 0;
    68 
    69 
    69 // indicator if thread id (lwpid_t) was set
    70 // indicator if thread id (lwpid_t) was set
    70 static bool _threads_filled = false;
    71 static bool _threads_filled = false;
    71 
    72 
       
    73 // mach_exc_server defined in the generated mach_excServer.c
       
    74 extern boolean_t mach_exc_server(mach_msg_header_t *input_msg_hdr,
       
    75                                  mach_msg_header_t *output_msg_hdr);
       
    76 
       
    77 kern_return_t catch_mach_exception_raise(
       
    78   mach_port_t exception_port, mach_port_t thread,
       
    79   mach_port_t task, exception_type_t exception,
       
    80   mach_exception_data_t code,
       
    81   mach_msg_type_number_t code_cnt);
       
    82 
       
    83 kern_return_t catch_mach_exception_raise_state(
       
    84   mach_port_t exception_port, exception_type_t exception,
       
    85   const mach_exception_data_t code, mach_msg_type_number_t code_cnt,
       
    86   int *flavor, const thread_state_t old_state,
       
    87   mach_msg_type_number_t old_state_cnt, thread_state_t new_state,
       
    88   mach_msg_type_number_t *new_state_cnt);
       
    89 
       
    90 kern_return_t catch_mach_exception_raise_state_identity(
       
    91   mach_port_t exception_port, mach_port_t thread, mach_port_t task,
       
    92   exception_type_t exception, mach_exception_data_t code,
       
    93   mach_msg_type_number_t code_cnt, int *flavor, thread_state_t old_state,
       
    94   mach_msg_type_number_t old_state_cnt, thread_state_t new_state,
       
    95   mach_msg_type_number_t *new_state_cnt);
       
    96 
       
    97 static struct exception_saved_state {
       
    98   exception_mask_t       saved_masks[EXC_TYPES_COUNT];
       
    99   mach_port_t            saved_ports[EXC_TYPES_COUNT];
       
   100   exception_behavior_t   saved_behaviors[EXC_TYPES_COUNT];
       
   101   thread_state_flavor_t  saved_flavors[EXC_TYPES_COUNT];
       
   102   mach_msg_type_number_t saved_exception_types_count;
       
   103 } exception_saved_state;
       
   104 
       
   105 static mach_port_t tgt_exception_port;
       
   106 
       
   107 // Mirrors __Reply__mach_exception_raise_t generated in mach_excServer.c
       
   108 static struct rep_msg {
       
   109   mach_msg_header_t header;
       
   110   NDR_record_t ndr;
       
   111   kern_return_t ret_code;
       
   112 } rep_msg;
       
   113 
       
   114 // Mirrors __Request__mach_exception_raise_t generated in mach_excServer.c
       
   115 // with a large trailing pad to avoid MACH_MSG_RCV_TOO_LARGE
       
   116 static struct exc_msg {
       
   117   mach_msg_header_t header;
       
   118   // start of the kernel processed data
       
   119   mach_msg_body_t msgh_body;
       
   120   mach_msg_port_descriptor_t thread;
       
   121   mach_msg_port_descriptor_t task;
       
   122   // end of the kernel processed data
       
   123   NDR_record_t ndr;
       
   124   exception_type_t exception;
       
   125   mach_msg_type_number_t code_cnt;
       
   126   mach_exception_data_t code; // an array of int64_t
       
   127   char pad[512];
       
   128 } exc_msg;
       
   129 
    72 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) {
   130 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) {
    73   (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator);
   131   (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator);
    74 }
   132 }
    75 
   133 
    76 static id getSymbolicator(JNIEnv *env, jobject this_obj) {
   134 static id getSymbolicator(JNIEnv *env, jobject this_obj) {
    89 
   147 
    90 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
   148 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; }
    91 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
   149 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;}
    92 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
   150 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; }
    93 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
   151 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;}
    94 #define CHECK_EXCEPTION_CLEAR if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); } 
   152 #define CHECK_EXCEPTION_CLEAR if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); }
    95 #define CHECK_EXCEPTION_CLEAR_VOID if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return; } 
   153 #define CHECK_EXCEPTION_CLEAR_VOID if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return; }
    96 #define CHECK_EXCEPTION_CLEAR_(value) if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return value; } 
   154 #define CHECK_EXCEPTION_CLEAR_(value) if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return value; }
    97 
   155 
    98 static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
   156 static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) {
    99   jclass exceptionClass = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
   157   jclass exceptionClass = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException");
   100   CHECK_EXCEPTION;
   158   CHECK_EXCEPTION;
   101   (*env)->ThrowNew(env, exceptionClass, errMsg);
   159   (*env)->ThrowNew(env, exceptionClass, errMsg);
   127 /*
   185 /*
   128  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   186  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   129  * Method:    init0
   187  * Method:    init0
   130  * Signature: ()V
   188  * Signature: ()V
   131  */
   189  */
   132 JNIEXPORT void JNICALL 
   190 JNIEXPORT void JNICALL
   133 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) {
   191 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) {
   134   symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J");
   192   symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J");
   135   CHECK_EXCEPTION;
   193   CHECK_EXCEPTION;
   136   taskID = (*env)->GetFieldID(env, cls, "task", "J");
   194   taskID = (*env)->GetFieldID(env, cls, "task", "J");
   137   CHECK_EXCEPTION;
   195   CHECK_EXCEPTION;
   200 /*
   258 /*
   201  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   259  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   202  * Method:    lookupByName0
   260  * Method:    lookupByName0
   203  * Signature: (Ljava/lang/String;Ljava/lang/String;)J
   261  * Signature: (Ljava/lang/String;Ljava/lang/String;)J
   204  */
   262  */
   205 JNIEXPORT jlong JNICALL 
   263 JNIEXPORT jlong JNICALL
   206 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(
   264 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0(
   207   JNIEnv *env, jobject this_obj, 
   265   JNIEnv *env, jobject this_obj,
   208   jstring objectName, jstring symbolName) 
   266   jstring objectName, jstring symbolName)
   209 {
   267 {
   210   struct ps_prochandle* ph = get_proc_handle(env, this_obj);
   268   struct ps_prochandle* ph = get_proc_handle(env, this_obj);
   211   if (ph != NULL && ph->core != NULL) {
   269   if (ph != NULL && ph->core != NULL) {
   212     return lookupByNameIncore(env, ph, this_obj, objectName, symbolName);
   270     return lookupByNameIncore(env, ph, this_obj, objectName, symbolName);
   213   }
   271   }
   278  * Method:    readBytesFromProcess0
   336  * Method:    readBytesFromProcess0
   279  * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
   337  * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult;
   280  */
   338  */
   281 JNIEXPORT jbyteArray JNICALL
   339 JNIEXPORT jbyteArray JNICALL
   282 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(
   340 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0(
   283   JNIEnv *env, jobject this_obj, 
   341   JNIEnv *env, jobject this_obj,
   284   jlong addr, jlong numBytes) 
   342   jlong addr, jlong numBytes)
   285 {
   343 {
   286   print_debug("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes);
   344   print_debug("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes);
   287 
   345 
   288   // must allocate storage instead of using former parameter buf
   346   // must allocate storage instead of using former parameter buf
   289   jbyteArray array;
   347   jbyteArray array;
   318   mapped = calloc(pageCount, sizeof(int));
   376   mapped = calloc(pageCount, sizeof(int));
   319 
   377 
   320   task_t gTask = getTask(env, this_obj);
   378   task_t gTask = getTask(env, this_obj);
   321   // Try to read each of the pages.
   379   // Try to read each of the pages.
   322   for (i = 0; i < pageCount; i++) {
   380   for (i = 0; i < pageCount; i++) {
   323     result = vm_read(gTask, alignedAddress + i*vm_page_size, vm_page_size, 
   381     result = vm_read(gTask, alignedAddress + i*vm_page_size, vm_page_size,
   324 		     &pages[i], &byteCount);
   382 		     &pages[i], &byteCount);
   325     mapped[i] = (result == KERN_SUCCESS); 
   383     mapped[i] = (result == KERN_SUCCESS);
   326     // assume all failures are unmapped pages
   384     // assume all failures are unmapped pages
   327   }
   385   }
   328 
   386 
   329   print_debug("%ld pages\n", pageCount);
   387   print_debug("%ld pages\n", pageCount);
   330 	
   388 
   331   remaining = numBytes;
   389   remaining = numBytes;
   332 	
   390 
   333   for (i = 0; i < pageCount; i++) {
   391   for (i = 0; i < pageCount; i++) {
   334     unsigned long len = vm_page_size;
   392     unsigned long len = vm_page_size;
   335     unsigned long start = 0;
   393     unsigned long start = 0;
   336 
   394 
   337     if (i == 0) {
   395     if (i == 0) {
   364   * Note Macosx uses unique_thread_id which is different from other platforms though printed ids
   422   * Note Macosx uses unique_thread_id which is different from other platforms though printed ids
   365   * are still pthread id. Function BsdDebuggerLocal.getJavaThreadsInfo returns an array of long
   423   * are still pthread id. Function BsdDebuggerLocal.getJavaThreadsInfo returns an array of long
   366   * integers to host all java threads' id, stack_start, stack_end as:
   424   * integers to host all java threads' id, stack_start, stack_end as:
   367   * [uid0, stack_start0, stack_end0, uid1, stack_start1, stack_end1, ...]
   425   * [uid0, stack_start0, stack_end0, uid1, stack_start1, stack_end1, ...]
   368   *
   426   *
   369   * The work cannot be done at init0 since Threads is not available yet(VM not initialized yet). 
   427   * The work cannot be done at init0 since Threads is not available yet(VM not initialized yet).
   370   * This function should be called only once if succeeded
   428   * This function should be called only once if succeeded
   371   */ 
   429   */
   372 bool fill_java_threads(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
   430 bool fill_java_threads(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
   373   int n = 0, i = 0, j;
   431   int n = 0, i = 0, j;
   374   struct reg regs;
   432   struct reg regs;
   375   
   433 
   376   jlongArray thrinfos = (*env)->CallObjectMethod(env, this_obj, getJavaThreadsInfo_ID);
   434   jlongArray thrinfos = (*env)->CallObjectMethod(env, this_obj, getJavaThreadsInfo_ID);
   377   CHECK_EXCEPTION_(false);
   435   CHECK_EXCEPTION_(false);
   378   int len = (int)(*env)->GetArrayLength(env, thrinfos);
   436   int len = (int)(*env)->GetArrayLength(env, thrinfos);
   379   uint64_t* cinfos = (uint64_t *)(*env)->GetLongArrayElements(env, thrinfos, NULL);
   437   uint64_t* cinfos = (uint64_t *)(*env)->GetLongArrayElements(env, thrinfos, NULL);
   380   CHECK_EXCEPTION_(false); 
   438   CHECK_EXCEPTION_(false);
   381   n = get_num_threads(ph);
   439   n = get_num_threads(ph);
   382   print_debug("fill_java_threads called, num_of_thread = %d\n", n);
   440   print_debug("fill_java_threads called, num_of_thread = %d\n", n);
   383   for (i = 0; i < n; i++) {
   441   for (i = 0; i < n; i++) {
   384     if (!get_nth_lwp_regs(ph, i, &regs)) {
   442     if (!get_nth_lwp_regs(ph, i, &regs)) {
   385       print_debug("Could not get regs of thread %d, already set!\n", i);
   443       print_debug("Could not get regs of thread %d, already set!\n", i);
   386       return false;
   444       return false;
   387     }
   445     }
   388     for (j = 0; j < len; j += 3) {
   446     for (j = 0; j < len; j += 3) {
   389       lwpid_t  uid = cinfos[j];
   447       lwpid_t  uid = cinfos[j];
   390       uint64_t beg = cinfos[j + 1];
   448       uint64_t beg = cinfos[j + 1];
   391       uint64_t end = cinfos[j + 2]; 
   449       uint64_t end = cinfos[j + 2];
   392       if ((regs.r_rsp < end && regs.r_rsp >= beg) ||
   450       if ((regs.r_rsp < end && regs.r_rsp >= beg) ||
   393           (regs.r_rbp < end && regs.r_rbp >= beg)) {
   451           (regs.r_rbp < end && regs.r_rbp >= beg)) {
   394         set_lwp_id(ph, i, uid);
   452         set_lwp_id(ph, i, uid);
   395         break;
   453         break;
   396       }
   454       }
   476  * in the VM, but that thread port is not valid for a remote debugger to access the thread.
   534  * in the VM, but that thread port is not valid for a remote debugger to access the thread.
   477  */
   535  */
   478 thread_t
   536 thread_t
   479 lookupThreadFromThreadId(task_t task, jlong thread_id) {
   537 lookupThreadFromThreadId(task_t task, jlong thread_id) {
   480   print_debug("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id);
   538   print_debug("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id);
   481   
   539 
   482   thread_array_t thread_list = NULL;
   540   thread_array_t thread_list = NULL;
   483   mach_msg_type_number_t thread_list_count = 0;
   541   mach_msg_type_number_t thread_list_count = 0;
   484   thread_t result_thread = 0;
   542   thread_t result_thread = 0;
   485   int i;
   543   int i;
   486   
   544 
   487   // get the list of all the send rights
   545   // get the list of all the send rights
   488   kern_return_t result = task_threads(task, &thread_list, &thread_list_count);
   546   kern_return_t result = task_threads(task, &thread_list, &thread_list_count);
   489   if (result != KERN_SUCCESS) {
   547   if (result != KERN_SUCCESS) {
   490     print_debug("task_threads returned 0x%x\n", result);
   548     print_debug("task_threads returned 0x%x\n", result);
   491     return 0;
   549     return 0;
   492   }
   550   }
   493   
   551 
   494   for(i = 0 ; i < thread_list_count; i++) {
   552   for(i = 0 ; i < thread_list_count; i++) {
   495     thread_identifier_info_data_t m_ident_info;
   553     thread_identifier_info_data_t m_ident_info;
   496     mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
   554     mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT;
   497 
   555 
   498     // get the THREAD_IDENTIFIER_INFO for the send right
   556     // get the THREAD_IDENTIFIER_INFO for the send right
   499     result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
   557     result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count);
   500     if (result != KERN_SUCCESS) {
   558     if (result != KERN_SUCCESS) {
   501       print_debug("thread_info returned 0x%x\n", result);
   559       print_debug("thread_info returned 0x%x\n", result);
   502       break;
   560       break;
   503     }
   561     }
   504     
   562 
   505     // if this is the one we're looking for, return the send right
   563     // if this is the one we're looking for, return the send right
   506     if (thread_id == m_ident_info.thread_id)
   564     if (thread_id == m_ident_info.thread_id)
   507     {
   565     {
   508       result_thread = thread_list[i];
   566       result_thread = thread_list[i];
   509       break;
   567       break;
   510     }
   568     }
   511   }
   569   }
   512   
   570 
   513   vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t));
   571   vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t));
   514   vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count);
   572   vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count);
   515   
   573 
   516   return result_thread;
   574   return result_thread;
   517 }
   575 }
   518 
   576 
   519 
   577 
   520 /*
   578 /*
   521  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   579  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   522  * Method:    getThreadIntegerRegisterSet0
   580  * Method:    getThreadIntegerRegisterSet0
   523  * Signature: (J)[J
   581  * Signature: (J)[J
   524  */
   582  */
   525 JNIEXPORT jlongArray JNICALL 
   583 JNIEXPORT jlongArray JNICALL
   526 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(
   584 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0(
   527   JNIEnv *env, jobject this_obj, 
   585   JNIEnv *env, jobject this_obj,
   528   jlong thread_id) 
   586   jlong thread_id)
   529 {
   587 {
   530   print_debug("getThreadRegisterSet0 called\n");
   588   print_debug("getThreadRegisterSet0 called\n");
   531 
   589 
   532   struct ps_prochandle* ph = get_proc_handle(env, this_obj);
   590   struct ps_prochandle* ph = get_proc_handle(env, this_obj);
   533   if (ph != NULL && ph->core != NULL) {
   591   if (ph != NULL && ph->core != NULL) {
   576   primitiveArray[REG_INDEX(RBX)] = state.__rbx;
   634   primitiveArray[REG_INDEX(RBX)] = state.__rbx;
   577   primitiveArray[REG_INDEX(RDX)] = state.__rdx;
   635   primitiveArray[REG_INDEX(RDX)] = state.__rdx;
   578   primitiveArray[REG_INDEX(RCX)] = state.__rcx;
   636   primitiveArray[REG_INDEX(RCX)] = state.__rcx;
   579   primitiveArray[REG_INDEX(RAX)] = state.__rax;
   637   primitiveArray[REG_INDEX(RAX)] = state.__rax;
   580   primitiveArray[REG_INDEX(TRAPNO)] = 0;            // trapno, not used
   638   primitiveArray[REG_INDEX(TRAPNO)] = 0;            // trapno, not used
   581   primitiveArray[REG_INDEX(ERR)]    = 0;            // err, not used 
   639   primitiveArray[REG_INDEX(ERR)]    = 0;            // err, not used
   582   primitiveArray[REG_INDEX(RIP)] = state.__rip;
   640   primitiveArray[REG_INDEX(RIP)] = state.__rip;
   583   primitiveArray[REG_INDEX(CS)]  = state.__cs;
   641   primitiveArray[REG_INDEX(CS)]  = state.__cs;
   584   primitiveArray[REG_INDEX(RFL)] = state.__rflags;
   642   primitiveArray[REG_INDEX(RFL)] = state.__rflags;
   585   primitiveArray[REG_INDEX(RSP)] = state.__rsp;
   643   primitiveArray[REG_INDEX(RSP)] = state.__rsp;
   586   primitiveArray[REG_INDEX(SS)] = 0;                // We don't have SS
   644   primitiveArray[REG_INDEX(SS)] = 0;                // We don't have SS
   628   print_debug("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid);
   686   print_debug("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid);
   629     
   687     
   630   return (jint) usable_tid;
   688   return (jint) usable_tid;
   631 }
   689 }
   632 
   690 
   633 
       
   634 static bool ptrace_continue(pid_t pid, int signal) {
       
   635   // pass the signal to the process so we don't swallow it
       
   636   int res;
       
   637   if ((res = ptrace(PT_CONTINUE, pid, (caddr_t)1, signal)) < 0) {
       
   638     print_error("attach: ptrace(PT_CONTINUE, %d) failed with %d\n", pid, res);
       
   639     return false;
       
   640   }
       
   641   return true;
       
   642 }
       
   643 
       
   644 // waits until the ATTACH has stopped the process
       
   645 // by signal SIGSTOP
       
   646 static bool ptrace_waitpid(pid_t pid) {
       
   647   int ret;
       
   648   int status;
       
   649   while (true) {
       
   650     // Wait for debuggee to stop.
       
   651     ret = waitpid(pid, &status, 0);
       
   652     if (ret >= 0) {
       
   653       if (WIFSTOPPED(status)) {
       
   654         // Any signal will stop the thread, make sure it is SIGSTOP. Otherwise SIGSTOP
       
   655         // will still be pending and delivered when the process is DETACHED and the process
       
   656         // will go to sleep.
       
   657         if (WSTOPSIG(status) == SIGSTOP) {
       
   658           // Debuggee stopped by SIGSTOP.
       
   659           return true;
       
   660         }
       
   661         if (!ptrace_continue(pid, WSTOPSIG(status))) {
       
   662           print_error("attach: Failed to correctly attach to VM. VM might HANG! [PTRACE_CONT failed, stopped by %d]\n", WSTOPSIG(status));
       
   663           return false;
       
   664         }
       
   665       } else {
       
   666         print_error("attach: waitpid(): Child process exited/terminated (status = 0x%x)\n", status);
       
   667         return false;
       
   668       }
       
   669     } else {
       
   670       switch (errno) {
       
   671         case EINTR:
       
   672           continue;
       
   673           break;
       
   674         case ECHILD:
       
   675           print_error("attach: waitpid() failed. Child process pid (%d) does not exist \n", pid);
       
   676           break;
       
   677         case EINVAL:
       
   678           print_error("attach: waitpid() failed. Invalid options argument.\n");
       
   679           break;
       
   680         default:
       
   681           print_error("attach: waitpid() failed. Unexpected error %d\n",errno);
       
   682           break;
       
   683       }
       
   684       return false;
       
   685     }
       
   686   }
       
   687 }
       
   688 
       
   689 // attach to a process/thread specified by "pid"
   691 // attach to a process/thread specified by "pid"
   690 static bool ptrace_attach(pid_t pid) {
   692 static bool ptrace_attach(pid_t pid) {
   691   int res;
   693   errno = 0;
   692 #ifdef __clang__
   694   ptrace(PT_ATTACHEXC, pid, 0, 0);
   693 #pragma clang diagnostic push
   695 
   694 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
   696   if (errno != 0) {
   695 #endif
   697     print_error("ptrace_attach: ptrace(PT_ATTACHEXC,...) failed: %s", strerror(errno));
   696   if ((res = ptrace(PT_ATTACH, pid, 0, 0)) < 0) {
       
   697     print_error("ptrace(PT_ATTACH, %d) failed with %d\n", pid, res);
       
   698 #ifdef __clang__
       
   699 #pragma clang diagnostic pop
       
   700 #endif
       
   701     return false;
   698     return false;
   702   } else {
   699   }
   703     return ptrace_waitpid(pid);
   700   return true;
   704   }
   701 }
       
   702 
       
   703 kern_return_t catch_mach_exception_raise(
       
   704   mach_port_t exception_port, mach_port_t thread_port, mach_port_t task_port,
       
   705   exception_type_t exception_type, mach_exception_data_t codes,
       
   706   mach_msg_type_number_t num_codes) {
       
   707 
       
   708   print_debug("catch_mach_exception_raise: Exception port = %d thread_port = %d "
       
   709               "task port %d exc type = %d num_codes %d\n",
       
   710               exception_port, thread_port, task_port, exception_type, num_codes);
       
   711 
       
   712   // This message should denote a Unix soft signal, with
       
   713   // 1. the exception type = EXC_SOFTWARE
       
   714   // 2. codes[0] (which is the code) = EXC_SOFT_SIGNAL
       
   715   // 3. codes[1] (which is the sub-code) = SIGSTOP
       
   716   if (!(exception_type == EXC_SOFTWARE &&
       
   717         codes[0] == EXC_SOFT_SIGNAL    &&
       
   718         codes[num_codes -1] == SIGSTOP)) {
       
   719     print_error("catch_mach_exception_raise: Message doesn't denote a Unix "
       
   720                 "soft signal. exception_type = %d, codes[0] = %d, "
       
   721                 "codes[num_codes -1] = %d, num_codes = %d\n",
       
   722                 exception_type, codes[0], codes[num_codes - 1], num_codes);
       
   723     return MACH_RCV_INVALID_TYPE;
       
   724   }
       
   725   return KERN_SUCCESS;
       
   726 }
       
   727 
       
   728 kern_return_t catch_mach_exception_raise_state(
       
   729   mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code,
       
   730   mach_msg_type_number_t code_cnt, int *flavor, const thread_state_t old_state,
       
   731   mach_msg_type_number_t old_state_cnt, thread_state_t new_state,
       
   732   mach_msg_type_number_t *new_state_cnt) {
       
   733   return MACH_RCV_INVALID_TYPE;
       
   734 }
       
   735 
       
   736 
       
   737 kern_return_t catch_mach_exception_raise_state_identity(
       
   738   mach_port_t exception_port, mach_port_t thread, mach_port_t task,
       
   739   exception_type_t exception, mach_exception_data_t code,
       
   740   mach_msg_type_number_t code_cnt, int *flavor,
       
   741   thread_state_t old_state, mach_msg_type_number_t old_state_cnt,
       
   742   thread_state_t new_state, mach_msg_type_number_t *new_state_cnt) {
       
   743   return MACH_RCV_INVALID_TYPE;
       
   744 }
       
   745 
       
   746 // wait to receive an exception message
       
   747 static bool wait_for_exception() {
       
   748   kern_return_t result;
       
   749 
       
   750   result = mach_msg(&exc_msg.header,
       
   751                     MACH_RCV_MSG,
       
   752                     0,
       
   753                     sizeof(exc_msg),
       
   754                     tgt_exception_port,
       
   755                     MACH_MSG_TIMEOUT_NONE,
       
   756                     MACH_PORT_NULL);
       
   757 
       
   758   if (result != MACH_MSG_SUCCESS) {
       
   759     print_error("attach: wait_for_exception: mach_msg() failed: '%s' (%d)\n",
       
   760                 mach_error_string(result), result);
       
   761     return false;
       
   762   }
       
   763 
       
   764   if (mach_exc_server(&exc_msg.header, &rep_msg.header) == false ||
       
   765       rep_msg.ret_code != KERN_SUCCESS) {
       
   766     print_error("attach: wait_for_exception: mach_exc_server failure\n");
       
   767     if (rep_msg.ret_code != KERN_SUCCESS) {
       
   768       print_error("catch_mach_exception_raise() failed '%s' (%d)\n",
       
   769                   mach_error_string(rep_msg.ret_code), rep_msg.ret_code);
       
   770     }
       
   771     return false;
       
   772   }
       
   773 
       
   774   print_debug("reply msg from mach_exc_server: (msg->{bits = %#x, size = %u, "
       
   775               "remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x},)",
       
   776               rep_msg.header.msgh_bits, rep_msg.header.msgh_size,
       
   777               rep_msg.header.msgh_remote_port, rep_msg.header.msgh_local_port,
       
   778               rep_msg.header.msgh_reserved, rep_msg.header.msgh_id);
       
   779 
       
   780   return true;
   705 }
   781 }
   706 
   782 
   707 /*
   783 /*
   708  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   784  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   709  * Method:    attach0
   785  * Method:    attach0
   717 
   793 
   718 JNF_COCOA_ENTER(env);
   794 JNF_COCOA_ENTER(env);
   719 
   795 
   720   kern_return_t result;
   796   kern_return_t result;
   721   task_t gTask = 0;
   797   task_t gTask = 0;
       
   798 
   722   result = task_for_pid(mach_task_self(), jpid, &gTask);
   799   result = task_for_pid(mach_task_self(), jpid, &gTask);
   723   if (result != KERN_SUCCESS) {
   800   if (result != KERN_SUCCESS) {
   724     print_error("attach: task_for_pid(%d) failed: '%s' (%d)\n", (int)jpid, mach_error_string(result), result);
   801     print_error("attach: task_for_pid(%d) failed: '%s' (%d)\n", (int)jpid, mach_error_string(result), result);
   725     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process. Could be caused by an incorrect pid or lack of privileges.");
   802     THROW_NEW_DEBUGGER_EXCEPTION(
       
   803       "Can't attach to the process. Could be caused by an incorrect pid or lack of privileges.");
   726   }
   804   }
   727   putTask(env, this_obj, gTask);
   805   putTask(env, this_obj, gTask);
       
   806 
       
   807   // Allocate an exception port.
       
   808   result = mach_port_allocate(mach_task_self(),
       
   809                               MACH_PORT_RIGHT_RECEIVE,
       
   810                               &tgt_exception_port);
       
   811   if (result != KERN_SUCCESS) {
       
   812     print_error("attach: mach_port_allocate() for tgt_exception_port failed: '%s' (%d)\n",
       
   813                 mach_error_string(result), result);
       
   814     THROW_NEW_DEBUGGER_EXCEPTION(
       
   815       "Can't attach to the process. Couldn't allocate an exception port.");
       
   816   }
       
   817 
       
   818   // Enable the new exception port to send messages.
       
   819   result = mach_port_insert_right (mach_task_self(),
       
   820                                    tgt_exception_port,
       
   821                                    tgt_exception_port,
       
   822                                    MACH_MSG_TYPE_MAKE_SEND);
       
   823   if (result != KERN_SUCCESS) {
       
   824     print_error("attach: mach_port_insert_right() failed for port 0x%x: '%s' (%d)\n",
       
   825                 tgt_exception_port, mach_error_string(result), result);
       
   826     THROW_NEW_DEBUGGER_EXCEPTION(
       
   827       "Can't attach to the process. Couldn't add send privileges to the exception port.");
       
   828   }
       
   829 
       
   830   // Save the existing original exception ports registered with the target
       
   831   // process (for later restoration while detaching from the process).
       
   832   result = task_get_exception_ports(gTask,
       
   833                                     EXC_MASK_ALL,
       
   834                                     exception_saved_state.saved_masks,
       
   835                                     &exception_saved_state.saved_exception_types_count,
       
   836                                     exception_saved_state.saved_ports,
       
   837                                     exception_saved_state.saved_behaviors,
       
   838                                     exception_saved_state.saved_flavors);
       
   839 
       
   840   if (result != KERN_SUCCESS) {
       
   841     print_error("attach: task_get_exception_ports() failed: '%s' (%d)\n",
       
   842                 mach_error_string(result), result);
       
   843     THROW_NEW_DEBUGGER_EXCEPTION(
       
   844       "Can't attach to the process. Could not get the target exception ports.");
       
   845   }
       
   846 
       
   847   // register the exception port to be used for all future exceptions with the
       
   848   // target process.
       
   849   result = task_set_exception_ports(gTask,
       
   850                                     EXC_MASK_ALL,
       
   851                                     tgt_exception_port,
       
   852                                     EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES,
       
   853                                     THREAD_STATE_NONE);
       
   854 
       
   855   if (result != KERN_SUCCESS) {
       
   856     print_error("attach: task_set_exception_ports() failed -- port 0x%x: '%s' (%d)\n",
       
   857                 tgt_exception_port, mach_error_string(result), result);
       
   858     mach_port_deallocate(mach_task_self(), gTask);
       
   859     mach_port_deallocate(mach_task_self(), tgt_exception_port);
       
   860     THROW_NEW_DEBUGGER_EXCEPTION(
       
   861       "Can't attach to the process. Could not register the exception port "
       
   862       "with the target process.");
       
   863   }
   728 
   864 
   729   // use ptrace to stop the process
   865   // use ptrace to stop the process
   730   // on os x, ptrace only needs to be called on the process, not the individual threads
   866   // on os x, ptrace only needs to be called on the process, not the individual threads
   731   if (ptrace_attach(jpid) != true) {
   867   if (ptrace_attach(jpid) != true) {
       
   868     print_error("attach: ptrace failure in attaching to %d\n", (int)jpid);
   732     mach_port_deallocate(mach_task_self(), gTask);
   869     mach_port_deallocate(mach_task_self(), gTask);
   733     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
   870     mach_port_deallocate(mach_task_self(), tgt_exception_port);
       
   871     THROW_NEW_DEBUGGER_EXCEPTION("Can't ptrace attach to the process");
       
   872   }
       
   873 
       
   874   if (wait_for_exception() != true) {
       
   875     mach_port_deallocate(mach_task_self(), gTask);
       
   876     mach_port_deallocate(mach_task_self(), tgt_exception_port);
       
   877     THROW_NEW_DEBUGGER_EXCEPTION(
       
   878       "Can't attach to the process. Issues with reception of the exception message.");
       
   879   }
       
   880 
       
   881   // suspend all the threads in the task
       
   882   result = task_suspend(gTask);
       
   883   if (result != KERN_SUCCESS) {
       
   884     print_error("attach: task_suspend() failed: '%s' (%d)\n",
       
   885                 mach_error_string(result), result);
       
   886     mach_port_deallocate(mach_task_self(), gTask);
       
   887     mach_port_deallocate(mach_task_self(), tgt_exception_port);
       
   888     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach. Unable to suspend all the threads in the task.");
   734   }
   889   }
   735 
   890 
   736   id symbolicator = nil;
   891   id symbolicator = nil;
   737   id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
   892   id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
   738   if (jrsSymbolicator != nil) {
   893   if (jrsSymbolicator != nil) {
   743     CFRetain(symbolicator); // pin symbolicator while in java heap
   898     CFRetain(symbolicator); // pin symbolicator while in java heap
   744   }
   899   }
   745 
   900 
   746   putSymbolicator(env, this_obj, symbolicator);
   901   putSymbolicator(env, this_obj, symbolicator);
   747   if (symbolicator == nil) {
   902   if (symbolicator == nil) {
       
   903     mach_port_deallocate(mach_task_self(), gTask);
       
   904     mach_port_deallocate(mach_task_self(), tgt_exception_port);
   748     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process");
   905     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process");
   749   }
   906   }
   750 
   907 
   751 JNF_COCOA_EXIT(env);
   908 JNF_COCOA_EXIT(env);
   752 }
   909 }
   753 
   910 
   754 /** For core file, 
   911 /** For core file,
   755     called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 */
   912     called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 */
   756 static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
   913 static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) {
   757   int n = 0, i = 0;
   914   int n = 0, i = 0;
   758 
   915 
   759   // add load objects
   916   // add load objects
   809   (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
   966   (*env)->ReleaseStringUTFChars(env, execName, execName_cstr);
   810   (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
   967   (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr);
   811   fillLoadObjects(env, this_obj, ph);
   968   fillLoadObjects(env, this_obj, ph);
   812 }
   969 }
   813 
   970 
       
   971 static void detach_cleanup(task_t gTask, JNIEnv *env, jobject this_obj, bool throw_exception) {
       
   972   mach_port_deallocate(mach_task_self(), tgt_exception_port);
       
   973   mach_port_deallocate(mach_task_self(), gTask);
       
   974 
       
   975   id symbolicator = getSymbolicator(env, this_obj);
       
   976   if (symbolicator != nil) {
       
   977     CFRelease(symbolicator);
       
   978   }
       
   979   if (throw_exception) {
       
   980     THROW_NEW_DEBUGGER_EXCEPTION("Cannot detach.");
       
   981   }
       
   982 }
       
   983 
   814 /*
   984 /*
   815  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   985  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
   816  * Method:    detach0
   986  * Method:    detach0
   817  * Signature: ()V
   987  * Signature: ()V
   818  */
   988  */
   825   if (ph != NULL && ph->core != NULL) {
   995   if (ph != NULL && ph->core != NULL) {
   826      Prelease(ph);
   996      Prelease(ph);
   827      return;
   997      return;
   828   }
   998   }
   829 JNF_COCOA_ENTER(env);
   999 JNF_COCOA_ENTER(env);
       
  1000 
   830   task_t gTask = getTask(env, this_obj);
  1001   task_t gTask = getTask(env, this_obj);
       
  1002   kern_return_t k_res = 0;
       
  1003 
       
  1004   // Restore the pre-saved original exception ports registered with the target process
       
  1005   for (uint32_t i = 0; i < exception_saved_state.saved_exception_types_count; ++i) {
       
  1006     k_res = task_set_exception_ports(gTask,
       
  1007                                      exception_saved_state.saved_masks[i],
       
  1008                                      exception_saved_state.saved_ports[i],
       
  1009                                      exception_saved_state.saved_behaviors[i],
       
  1010                                      exception_saved_state.saved_flavors[i]);
       
  1011     if (k_res != KERN_SUCCESS) {
       
  1012       print_error("detach: task_set_exception_ports failed with %d while "
       
  1013                   "restoring the target exception ports.\n", k_res);
       
  1014       detach_cleanup(gTask, env, this_obj, true);
       
  1015     }
       
  1016   }
   831 
  1017 
   832   // detach from the ptraced process causing it to resume execution
  1018   // detach from the ptraced process causing it to resume execution
   833   int pid;
  1019   int pid;
   834   kern_return_t k_res;
       
   835   k_res = pid_for_task(gTask, &pid);
  1020   k_res = pid_for_task(gTask, &pid);
   836   if (k_res != KERN_SUCCESS) {
  1021   if (k_res != KERN_SUCCESS) {
   837     print_error("detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
  1022     print_error("detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
       
  1023     detach_cleanup(gTask, env, this_obj, true);
   838   }
  1024   }
   839   else {
  1025   else {
   840     int res = ptrace(PT_DETACH, pid, 0, 0);
  1026     errno = 0;
   841     if (res < 0) {
  1027     ptrace(PT_DETACH, pid, (caddr_t)1, 0);
   842       print_error("detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res);
  1028     if (errno != 0) {
       
  1029       print_error("detach: ptrace(PT_DETACH,...) failed: %s", strerror(errno));
       
  1030       detach_cleanup(gTask, env, this_obj, true);
   843     }
  1031     }
   844   }
  1032   }
   845 
  1033 
   846   mach_port_deallocate(mach_task_self(), gTask);
  1034   // reply to the previous exception message
   847   id symbolicator = getSymbolicator(env, this_obj);
  1035   k_res = mach_msg(&rep_msg.header,
   848   if (symbolicator != nil) {
  1036                    MACH_SEND_MSG| MACH_SEND_INTERRUPT,
   849     CFRelease(symbolicator);
  1037                    rep_msg.header.msgh_size,
   850   }
  1038                    0,
       
  1039                    MACH_PORT_NULL,
       
  1040                    MACH_MSG_TIMEOUT_NONE,
       
  1041                    MACH_PORT_NULL);
       
  1042   if (k_res != MACH_MSG_SUCCESS) {
       
  1043     print_error("detach: mach_msg() for replying to pending exceptions failed: '%s' (%d)\n",
       
  1044                  mach_error_string(k_res), k_res);
       
  1045     detach_cleanup(gTask, env, this_obj, true);
       
  1046   }
       
  1047 
       
  1048   detach_cleanup(gTask, env, this_obj, false);
       
  1049 
   851 JNF_COCOA_EXIT(env);
  1050 JNF_COCOA_EXIT(env);
   852 }
  1051 }