agent/src/os/bsd/MacosxDebuggerLocal.m

Print this page
rev 4134 : 8008102: SA on OS X does not stop the attached process
Reviewed-by:


  21  * questions.
  22  *
  23  */
  24 
  25 #include <objc/objc-runtime.h>
  26 #import <Foundation/Foundation.h>
  27 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  28 
  29 #include <JavaVM/jni.h>
  30 
  31 #import <mach/mach.h>
  32 #import <mach/mach_types.h>
  33 #import <sys/sysctl.h>
  34 #import <stdio.h>
  35 #import <stdarg.h>
  36 #import <stdlib.h>
  37 #import <strings.h>
  38 #import <dlfcn.h>
  39 #import <limits.h>
  40 #import <errno.h>


  41 
  42 jboolean debug = JNI_FALSE;
  43 
  44 static jfieldID symbolicatorID = 0; // set in _init0
  45 static jfieldID taskID = 0; // set in _init0
  46 
  47 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) {
  48   (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator);
  49 }
  50 
  51 static id getSymbolicator(JNIEnv *env, jobject this_obj) {
  52   jlong ptr = (*env)->GetLongField(env, this_obj, symbolicatorID);
  53   return (id)(intptr_t)ptr;
  54 }
  55 
  56 static void putTask(JNIEnv *env, jobject this_obj, task_t task) {
  57   (*env)->SetLongField(env, this_obj, taskID, (jlong)task);
  58 }
  59 
  60 static task_t getTask(JNIEnv *env, jobject this_obj) {


 429     
 430   return (jint) usable_tid;
 431 }
 432 
 433 /*
 434  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
 435  * Method:    attach0
 436  * Signature: (I)V
 437  */
 438 JNIEXPORT void JNICALL 
 439 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(
 440   JNIEnv *env, jobject this_obj, jint jpid) 
 441 {
 442 JNF_COCOA_ENTER(env);
 443   if (getenv("JAVA_SAPROC_DEBUG") != NULL)
 444     debug = JNI_TRUE;
 445   else
 446     debug = JNI_FALSE;
 447   if (debug) printf("attach0 called for jpid=%d\n", (int)jpid);
 448 

 449   kern_return_t result;
 450   task_t gTask = 0;
 451   result = task_for_pid(mach_task_self(), jpid, &gTask);
 452   if (result != KERN_SUCCESS) {
 453     fprintf(stderr, "attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result);
 454     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
 455   }
 456   putTask(env, this_obj, gTask);
 457 




















 458   id symbolicator = nil;
 459   id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
 460   if (jrsSymbolicator != nil) {
 461     id (*dynamicCall)(id, SEL, pid_t) = (id (*)(id, SEL, pid_t))&objc_msgSend;
 462     symbolicator = dynamicCall(jrsSymbolicator, @selector(symbolicatorForPid:), (pid_t)jpid);
 463   }
 464   if (symbolicator != nil) {
 465     CFRetain(symbolicator); // pin symbolicator while in java heap
 466   }
 467 
 468   putSymbolicator(env, this_obj, symbolicator);
 469   if (symbolicator == nil) {
 470     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process");
 471   }
 472 
 473 JNF_COCOA_EXIT(env);
 474 }
 475 
 476 /*
 477  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
 478  * Method:    detach0
 479  * Signature: ()V
 480  */
 481 JNIEXPORT void JNICALL 
 482 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(
 483   JNIEnv *env, jobject this_obj) 
 484 {
 485 JNF_COCOA_ENTER(env);
 486   if (debug) printf("detach0 called\n");
 487 
 488   task_t gTask = getTask(env, this_obj);















 489   mach_port_deallocate(mach_task_self(), gTask);
 490   id symbolicator = getSymbolicator(env, this_obj);
 491   if (symbolicator != nil) {
 492     CFRelease(symbolicator);
 493   }
 494 JNF_COCOA_EXIT(env);
 495 }
 496 
 497 /*
 498  * Class:     sun_jvm_hotspot_asm_Disassembler
 499  * Method:    load_library
 500  * Signature: (Ljava/lang/String;)L
 501  */
 502 JNIEXPORT jlong JNICALL
 503 Java_sun_jvm_hotspot_asm_Disassembler_load_1library(
 504   JNIEnv * env, 
 505   jclass disclass,
 506   jstring jrepath_s,
 507   jstring libname_s) 
 508 {




  21  * questions.
  22  *
  23  */
  24 
  25 #include <objc/objc-runtime.h>
  26 #import <Foundation/Foundation.h>
  27 #import <JavaNativeFoundation/JavaNativeFoundation.h>
  28 
  29 #include <JavaVM/jni.h>
  30 
  31 #import <mach/mach.h>
  32 #import <mach/mach_types.h>
  33 #import <sys/sysctl.h>
  34 #import <stdio.h>
  35 #import <stdarg.h>
  36 #import <stdlib.h>
  37 #import <strings.h>
  38 #import <dlfcn.h>
  39 #import <limits.h>
  40 #import <errno.h>
  41 #import <sys/types.h>
  42 #import <sys/ptrace.h>
  43 
  44 jboolean debug = JNI_FALSE;
  45 
  46 static jfieldID symbolicatorID = 0; // set in _init0
  47 static jfieldID taskID = 0; // set in _init0
  48 
  49 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) {
  50   (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator);
  51 }
  52 
  53 static id getSymbolicator(JNIEnv *env, jobject this_obj) {
  54   jlong ptr = (*env)->GetLongField(env, this_obj, symbolicatorID);
  55   return (id)(intptr_t)ptr;
  56 }
  57 
  58 static void putTask(JNIEnv *env, jobject this_obj, task_t task) {
  59   (*env)->SetLongField(env, this_obj, taskID, (jlong)task);
  60 }
  61 
  62 static task_t getTask(JNIEnv *env, jobject this_obj) {


 431     
 432   return (jint) usable_tid;
 433 }
 434 
 435 /*
 436  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
 437  * Method:    attach0
 438  * Signature: (I)V
 439  */
 440 JNIEXPORT void JNICALL 
 441 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I(
 442   JNIEnv *env, jobject this_obj, jint jpid) 
 443 {
 444 JNF_COCOA_ENTER(env);
 445   if (getenv("JAVA_SAPROC_DEBUG") != NULL)
 446     debug = JNI_TRUE;
 447   else
 448     debug = JNI_FALSE;
 449   if (debug) printf("attach0 called for jpid=%d\n", (int)jpid);
 450   
 451   // get the task from the pid
 452   kern_return_t result;
 453   task_t gTask = 0;
 454   result = task_for_pid(mach_task_self(), jpid, &gTask);
 455   if (result != KERN_SUCCESS) {
 456     fprintf(stderr, "attach: task_for_pid(%d) failed (%d)\n", (int)jpid, result);
 457     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
 458   }
 459   putTask(env, this_obj, gTask);
 460 
 461   // use ptrace to stop the process
 462   // on os x, ptrace only needs to be called on the process, not the individual threads
 463   int res, status;  
 464   res = ptrace(PT_ATTACH, jpid, 0, 0);
 465   if (res < 0) {
 466     fprintf(stderr, "attach: ptrace(PT_ATTACH, %d) failed (%d)\n", (int)jpid, res);
 467     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
 468   }
 469   
 470   res = waitpid(jpid, &status, 0);
 471   if (res < 0) {
 472     fprintf(stderr, "attach: waitpid(%d) failed (%d, %d)\n", (int)jpid, res, errno);
 473     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
 474   }
 475   
 476   if (! WIFSTOPPED(status)) {
 477     fprintf(stderr, "attach: stopping the process failed %d\n", status);
 478     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the process");
 479   }  
 480 
 481   id symbolicator = nil;
 482   id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator");
 483   if (jrsSymbolicator != nil) {
 484     id (*dynamicCall)(id, SEL, pid_t) = (id (*)(id, SEL, pid_t))&objc_msgSend;
 485     symbolicator = dynamicCall(jrsSymbolicator, @selector(symbolicatorForPid:), (pid_t)jpid);
 486   }
 487   if (symbolicator != nil) {
 488     CFRetain(symbolicator); // pin symbolicator while in java heap
 489   }
 490 
 491   putSymbolicator(env, this_obj, symbolicator);
 492   if (symbolicator == nil) {
 493     THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process");
 494   }
 495 
 496 JNF_COCOA_EXIT(env);
 497 }
 498 
 499 /*
 500  * Class:     sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal
 501  * Method:    detach0
 502  * Signature: ()V
 503  */
 504 JNIEXPORT void JNICALL 
 505 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0(
 506   JNIEnv *env, jobject this_obj) 
 507 {
 508 JNF_COCOA_ENTER(env);
 509   if (debug) printf("detach0 called\n");
 510 
 511   task_t gTask = getTask(env, this_obj);
 512 
 513   // detach from the ptraced process causing it to resume execution
 514   int pid;
 515   kern_return_t k_res;
 516   k_res = pid_for_task(gTask, &pid);
 517   if (k_res != KERN_SUCCESS) {
 518     fprintf(stderr, "detach: pid_for_task(%d) failed (%d)\n", pid, k_res);
 519   }
 520   else {
 521     int res = ptrace(PT_DETACH, pid, 0, 0);
 522     if (res < 0) {
 523       fprintf(stderr, "detach: ptrace(PT_DETACH, %d) failed (%d)\n", pid, res);
 524     }
 525   }
 526   
 527   mach_port_deallocate(mach_task_self(), gTask);
 528   id symbolicator = getSymbolicator(env, this_obj);
 529   if (symbolicator != nil) {
 530     CFRelease(symbolicator);
 531   }
 532 JNF_COCOA_EXIT(env);
 533 }
 534 
 535 /*
 536  * Class:     sun_jvm_hotspot_asm_Disassembler
 537  * Method:    load_library
 538  * Signature: (Ljava/lang/String;)L
 539  */
 540 JNIEXPORT jlong JNICALL
 541 Java_sun_jvm_hotspot_asm_Disassembler_load_1library(
 542   JNIEnv * env, 
 543   jclass disclass,
 544   jstring jrepath_s,
 545   jstring libname_s) 
 546 {