1 /* 2 * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 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 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 * 23 */ 24 25 #include <objc/objc-runtime.h> 26 #import <Foundation/Foundation.h> 27 #import <JavaNativeFoundation/JavaNativeFoundation.h> 28 #import <JavaRuntimeSupport/JavaRuntimeSupport.h> 29 30 #include <jni.h> 31 32 #import <mach/mach.h> 33 #import <mach/mach_types.h> 34 #import <sys/sysctl.h> 35 #import <stdio.h> 36 #import <string.h> 37 #import <stdarg.h> 38 #import <stdlib.h> 39 #import <strings.h> 40 #import <dlfcn.h> 41 #import <limits.h> 42 #import <errno.h> 43 #import <sys/types.h> 44 #import <sys/ptrace.h> 45 #include "libproc_impl.h" 46 47 #define UNSUPPORTED_ARCH "Unsupported architecture!" 48 49 #if defined(x86_64) && !defined(amd64) 50 #define amd64 1 51 #endif 52 53 #if amd64 54 #include "sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext.h" 55 #else 56 #error UNSUPPORTED_ARCH 57 #endif 58 59 static jfieldID symbolicatorID = 0; // set in _init0 60 static jfieldID taskID = 0; // set in _init0 61 62 static jfieldID p_ps_prochandle_ID = 0; 63 static jfieldID loadObjectList_ID = 0; 64 static jmethodID listAdd_ID = 0; 65 66 static jmethodID createClosestSymbol_ID = 0; 67 static jmethodID createLoadObject_ID = 0; 68 static jmethodID getJavaThreadsInfo_ID = 0; 69 70 // indicator if thread id (lwpid_t) was set 71 static bool _threads_filled = false; 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 130 static void putSymbolicator(JNIEnv *env, jobject this_obj, id symbolicator) { 131 (*env)->SetLongField(env, this_obj, symbolicatorID, (jlong)(intptr_t)symbolicator); 132 } 133 134 static id getSymbolicator(JNIEnv *env, jobject this_obj) { 135 jlong ptr = (*env)->GetLongField(env, this_obj, symbolicatorID); 136 return (id)(intptr_t)ptr; 137 } 138 139 static void putTask(JNIEnv *env, jobject this_obj, task_t task) { 140 (*env)->SetLongField(env, this_obj, taskID, (jlong)task); 141 } 142 143 static task_t getTask(JNIEnv *env, jobject this_obj) { 144 jlong ptr = (*env)->GetLongField(env, this_obj, taskID); 145 return (task_t)ptr; 146 } 147 148 #define CHECK_EXCEPTION_(value) if ((*env)->ExceptionOccurred(env)) { return value; } 149 #define CHECK_EXCEPTION if ((*env)->ExceptionOccurred(env)) { return;} 150 #define THROW_NEW_DEBUGGER_EXCEPTION_(str, value) { throw_new_debugger_exception(env, str); return value; } 151 #define THROW_NEW_DEBUGGER_EXCEPTION(str) { throw_new_debugger_exception(env, str); return;} 152 #define CHECK_EXCEPTION_CLEAR if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); } 153 #define CHECK_EXCEPTION_CLEAR_VOID if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return; } 154 #define CHECK_EXCEPTION_CLEAR_(value) if ((*env)->ExceptionOccurred(env)) { (*env)->ExceptionClear(env); return value; } 155 156 static void throw_new_debugger_exception(JNIEnv* env, const char* errMsg) { 157 jclass exceptionClass = (*env)->FindClass(env, "sun/jvm/hotspot/debugger/DebuggerException"); 158 CHECK_EXCEPTION; 159 (*env)->ThrowNew(env, exceptionClass, errMsg); 160 } 161 162 static struct ps_prochandle* get_proc_handle(JNIEnv* env, jobject this_obj) { 163 jlong ptr = (*env)->GetLongField(env, this_obj, p_ps_prochandle_ID); 164 return (struct ps_prochandle*)(intptr_t)ptr; 165 } 166 167 #if defined(__i386__) 168 #define hsdb_thread_state_t x86_thread_state32_t 169 #define hsdb_float_state_t x86_float_state32_t 170 #define HSDB_THREAD_STATE x86_THREAD_STATE32 171 #define HSDB_FLOAT_STATE x86_FLOAT_STATE32 172 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE32_COUNT 173 #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE32_COUNT 174 #elif defined(__x86_64__) 175 #define hsdb_thread_state_t x86_thread_state64_t 176 #define hsdb_float_state_t x86_float_state64_t 177 #define HSDB_THREAD_STATE x86_THREAD_STATE64 178 #define HSDB_FLOAT_STATE x86_FLOAT_STATE64 179 #define HSDB_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT 180 #define HSDB_FLOAT_STATE_COUNT x86_FLOAT_STATE64_COUNT 181 #else 182 #error UNSUPPORTED_ARCH 183 #endif 184 185 /* 186 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 187 * Method: init0 188 * Signature: ()V 189 */ 190 JNIEXPORT void JNICALL 191 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_init0(JNIEnv *env, jclass cls) { 192 symbolicatorID = (*env)->GetFieldID(env, cls, "symbolicator", "J"); 193 CHECK_EXCEPTION; 194 taskID = (*env)->GetFieldID(env, cls, "task", "J"); 195 CHECK_EXCEPTION; 196 197 // for core file 198 p_ps_prochandle_ID = (*env)->GetFieldID(env, cls, "p_ps_prochandle", "J"); 199 CHECK_EXCEPTION; 200 loadObjectList_ID = (*env)->GetFieldID(env, cls, "loadObjectList", "Ljava/util/List;"); 201 CHECK_EXCEPTION; 202 203 // methods we use 204 createClosestSymbol_ID = (*env)->GetMethodID(env, cls, "createClosestSymbol", 205 "(Ljava/lang/String;J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol;"); 206 CHECK_EXCEPTION; 207 createLoadObject_ID = (*env)->GetMethodID(env, cls, "createLoadObject", 208 "(Ljava/lang/String;JJ)Lsun/jvm/hotspot/debugger/cdbg/LoadObject;"); 209 CHECK_EXCEPTION; 210 211 // java.util.List method we call 212 jclass listClass = (*env)->FindClass(env, "java/util/List"); 213 CHECK_EXCEPTION; 214 listAdd_ID = (*env)->GetMethodID(env, listClass, "add", "(Ljava/lang/Object;)Z"); 215 CHECK_EXCEPTION; 216 getJavaThreadsInfo_ID = (*env)->GetMethodID(env, cls, "getJavaThreadsInfo", 217 "()[J"); 218 CHECK_EXCEPTION; 219 220 init_libproc(getenv("LIBSAPROC_DEBUG") != NULL); 221 } 222 223 JNIEXPORT jint JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getAddressSize 224 (JNIEnv *env, jclass cls) 225 { 226 #ifdef _LP64 227 return 8; 228 #else 229 #error UNSUPPORTED_ARCH 230 #endif 231 } 232 233 /** called by Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0 */ 234 jlong lookupByNameIncore( 235 JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jstring objectName, jstring symbolName) 236 { 237 const char *objectName_cstr, *symbolName_cstr; 238 jlong addr; 239 jboolean isCopy; 240 objectName_cstr = NULL; 241 if (objectName != NULL) { 242 objectName_cstr = (*env)->GetStringUTFChars(env, objectName, &isCopy); 243 CHECK_EXCEPTION_(0); 244 } 245 symbolName_cstr = (*env)->GetStringUTFChars(env, symbolName, &isCopy); 246 if ((*env)->ExceptionOccurred(env)) { 247 if (objectName_cstr != NULL) { 248 (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr); 249 } 250 return 0; 251 } 252 253 print_debug("look for %s \n", symbolName_cstr); 254 addr = (jlong) lookup_symbol(ph, objectName_cstr, symbolName_cstr); 255 256 if (objectName_cstr != NULL) { 257 (*env)->ReleaseStringUTFChars(env, objectName, objectName_cstr); 258 } 259 (*env)->ReleaseStringUTFChars(env, symbolName, symbolName_cstr); 260 return addr; 261 } 262 263 /* 264 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 265 * Method: lookupByName0 266 * Signature: (Ljava/lang/String;Ljava/lang/String;)J 267 */ 268 JNIEXPORT jlong JNICALL 269 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByName0( 270 JNIEnv *env, jobject this_obj, 271 jstring objectName, jstring symbolName) 272 { 273 struct ps_prochandle* ph = get_proc_handle(env, this_obj); 274 if (ph != NULL && ph->core != NULL) { 275 return lookupByNameIncore(env, ph, this_obj, objectName, symbolName); 276 } 277 278 jlong address = 0; 279 280 JNF_COCOA_ENTER(env); 281 NSString *symbolNameString = JNFJavaToNSString(env, symbolName); 282 283 print_debug("lookupInProcess called for %s\n", [symbolNameString UTF8String]); 284 285 id symbolicator = getSymbolicator(env, this_obj); 286 if (symbolicator != nil) { 287 uint64_t (*dynamicCall)(id, SEL, NSString *) = (uint64_t (*)(id, SEL, NSString *))&objc_msgSend; 288 address = (jlong) dynamicCall(symbolicator, @selector(addressForSymbol:), symbolNameString); 289 } 290 291 print_debug("address of symbol %s = %llx\n", [symbolNameString UTF8String], address); 292 JNF_COCOA_EXIT(env); 293 294 return address; 295 } 296 297 /* 298 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 299 * Method: lookupByAddress0 300 * Signature: (J)Lsun/jvm/hotspot/debugger/cdbg/ClosestSymbol; 301 */ 302 JNIEXPORT jobject JNICALL Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_lookupByAddress0 303 (JNIEnv *env, jobject this_obj, jlong addr) { 304 uintptr_t offset; 305 const char* sym = NULL; 306 jstring sym_string; 307 308 struct ps_prochandle* ph = get_proc_handle(env, this_obj); 309 if (ph != NULL && ph->core != NULL) { 310 sym = symbol_for_pc(ph, (uintptr_t) addr, &offset); 311 if (sym == NULL) return 0; 312 sym_string = (*env)->NewStringUTF(env, sym); 313 CHECK_EXCEPTION_(0); 314 return (*env)->CallObjectMethod(env, this_obj, createClosestSymbol_ID, 315 sym_string, (jlong)offset); 316 } 317 return 0; 318 } 319 320 /** called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0 */ 321 jbyteArray readBytesFromCore( 322 JNIEnv *env, struct ps_prochandle *ph, jobject this_obj, jlong addr, jlong numBytes) 323 { 324 jboolean isCopy; 325 jbyteArray array; 326 jbyte *bufPtr; 327 ps_err_e err; 328 329 array = (*env)->NewByteArray(env, numBytes); 330 CHECK_EXCEPTION_(0); 331 bufPtr = (*env)->GetByteArrayElements(env, array, &isCopy); 332 CHECK_EXCEPTION_(0); 333 334 err = ps_pread(ph, (psaddr_t) (uintptr_t)addr, bufPtr, numBytes); 335 (*env)->ReleaseByteArrayElements(env, array, bufPtr, 0); 336 return (err == PS_OK)? array : 0; 337 } 338 339 /* 340 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 341 * Method: readBytesFromProcess0 342 * Signature: (JJ)Lsun/jvm/hotspot/debugger/ReadResult; 343 */ 344 JNIEXPORT jbyteArray JNICALL 345 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_readBytesFromProcess0( 346 JNIEnv *env, jobject this_obj, 347 jlong addr, jlong numBytes) 348 { 349 print_debug("readBytesFromProcess called. addr = %llx numBytes = %lld\n", addr, numBytes); 350 351 // must allocate storage instead of using former parameter buf 352 jbyteArray array; 353 354 struct ps_prochandle* ph = get_proc_handle(env, this_obj); 355 if (ph != NULL && ph->core != NULL) { 356 return readBytesFromCore(env, ph, this_obj, addr, numBytes); 357 } 358 359 array = (*env)->NewByteArray(env, numBytes); 360 CHECK_EXCEPTION_(0); 361 362 unsigned long alignedAddress; 363 unsigned long alignedLength = 0; 364 kern_return_t result; 365 vm_offset_t *pages; 366 int *mapped; 367 long pageCount; 368 uint byteCount; 369 int i; 370 unsigned long remaining; 371 372 alignedAddress = trunc_page(addr); 373 if (addr != alignedAddress) { 374 alignedLength += addr - alignedAddress; 375 } 376 alignedLength = round_page(numBytes); 377 pageCount = alignedLength/vm_page_size; 378 379 // Allocate storage for pages and flags. 380 pages = malloc(pageCount * sizeof(vm_offset_t)); 381 if (pages == NULL) { 382 (*env)->DeleteLocalRef(env, array); 383 return NULL; 384 } 385 mapped = calloc(pageCount, sizeof(int)); 386 if (mapped == NULL) { 387 (*env)->DeleteLocalRef(env, array); 388 free(pages); 389 return NULL; 390 } 391 392 task_t gTask = getTask(env, this_obj); 393 // Try to read each of the pages. 394 for (i = 0; i < pageCount; i++) { 395 result = vm_read(gTask, alignedAddress + i*vm_page_size, vm_page_size, 396 &pages[i], &byteCount); 397 mapped[i] = (result == KERN_SUCCESS); 398 // assume all failures are unmapped pages 399 } 400 401 print_debug("%ld pages\n", pageCount); 402 403 remaining = numBytes; 404 405 for (i = 0; i < pageCount; i++) { 406 unsigned long len = vm_page_size; 407 unsigned long start = 0; 408 409 if (i == 0) { 410 start = addr - alignedAddress; 411 len = vm_page_size - start; 412 } 413 414 if (i == (pageCount - 1)) { 415 len = remaining; 416 } 417 418 if (mapped[i]) { 419 print_debug("page %d mapped (len %ld start %ld)\n", i, len, start); 420 (*env)->SetByteArrayRegion(env, array, 0, len, ((jbyte *) pages[i] + start)); 421 vm_deallocate(mach_task_self(), pages[i], vm_page_size); 422 } 423 424 remaining -= len; 425 } 426 427 free (pages); 428 free (mapped); 429 return array; 430 } 431 432 /** Only used for core file reading, set thread_id for threads which is got after core file parsed. 433 * Thread context is available in Mach-O core file but thread id is not. We can get thread id 434 * from Threads which store all java threads information when they are created. Here we can identify 435 * them as java threads by checking if a thread's rsp or rbp within a java thread's stack. 436 * Note Macosx uses unique_thread_id which is different from other platforms though printed ids 437 * are still pthread id. Function BsdDebuggerLocal.getJavaThreadsInfo returns an array of long 438 * integers to host all java threads' id, stack_start, stack_end as: 439 * [uid0, stack_start0, stack_end0, uid1, stack_start1, stack_end1, ...] 440 * 441 * The work cannot be done at init0 since Threads is not available yet(VM not initialized yet). 442 * This function should be called only once if succeeded 443 */ 444 bool fill_java_threads(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { 445 int n = 0, i = 0, j; 446 struct reg regs; 447 448 jlongArray thrinfos = (*env)->CallObjectMethod(env, this_obj, getJavaThreadsInfo_ID); 449 CHECK_EXCEPTION_(false); 450 int len = (int)(*env)->GetArrayLength(env, thrinfos); 451 uint64_t* cinfos = (uint64_t *)(*env)->GetLongArrayElements(env, thrinfos, NULL); 452 CHECK_EXCEPTION_(false); 453 n = get_num_threads(ph); 454 print_debug("fill_java_threads called, num_of_thread = %d\n", n); 455 for (i = 0; i < n; i++) { 456 if (!get_nth_lwp_regs(ph, i, ®s)) { 457 print_debug("Could not get regs of thread %d, already set!\n", i); 458 return false; 459 } 460 for (j = 0; j < len; j += 3) { 461 lwpid_t uid = cinfos[j]; 462 uint64_t beg = cinfos[j + 1]; 463 uint64_t end = cinfos[j + 2]; 464 if ((regs.r_rsp < end && regs.r_rsp >= beg) || 465 (regs.r_rbp < end && regs.r_rbp >= beg)) { 466 set_lwp_id(ph, i, uid); 467 break; 468 } 469 } 470 } 471 (*env)->ReleaseLongArrayElements(env, thrinfos, (jlong*)cinfos, 0); 472 CHECK_EXCEPTION_(false); 473 return true; 474 } 475 476 /* For core file only, called from 477 * Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0 478 */ 479 jlongArray getThreadIntegerRegisterSetFromCore(JNIEnv *env, jobject this_obj, long lwp_id, struct ps_prochandle* ph) { 480 if (!_threads_filled) { 481 if (!fill_java_threads(env, this_obj, ph)) { 482 throw_new_debugger_exception(env, "Failed to fill in threads"); 483 return 0; 484 } else { 485 _threads_filled = true; 486 } 487 } 488 489 struct reg gregs; 490 jboolean isCopy; 491 jlongArray array; 492 jlong *regs; 493 494 if (get_lwp_regs(ph, lwp_id, &gregs) != true) { 495 THROW_NEW_DEBUGGER_EXCEPTION_("get_thread_regs failed for a lwp", 0); 496 } 497 498 #undef NPRGREG 499 #undef REG_INDEX 500 #if amd64 501 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG 502 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg 503 504 array = (*env)->NewLongArray(env, NPRGREG); 505 CHECK_EXCEPTION_(0); 506 regs = (*env)->GetLongArrayElements(env, array, &isCopy); 507 508 regs[REG_INDEX(R15)] = gregs.r_r15; 509 regs[REG_INDEX(R14)] = gregs.r_r14; 510 regs[REG_INDEX(R13)] = gregs.r_r13; 511 regs[REG_INDEX(R12)] = gregs.r_r12; 512 regs[REG_INDEX(RBP)] = gregs.r_rbp; 513 regs[REG_INDEX(RBX)] = gregs.r_rbx; 514 regs[REG_INDEX(R11)] = gregs.r_r11; 515 regs[REG_INDEX(R10)] = gregs.r_r10; 516 regs[REG_INDEX(R9)] = gregs.r_r9; 517 regs[REG_INDEX(R8)] = gregs.r_r8; 518 regs[REG_INDEX(RAX)] = gregs.r_rax; 519 regs[REG_INDEX(RCX)] = gregs.r_rcx; 520 regs[REG_INDEX(RDX)] = gregs.r_rdx; 521 regs[REG_INDEX(RSI)] = gregs.r_rsi; 522 regs[REG_INDEX(RDI)] = gregs.r_rdi; 523 regs[REG_INDEX(RIP)] = gregs.r_rip; 524 regs[REG_INDEX(CS)] = gregs.r_cs; 525 regs[REG_INDEX(RSP)] = gregs.r_rsp; 526 regs[REG_INDEX(SS)] = gregs.r_ss; 527 regs[REG_INDEX(FSBASE)] = 0; 528 regs[REG_INDEX(GSBASE)] = 0; 529 regs[REG_INDEX(DS)] = gregs.r_ds; 530 regs[REG_INDEX(ES)] = gregs.r_es; 531 regs[REG_INDEX(FS)] = gregs.r_fs; 532 regs[REG_INDEX(GS)] = gregs.r_gs; 533 regs[REG_INDEX(TRAPNO)] = gregs.r_trapno; 534 regs[REG_INDEX(RFL)] = gregs.r_rflags; 535 536 #endif /* amd64 */ 537 (*env)->ReleaseLongArrayElements(env, array, regs, JNI_COMMIT); 538 return array; 539 } 540 541 /* 542 * Lookup the thread_t that corresponds to the given thread_id. 543 * The thread_id should be the result from calling thread_info() with THREAD_IDENTIFIER_INFO 544 * and reading the m_ident_info.thread_id returned. 545 * The returned thread_t is the mach send right to the kernel port for the corresponding thread. 546 * 547 * We cannot simply use the OSThread._thread_id field in the JVM. This is set to ::mach_thread_self() 548 * in the VM, but that thread port is not valid for a remote debugger to access the thread. 549 */ 550 thread_t 551 lookupThreadFromThreadId(task_t task, jlong thread_id) { 552 print_debug("lookupThreadFromThreadId thread_id=0x%llx\n", thread_id); 553 554 thread_array_t thread_list = NULL; 555 mach_msg_type_number_t thread_list_count = 0; 556 thread_t result_thread = 0; 557 int i; 558 559 // get the list of all the send rights 560 kern_return_t result = task_threads(task, &thread_list, &thread_list_count); 561 if (result != KERN_SUCCESS) { 562 print_debug("task_threads returned 0x%x\n", result); 563 return 0; 564 } 565 566 for(i = 0 ; i < thread_list_count; i++) { 567 thread_identifier_info_data_t m_ident_info; 568 mach_msg_type_number_t count = THREAD_IDENTIFIER_INFO_COUNT; 569 570 // get the THREAD_IDENTIFIER_INFO for the send right 571 result = thread_info(thread_list[i], THREAD_IDENTIFIER_INFO, (thread_info_t) &m_ident_info, &count); 572 if (result != KERN_SUCCESS) { 573 print_debug("thread_info returned 0x%x\n", result); 574 break; 575 } 576 577 // if this is the one we're looking for, return the send right 578 if (thread_id == m_ident_info.thread_id) 579 { 580 result_thread = thread_list[i]; 581 break; 582 } 583 } 584 585 vm_size_t thread_list_size = (vm_size_t) (thread_list_count * sizeof (thread_t)); 586 vm_deallocate(mach_task_self(), (vm_address_t) thread_list, thread_list_count); 587 588 return result_thread; 589 } 590 591 592 /* 593 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 594 * Method: getThreadIntegerRegisterSet0 595 * Signature: (J)[J 596 */ 597 JNIEXPORT jlongArray JNICALL 598 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_getThreadIntegerRegisterSet0( 599 JNIEnv *env, jobject this_obj, 600 jlong thread_id) 601 { 602 print_debug("getThreadRegisterSet0 called\n"); 603 604 struct ps_prochandle* ph = get_proc_handle(env, this_obj); 605 if (ph != NULL && ph->core != NULL) { 606 return getThreadIntegerRegisterSetFromCore(env, this_obj, thread_id, ph); 607 } 608 609 kern_return_t result; 610 thread_t tid; 611 mach_msg_type_number_t count = HSDB_THREAD_STATE_COUNT; 612 hsdb_thread_state_t state; 613 jlongArray registerArray; 614 jlong *primitiveArray; 615 task_t gTask = getTask(env, this_obj); 616 617 tid = lookupThreadFromThreadId(gTask, thread_id); 618 619 result = thread_get_state(tid, HSDB_THREAD_STATE, (thread_state_t)&state, &count); 620 621 if (result != KERN_SUCCESS) { 622 print_error("getregs: thread_get_state(%d) failed (%d)\n", tid, result); 623 return NULL; 624 } 625 626 #if amd64 627 #define NPRGREG sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_NPRGREG 628 #undef REG_INDEX 629 #define REG_INDEX(reg) sun_jvm_hotspot_debugger_amd64_AMD64ThreadContext_##reg 630 631 // 64 bit 632 print_debug("Getting threads for a 64-bit process\n"); 633 registerArray = (*env)->NewLongArray(env, NPRGREG); 634 CHECK_EXCEPTION_(0); 635 primitiveArray = (*env)->GetLongArrayElements(env, registerArray, NULL); 636 637 primitiveArray[REG_INDEX(R15)] = state.__r15; 638 primitiveArray[REG_INDEX(R14)] = state.__r14; 639 primitiveArray[REG_INDEX(R13)] = state.__r13; 640 primitiveArray[REG_INDEX(R12)] = state.__r12; 641 primitiveArray[REG_INDEX(R11)] = state.__r11; 642 primitiveArray[REG_INDEX(R10)] = state.__r10; 643 primitiveArray[REG_INDEX(R9)] = state.__r9; 644 primitiveArray[REG_INDEX(R8)] = state.__r8; 645 primitiveArray[REG_INDEX(RDI)] = state.__rdi; 646 primitiveArray[REG_INDEX(RSI)] = state.__rsi; 647 primitiveArray[REG_INDEX(RBP)] = state.__rbp; 648 primitiveArray[REG_INDEX(RBX)] = state.__rbx; 649 primitiveArray[REG_INDEX(RDX)] = state.__rdx; 650 primitiveArray[REG_INDEX(RCX)] = state.__rcx; 651 primitiveArray[REG_INDEX(RAX)] = state.__rax; 652 primitiveArray[REG_INDEX(TRAPNO)] = 0; // trapno, not used 653 primitiveArray[REG_INDEX(ERR)] = 0; // err, not used 654 primitiveArray[REG_INDEX(RIP)] = state.__rip; 655 primitiveArray[REG_INDEX(CS)] = state.__cs; 656 primitiveArray[REG_INDEX(RFL)] = state.__rflags; 657 primitiveArray[REG_INDEX(RSP)] = state.__rsp; 658 primitiveArray[REG_INDEX(SS)] = 0; // We don't have SS 659 primitiveArray[REG_INDEX(FS)] = state.__fs; 660 primitiveArray[REG_INDEX(GS)] = state.__gs; 661 primitiveArray[REG_INDEX(ES)] = 0; 662 primitiveArray[REG_INDEX(DS)] = 0; 663 primitiveArray[REG_INDEX(FSBASE)] = 0; 664 primitiveArray[REG_INDEX(GSBASE)] = 0; 665 print_debug("set registers\n"); 666 667 (*env)->ReleaseLongArrayElements(env, registerArray, primitiveArray, 0); 668 669 #else 670 #error UNSUPPORTED_ARCH 671 #endif /* amd64 */ 672 673 return registerArray; 674 } 675 676 /* 677 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 678 * Method: translateTID0 679 * Signature: (I)I 680 */ 681 JNIEXPORT jint JNICALL 682 Java_sun_jvm_hotspot_debugger_macosx_MacOSXDebuggerLocal_translateTID0( 683 JNIEnv *env, jobject this_obj, jint tid) 684 { 685 print_debug("translateTID0 called on tid = 0x%x\n", (int)tid); 686 687 kern_return_t result; 688 thread_t foreign_tid, usable_tid; 689 mach_msg_type_name_t type; 690 691 foreign_tid = tid; 692 693 task_t gTask = getTask(env, this_obj); 694 result = mach_port_extract_right(gTask, foreign_tid, 695 MACH_MSG_TYPE_COPY_SEND, 696 &usable_tid, &type); 697 if (result != KERN_SUCCESS) 698 return -1; 699 700 print_debug("translateTID0: 0x%x -> 0x%x\n", foreign_tid, usable_tid); 701 702 return (jint) usable_tid; 703 } 704 705 // attach to a process/thread specified by "pid" 706 static bool ptrace_attach(pid_t pid) { 707 errno = 0; 708 ptrace(PT_ATTACHEXC, pid, 0, 0); 709 710 if (errno != 0) { 711 print_error("ptrace_attach: ptrace(PT_ATTACHEXC,...) failed: %s", strerror(errno)); 712 return false; 713 } 714 return true; 715 } 716 717 kern_return_t catch_mach_exception_raise( 718 mach_port_t exception_port, mach_port_t thread_port, mach_port_t task_port, 719 exception_type_t exception_type, mach_exception_data_t codes, 720 mach_msg_type_number_t num_codes) { 721 722 print_debug("catch_mach_exception_raise: Exception port = %d thread_port = %d " 723 "task port %d exc type = %d num_codes %d\n", 724 exception_port, thread_port, task_port, exception_type, num_codes); 725 726 // This message should denote a Unix soft signal, with 727 // 1. the exception type = EXC_SOFTWARE 728 // 2. codes[0] (which is the code) = EXC_SOFT_SIGNAL 729 // 3. codes[1] (which is the sub-code) = SIGSTOP 730 if (!(exception_type == EXC_SOFTWARE && 731 codes[0] == EXC_SOFT_SIGNAL && 732 codes[num_codes -1] == SIGSTOP)) { 733 print_error("catch_mach_exception_raise: Message doesn't denote a Unix " 734 "soft signal. exception_type = %d, codes[0] = %d, " 735 "codes[num_codes -1] = %d, num_codes = %d\n", 736 exception_type, codes[0], codes[num_codes - 1], num_codes); 737 return MACH_RCV_INVALID_TYPE; 738 } 739 return KERN_SUCCESS; 740 } 741 742 kern_return_t catch_mach_exception_raise_state( 743 mach_port_t exception_port, exception_type_t exception, const mach_exception_data_t code, 744 mach_msg_type_number_t code_cnt, int *flavor, const thread_state_t old_state, 745 mach_msg_type_number_t old_state_cnt, thread_state_t new_state, 746 mach_msg_type_number_t *new_state_cnt) { 747 return MACH_RCV_INVALID_TYPE; 748 } 749 750 751 kern_return_t catch_mach_exception_raise_state_identity( 752 mach_port_t exception_port, mach_port_t thread, mach_port_t task, 753 exception_type_t exception, mach_exception_data_t code, 754 mach_msg_type_number_t code_cnt, int *flavor, 755 thread_state_t old_state, mach_msg_type_number_t old_state_cnt, 756 thread_state_t new_state, mach_msg_type_number_t *new_state_cnt) { 757 return MACH_RCV_INVALID_TYPE; 758 } 759 760 // wait to receive an exception message 761 static bool wait_for_exception() { 762 kern_return_t result; 763 764 result = mach_msg(&exc_msg.header, 765 MACH_RCV_MSG, 766 0, 767 sizeof(exc_msg), 768 tgt_exception_port, 769 MACH_MSG_TIMEOUT_NONE, 770 MACH_PORT_NULL); 771 772 if (result != MACH_MSG_SUCCESS) { 773 print_error("attach: wait_for_exception: mach_msg() failed: '%s' (%d)\n", 774 mach_error_string(result), result); 775 return false; 776 } 777 778 if (mach_exc_server(&exc_msg.header, &rep_msg.header) == false || 779 rep_msg.ret_code != KERN_SUCCESS) { 780 print_error("attach: wait_for_exception: mach_exc_server failure\n"); 781 if (rep_msg.ret_code != KERN_SUCCESS) { 782 print_error("catch_mach_exception_raise() failed '%s' (%d)\n", 783 mach_error_string(rep_msg.ret_code), rep_msg.ret_code); 784 } 785 return false; 786 } 787 788 print_debug("reply msg from mach_exc_server: (msg->{bits = %#x, size = %u, " 789 "remote_port = %#x, local_port = %#x, reserved = 0x%x, id = 0x%x},)", 790 rep_msg.header.msgh_bits, rep_msg.header.msgh_size, 791 rep_msg.header.msgh_remote_port, rep_msg.header.msgh_local_port, 792 rep_msg.header.msgh_reserved, rep_msg.header.msgh_id); 793 794 return true; 795 } 796 797 /* 798 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 799 * Method: attach0 800 * Signature: (I)V 801 */ 802 JNIEXPORT void JNICALL 803 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__I( 804 JNIEnv *env, jobject this_obj, jint jpid) 805 { 806 print_debug("attach0 called for jpid=%d\n", (int)jpid); 807 808 JNF_COCOA_ENTER(env); 809 810 kern_return_t result; 811 task_t gTask = 0; 812 813 result = task_for_pid(mach_task_self(), jpid, &gTask); 814 if (result != KERN_SUCCESS) { 815 print_error("attach: task_for_pid(%d) failed: '%s' (%d)\n", (int)jpid, mach_error_string(result), result); 816 THROW_NEW_DEBUGGER_EXCEPTION( 817 "Can't attach to the process. Could be caused by an incorrect pid or lack of privileges."); 818 } 819 putTask(env, this_obj, gTask); 820 821 // Allocate an exception port. 822 result = mach_port_allocate(mach_task_self(), 823 MACH_PORT_RIGHT_RECEIVE, 824 &tgt_exception_port); 825 if (result != KERN_SUCCESS) { 826 print_error("attach: mach_port_allocate() for tgt_exception_port failed: '%s' (%d)\n", 827 mach_error_string(result), result); 828 THROW_NEW_DEBUGGER_EXCEPTION( 829 "Can't attach to the process. Couldn't allocate an exception port."); 830 } 831 832 // Enable the new exception port to send messages. 833 result = mach_port_insert_right (mach_task_self(), 834 tgt_exception_port, 835 tgt_exception_port, 836 MACH_MSG_TYPE_MAKE_SEND); 837 if (result != KERN_SUCCESS) { 838 print_error("attach: mach_port_insert_right() failed for port 0x%x: '%s' (%d)\n", 839 tgt_exception_port, mach_error_string(result), result); 840 THROW_NEW_DEBUGGER_EXCEPTION( 841 "Can't attach to the process. Couldn't add send privileges to the exception port."); 842 } 843 844 // Save the existing original exception ports registered with the target 845 // process (for later restoration while detaching from the process). 846 result = task_get_exception_ports(gTask, 847 EXC_MASK_ALL, 848 exception_saved_state.saved_masks, 849 &exception_saved_state.saved_exception_types_count, 850 exception_saved_state.saved_ports, 851 exception_saved_state.saved_behaviors, 852 exception_saved_state.saved_flavors); 853 854 if (result != KERN_SUCCESS) { 855 print_error("attach: task_get_exception_ports() failed: '%s' (%d)\n", 856 mach_error_string(result), result); 857 THROW_NEW_DEBUGGER_EXCEPTION( 858 "Can't attach to the process. Could not get the target exception ports."); 859 } 860 861 // register the exception port to be used for all future exceptions with the 862 // target process. 863 result = task_set_exception_ports(gTask, 864 EXC_MASK_ALL, 865 tgt_exception_port, 866 EXCEPTION_DEFAULT | MACH_EXCEPTION_CODES, 867 THREAD_STATE_NONE); 868 869 if (result != KERN_SUCCESS) { 870 print_error("attach: task_set_exception_ports() failed -- port 0x%x: '%s' (%d)\n", 871 tgt_exception_port, mach_error_string(result), result); 872 mach_port_deallocate(mach_task_self(), gTask); 873 mach_port_deallocate(mach_task_self(), tgt_exception_port); 874 THROW_NEW_DEBUGGER_EXCEPTION( 875 "Can't attach to the process. Could not register the exception port " 876 "with the target process."); 877 } 878 879 // use ptrace to stop the process 880 // on os x, ptrace only needs to be called on the process, not the individual threads 881 if (ptrace_attach(jpid) != true) { 882 print_error("attach: ptrace failure in attaching to %d\n", (int)jpid); 883 mach_port_deallocate(mach_task_self(), gTask); 884 mach_port_deallocate(mach_task_self(), tgt_exception_port); 885 THROW_NEW_DEBUGGER_EXCEPTION("Can't ptrace attach to the process"); 886 } 887 888 if (wait_for_exception() != true) { 889 mach_port_deallocate(mach_task_self(), gTask); 890 mach_port_deallocate(mach_task_self(), tgt_exception_port); 891 THROW_NEW_DEBUGGER_EXCEPTION( 892 "Can't attach to the process. Issues with reception of the exception message."); 893 } 894 895 // suspend all the threads in the task 896 result = task_suspend(gTask); 897 if (result != KERN_SUCCESS) { 898 print_error("attach: task_suspend() failed: '%s' (%d)\n", 899 mach_error_string(result), result); 900 mach_port_deallocate(mach_task_self(), gTask); 901 mach_port_deallocate(mach_task_self(), tgt_exception_port); 902 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach. Unable to suspend all the threads in the task."); 903 } 904 905 id symbolicator = nil; 906 id jrsSymbolicator = objc_lookUpClass("JRSSymbolicator"); 907 if (jrsSymbolicator != nil) { 908 id (*dynamicCall)(id, SEL, pid_t) = (id (*)(id, SEL, pid_t))&objc_msgSend; 909 symbolicator = dynamicCall(jrsSymbolicator, @selector(symbolicatorForPid:), (pid_t)jpid); 910 } 911 if (symbolicator != nil) { 912 CFRetain(symbolicator); // pin symbolicator while in java heap 913 } 914 915 putSymbolicator(env, this_obj, symbolicator); 916 if (symbolicator == nil) { 917 mach_port_deallocate(mach_task_self(), gTask); 918 mach_port_deallocate(mach_task_self(), tgt_exception_port); 919 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach symbolicator to the process"); 920 } 921 922 JNF_COCOA_EXIT(env); 923 } 924 925 /** For core file, 926 called from Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2 */ 927 static void fillLoadObjects(JNIEnv* env, jobject this_obj, struct ps_prochandle* ph) { 928 int n = 0, i = 0; 929 930 // add load objects 931 n = get_num_libs(ph); 932 for (i = 0; i < n; i++) { 933 uintptr_t base; 934 const char* name; 935 jobject loadObject; 936 jobject loadObjectList; 937 jstring nameString; 938 939 base = get_lib_base(ph, i); 940 name = get_lib_name(ph, i); 941 nameString = (*env)->NewStringUTF(env, name); 942 CHECK_EXCEPTION; 943 loadObject = (*env)->CallObjectMethod(env, this_obj, createLoadObject_ID, 944 nameString, (jlong)0, (jlong)base); 945 CHECK_EXCEPTION; 946 loadObjectList = (*env)->GetObjectField(env, this_obj, loadObjectList_ID); 947 CHECK_EXCEPTION; 948 (*env)->CallBooleanMethod(env, loadObjectList, listAdd_ID, loadObject); 949 CHECK_EXCEPTION; 950 } 951 } 952 953 /* 954 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 955 * Method: attach0 956 * Signature: (Ljava/lang/String;Ljava/lang/String;)V 957 */ 958 JNIEXPORT void JNICALL 959 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_attach0__Ljava_lang_String_2Ljava_lang_String_2( 960 JNIEnv *env, jobject this_obj, jstring execName, jstring coreName) 961 { 962 const char *execName_cstr; 963 const char *coreName_cstr; 964 jboolean isCopy; 965 struct ps_prochandle* ph; 966 967 execName_cstr = (*env)->GetStringUTFChars(env, execName, &isCopy); 968 CHECK_EXCEPTION; 969 coreName_cstr = (*env)->GetStringUTFChars(env, coreName, &isCopy); 970 if ((*env)->ExceptionOccurred(env)) { 971 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); 972 return; 973 } 974 975 print_debug("attach: %s %s\n", execName_cstr, coreName_cstr); 976 977 if ( (ph = Pgrab_core(execName_cstr, coreName_cstr)) == NULL) { 978 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); 979 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); 980 THROW_NEW_DEBUGGER_EXCEPTION("Can't attach to the core file"); 981 } 982 (*env)->SetLongField(env, this_obj, p_ps_prochandle_ID, (jlong)(intptr_t)ph); 983 (*env)->ReleaseStringUTFChars(env, execName, execName_cstr); 984 (*env)->ReleaseStringUTFChars(env, coreName, coreName_cstr); 985 fillLoadObjects(env, this_obj, ph); 986 } 987 988 static void detach_cleanup(task_t gTask, JNIEnv *env, jobject this_obj, bool throw_exception) { 989 mach_port_deallocate(mach_task_self(), tgt_exception_port); 990 mach_port_deallocate(mach_task_self(), gTask); 991 992 id symbolicator = getSymbolicator(env, this_obj); 993 if (symbolicator != nil) { 994 CFRelease(symbolicator); 995 } 996 if (throw_exception) { 997 THROW_NEW_DEBUGGER_EXCEPTION("Cannot detach."); 998 } 999 } 1000 1001 /* 1002 * Class: sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal 1003 * Method: detach0 1004 * Signature: ()V 1005 */ 1006 JNIEXPORT void JNICALL 1007 Java_sun_jvm_hotspot_debugger_bsd_BsdDebuggerLocal_detach0( 1008 JNIEnv *env, jobject this_obj) 1009 { 1010 print_debug("detach0 called\n"); 1011 struct ps_prochandle* ph = get_proc_handle(env, this_obj); 1012 if (ph != NULL && ph->core != NULL) { 1013 Prelease(ph); 1014 return; 1015 } 1016 JNF_COCOA_ENTER(env); 1017 1018 task_t gTask = getTask(env, this_obj); 1019 kern_return_t k_res = 0; 1020 1021 // Restore the pre-saved original exception ports registered with the target process 1022 for (uint32_t i = 0; i < exception_saved_state.saved_exception_types_count; ++i) { 1023 k_res = task_set_exception_ports(gTask, 1024 exception_saved_state.saved_masks[i], 1025 exception_saved_state.saved_ports[i], 1026 exception_saved_state.saved_behaviors[i], 1027 exception_saved_state.saved_flavors[i]); 1028 if (k_res != KERN_SUCCESS) { 1029 print_error("detach: task_set_exception_ports failed with %d while " 1030 "restoring the target exception ports.\n", k_res); 1031 detach_cleanup(gTask, env, this_obj, true); 1032 } 1033 } 1034 1035 // detach from the ptraced process causing it to resume execution 1036 int pid; 1037 k_res = pid_for_task(gTask, &pid); 1038 if (k_res != KERN_SUCCESS) { 1039 print_error("detach: pid_for_task(%d) failed (%d)\n", pid, k_res); 1040 detach_cleanup(gTask, env, this_obj, true); 1041 } 1042 else { 1043 errno = 0; 1044 ptrace(PT_DETACH, pid, (caddr_t)1, 0); 1045 if (errno != 0) { 1046 print_error("detach: ptrace(PT_DETACH,...) failed: %s", strerror(errno)); 1047 detach_cleanup(gTask, env, this_obj, true); 1048 } 1049 } 1050 1051 // reply to the previous exception message 1052 k_res = mach_msg(&rep_msg.header, 1053 MACH_SEND_MSG| MACH_SEND_INTERRUPT, 1054 rep_msg.header.msgh_size, 1055 0, 1056 MACH_PORT_NULL, 1057 MACH_MSG_TIMEOUT_NONE, 1058 MACH_PORT_NULL); 1059 if (k_res != MACH_MSG_SUCCESS) { 1060 print_error("detach: mach_msg() for replying to pending exceptions failed: '%s' (%d)\n", 1061 mach_error_string(k_res), k_res); 1062 detach_cleanup(gTask, env, this_obj, true); 1063 } 1064 1065 detach_cleanup(gTask, env, this_obj, false); 1066 1067 JNF_COCOA_EXIT(env); 1068 }