1 /* 2 * Copyright (c) 1998, 2014, 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. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 #include <ctype.h> 27 28 #include "util.h" 29 #include "commonRef.h" 30 #include "debugDispatch.h" 31 #include "eventHandler.h" 32 #include "eventHelper.h" 33 #include "threadControl.h" 34 #include "stepControl.h" 35 #include "transport.h" 36 #include "classTrack.h" 37 #include "debugLoop.h" 38 #include "bag.h" 39 #include "invoker.h" 40 #include "sys.h" 41 42 /* How the options get to OnLoad: */ 43 #define XDEBUG "-Xdebug" 44 #define XRUN "-Xrunjdwp" 45 #define AGENTLIB "-agentlib:jdwp" 46 47 /* Debug version defaults */ 48 #ifdef DEBUG 49 #define DEFAULT_ASSERT_ON JNI_TRUE 50 #define DEFAULT_ASSERT_FATAL JNI_TRUE 51 #define DEFAULT_LOGFILE "jdwp.log" 52 #else 53 #define DEFAULT_ASSERT_ON JNI_FALSE 54 #define DEFAULT_ASSERT_FATAL JNI_FALSE 55 #define DEFAULT_LOGFILE NULL 56 #endif 57 58 static jboolean vmInitialized; 59 static jrawMonitorID initMonitor; 60 static jboolean initComplete; 61 static jbyte currentSessionID; 62 63 /* 64 * Options set through the OnLoad options string. All of these values 65 * are set once at VM startup and never reset. 66 */ 67 static jboolean isServer = JNI_FALSE; /* Listens for connecting debuggers? */ 68 static jboolean isStrict = JNI_FALSE; /* Unused */ 69 static jboolean useStandardAlloc = JNI_FALSE; /* Use standard malloc/free? */ 70 static struct bag *transports; /* of TransportSpec */ 71 72 static jboolean initOnStartup = JNI_TRUE; /* init immediately */ 73 static char *initOnException = NULL; /* init when this exception thrown */ 74 static jboolean initOnUncaught = JNI_FALSE; /* init when uncaught exc thrown */ 75 76 static char *launchOnInit = NULL; /* launch this app during init */ 77 static jboolean suspendOnInit = JNI_TRUE; /* suspend all app threads after init */ 78 static jboolean dopause = JNI_FALSE; /* pause for debugger attach */ 79 static jboolean docoredump = JNI_FALSE; /* core dump on exit */ 80 static char *logfile = NULL; /* Name of logfile (if logging) */ 81 static unsigned logflags = 0; /* Log flags */ 82 83 static char *names; /* strings derived from OnLoad options */ 84 85 /* 86 * Elements of the transports bag 87 */ 88 typedef struct TransportSpec { 89 char *name; 90 char *address; 91 long timeout; 92 } TransportSpec; 93 94 /* 95 * Forward Refs 96 */ 97 static void JNICALL cbEarlyVMInit(jvmtiEnv*, JNIEnv *, jthread); 98 static void JNICALL cbEarlyVMDeath(jvmtiEnv*, JNIEnv *); 99 static void JNICALL cbEarlyException(jvmtiEnv*, JNIEnv *, 100 jthread, jmethodID, jlocation, jobject, jmethodID, jlocation); 101 102 static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei); 103 static jboolean parseOptions(char *str); 104 105 /* 106 * Phase 1: Initial load. 107 * 108 * OnLoad is called by the VM immediately after the back-end 109 * library is loaded. We can do very little in this function since 110 * the VM has not completed initialization. So, we parse the JDWP 111 * options and set up a simple initial event callbacks for JVMTI events. 112 * When a triggering event occurs, that callback will begin debugger initialization. 113 */ 114 115 /* Get a static area to hold the Global Data */ 116 static BackendGlobalData * 117 get_gdata(void) 118 { 119 static BackendGlobalData s; 120 (void)memset(&s, 0, sizeof(BackendGlobalData)); 121 return &s; 122 } 123 124 static jvmtiError 125 set_event_notification(jvmtiEventMode mode, EventIndex ei) 126 { 127 jvmtiError error; 128 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode) 129 (gdata->jvmti, mode, eventIndex2jvmti(ei), NULL); 130 if (error != JVMTI_ERROR_NONE) { 131 ERROR_MESSAGE(("JDWP unable to configure initial JVMTI event %s: %s(%d)", 132 eventText(ei), jvmtiErrorText(error), error)); 133 } 134 return error; 135 } 136 137 typedef struct { 138 int major; 139 int minor; 140 } version_type; 141 142 typedef struct { 143 version_type runtime; 144 version_type compiletime; 145 } compatible_versions_type; 146 147 /* 148 * List of explicitly compatible JVMTI versions, specified as 149 * { runtime version, compile-time version } pairs. -1 is a wildcard. 150 */ 151 static int nof_compatible_versions = 3; 152 static compatible_versions_type compatible_versions_list[] = { 153 /* 154 * FIXUP: Allow version 0 to be compatible with anything 155 * Special check for FCS of 1.0. 156 */ 157 { { 0, -1 }, { -1, -1 } }, 158 { { -1, -1 }, { 0, -1 } }, 159 /* 160 * 1.2 is runtime compatible with 1.1 -- just make sure to check the 161 * version before using any new 1.2 features 162 */ 163 { { 1, 1 }, { 1, 2 } } 164 }; 165 166 167 /* Logic to determine JVMTI version compatibility */ 168 static jboolean 169 compatible_versions(jint major_runtime, jint minor_runtime, 170 jint major_compiletime, jint minor_compiletime) 171 { 172 /* 173 * First check to see if versions are explicitly compatible via the 174 * list specified above. 175 */ 176 int i; 177 for (i = 0; i < nof_compatible_versions; ++i) { 178 version_type runtime = compatible_versions_list[i].runtime; 179 version_type comptime = compatible_versions_list[i].compiletime; 180 181 if ((major_runtime == runtime.major || runtime.major == -1) && 182 (minor_runtime == runtime.minor || runtime.minor == -1) && 183 (major_compiletime == comptime.major || comptime.major == -1) && 184 (minor_compiletime == comptime.minor || comptime.minor == -1)) { 185 return JNI_TRUE; 186 } 187 } 188 189 return major_runtime == major_compiletime && 190 minor_runtime >= minor_compiletime; 191 } 192 193 /* OnLoad startup: 194 * Returning JNI_ERR will cause the java_g VM to core dump, be careful. 195 */ 196 JNIEXPORT jint JNICALL 197 Agent_OnLoad(JavaVM *vm, char *options, void *reserved) 198 { 199 jvmtiError error; 200 jvmtiCapabilities needed_capabilities; 201 jvmtiCapabilities potential_capabilities; 202 jint jvmtiCompileTimeMajorVersion; 203 jint jvmtiCompileTimeMinorVersion; 204 jint jvmtiCompileTimeMicroVersion; 205 206 /* See if it's already loaded */ 207 if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) { 208 ERROR_MESSAGE(("Cannot load this JVM TI agent twice, check your java command line for duplicate jdwp options.")); 209 return JNI_ERR; 210 } 211 212 /* If gdata is defined and the VM died, why are we here? */ 213 if ( gdata!=NULL && gdata->vmDead ) { 214 ERROR_MESSAGE(("JDWP unable to load, VM died")); 215 return JNI_ERR; 216 } 217 218 /* Get global data area */ 219 gdata = get_gdata(); 220 if (gdata == NULL) { 221 ERROR_MESSAGE(("JDWP unable to allocate memory")); 222 return JNI_ERR; 223 } 224 gdata->isLoaded = JNI_TRUE; 225 226 /* Start filling in gdata */ 227 gdata->jvm = vm; 228 vmInitialized = JNI_FALSE; 229 gdata->vmDead = JNI_FALSE; 230 231 /* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */ 232 error = JVM_FUNC_PTR(vm,GetEnv) 233 (vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1); 234 if (error != JNI_OK) { 235 ERROR_MESSAGE(("JDWP unable to access JVMTI Version 1 (0x%x)," 236 " is your J2SE a 1.5 or newer version?" 237 " JNIEnv's GetEnv() returned %d", 238 JVMTI_VERSION_1, error)); 239 forceExit(1); /* Kill entire process, no core dump */ 240 } 241 242 /* Check to make sure the version of jvmti.h we compiled with 243 * matches the runtime version we are using. 244 */ 245 jvmtiCompileTimeMajorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MAJOR ) 246 >> JVMTI_VERSION_SHIFT_MAJOR; 247 jvmtiCompileTimeMinorVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MINOR ) 248 >> JVMTI_VERSION_SHIFT_MINOR; 249 jvmtiCompileTimeMicroVersion = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MICRO ) 250 >> JVMTI_VERSION_SHIFT_MICRO; 251 252 /* Check for compatibility */ 253 if ( !compatible_versions(jvmtiMajorVersion(), jvmtiMinorVersion(), 254 jvmtiCompileTimeMajorVersion, jvmtiCompileTimeMinorVersion) ) { 255 256 ERROR_MESSAGE(("This jdwp native library will not work with this VM's " 257 "version of JVMTI (%d.%d.%d), it needs JVMTI %d.%d[.%d].", 258 jvmtiMajorVersion(), 259 jvmtiMinorVersion(), 260 jvmtiMicroVersion(), 261 jvmtiCompileTimeMajorVersion, 262 jvmtiCompileTimeMinorVersion, 263 jvmtiCompileTimeMicroVersion)); 264 265 /* Do not let VM get a fatal error, we don't want a core dump here. */ 266 forceExit(1); /* Kill entire process, no core dump wanted */ 267 } 268 269 /* Parse input options */ 270 if (!parseOptions(options)) { 271 /* No message necessary, should have been printed out already */ 272 /* Do not let VM get a fatal error, we don't want a core dump here. */ 273 forceExit(1); /* Kill entire process, no core dump wanted */ 274 } 275 276 LOG_MISC(("Onload: %s", options)); 277 278 /* Get potential capabilities */ 279 (void)memset(&potential_capabilities,0,sizeof(potential_capabilities)); 280 error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities) 281 (gdata->jvmti, &potential_capabilities); 282 if (error != JVMTI_ERROR_NONE) { 283 ERROR_MESSAGE(("JDWP unable to get potential JVMTI capabilities: %s(%d)", 284 jvmtiErrorText(error), error)); 285 return JNI_ERR; 286 } 287 288 /* Fill in ones that we must have */ 289 (void)memset(&needed_capabilities,0,sizeof(needed_capabilities)); 290 needed_capabilities.can_access_local_variables = 1; 291 needed_capabilities.can_generate_single_step_events = 1; 292 needed_capabilities.can_generate_exception_events = 1; 293 needed_capabilities.can_generate_frame_pop_events = 1; 294 needed_capabilities.can_generate_breakpoint_events = 1; 295 needed_capabilities.can_suspend = 1; 296 needed_capabilities.can_generate_method_entry_events = 1; 297 needed_capabilities.can_generate_method_exit_events = 1; 298 needed_capabilities.can_generate_garbage_collection_events = 1; 299 needed_capabilities.can_maintain_original_method_order = 1; 300 needed_capabilities.can_generate_monitor_events = 1; 301 needed_capabilities.can_tag_objects = 1; 302 303 /* And what potential ones that would be nice to have */ 304 needed_capabilities.can_force_early_return 305 = potential_capabilities.can_force_early_return; 306 needed_capabilities.can_generate_field_modification_events 307 = potential_capabilities.can_generate_field_modification_events; 308 needed_capabilities.can_generate_field_access_events 309 = potential_capabilities.can_generate_field_access_events; 310 needed_capabilities.can_get_bytecodes 311 = potential_capabilities.can_get_bytecodes; 312 needed_capabilities.can_get_synthetic_attribute 313 = potential_capabilities.can_get_synthetic_attribute; 314 needed_capabilities.can_get_owned_monitor_info 315 = potential_capabilities.can_get_owned_monitor_info; 316 needed_capabilities.can_get_current_contended_monitor 317 = potential_capabilities.can_get_current_contended_monitor; 318 needed_capabilities.can_get_monitor_info 319 = potential_capabilities.can_get_monitor_info; 320 needed_capabilities.can_pop_frame 321 = potential_capabilities.can_pop_frame; 322 needed_capabilities.can_redefine_classes 323 = potential_capabilities.can_redefine_classes; 324 needed_capabilities.can_redefine_any_class 325 = potential_capabilities.can_redefine_any_class; 326 needed_capabilities.can_get_owned_monitor_stack_depth_info 327 = potential_capabilities.can_get_owned_monitor_stack_depth_info; 328 needed_capabilities.can_get_constant_pool 329 = potential_capabilities.can_get_constant_pool; 330 { 331 needed_capabilities.can_get_source_debug_extension = 1; 332 needed_capabilities.can_get_source_file_name = 1; 333 needed_capabilities.can_get_line_numbers = 1; 334 needed_capabilities.can_signal_thread 335 = potential_capabilities.can_signal_thread; 336 } 337 338 /* Add the capabilities */ 339 error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities) 340 (gdata->jvmti, &needed_capabilities); 341 if (error != JVMTI_ERROR_NONE) { 342 ERROR_MESSAGE(("JDWP unable to get necessary JVMTI capabilities.")); 343 forceExit(1); /* Kill entire process, no core dump wanted */ 344 } 345 346 /* Initialize event number mapping tables */ 347 eventIndexInit(); 348 349 /* Set the initial JVMTI event notifications */ 350 error = set_event_notification(JVMTI_ENABLE, EI_VM_DEATH); 351 if (error != JVMTI_ERROR_NONE) { 352 return JNI_ERR; 353 } 354 error = set_event_notification(JVMTI_ENABLE, EI_VM_INIT); 355 if (error != JVMTI_ERROR_NONE) { 356 return JNI_ERR; 357 } 358 if (initOnUncaught || (initOnException != NULL)) { 359 error = set_event_notification(JVMTI_ENABLE, EI_EXCEPTION); 360 if (error != JVMTI_ERROR_NONE) { 361 return JNI_ERR; 362 } 363 } 364 365 /* Set callbacks just for 3 functions */ 366 (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks)); 367 gdata->callbacks.VMInit = &cbEarlyVMInit; 368 gdata->callbacks.VMDeath = &cbEarlyVMDeath; 369 gdata->callbacks.Exception = &cbEarlyException; 370 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks) 371 (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks)); 372 if (error != JVMTI_ERROR_NONE) { 373 ERROR_MESSAGE(("JDWP unable to set JVMTI event callbacks: %s(%d)", 374 jvmtiErrorText(error), error)); 375 return JNI_ERR; 376 } 377 378 LOG_MISC(("OnLoad: DONE")); 379 return JNI_OK; 380 } 381 382 JNIEXPORT void JNICALL 383 Agent_OnUnload(JavaVM *vm) 384 { 385 386 gdata->isLoaded = JNI_FALSE; 387 388 /* Cleanup, but make sure VM is alive before using JNI, and 389 * make sure JVMTI environment is ok before deallocating 390 * memory allocated through JVMTI, which all of it is. 391 */ 392 393 /* 394 * Close transport before exit 395 */ 396 if (transport_is_open()) { 397 transport_close(); 398 } 399 } 400 401 /* 402 * Phase 2: Initial events. Phase 2 consists of waiting for the 403 * event that triggers full initialization. Under normal circumstances 404 * (initOnStartup == TRUE) this is the JVMTI_EVENT_VM_INIT event. 405 * Otherwise, we delay initialization until the app throws a 406 * particular exception. The triggering event invokes 407 * the bulk of the initialization, including creation of threads and 408 * monitors, transport setup, and installation of a new event callback which 409 * handles the complete set of events. 410 * 411 * Since the triggering event comes in on an application thread, some of the 412 * initialization is difficult to do here. Specifically, this thread along 413 * with all other app threads may need to be suspended until a debugger 414 * connects. These kinds of tasks are left to the third phase which is 415 * invoked by one of the spawned debugger threads, the event handler. 416 */ 417 418 /* 419 * Wait for a triggering event; then kick off debugger 420 * initialization. A different event callback will be installed by 421 * debugger initialization, and this function will not be called 422 * again. 423 */ 424 425 /* 426 * TO DO: Decide whether we need to protect this code with 427 * a lock. It might be too early to create a monitor safely (?). 428 */ 429 430 static void JNICALL 431 cbEarlyVMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread) 432 { 433 LOG_CB(("cbEarlyVMInit")); 434 if ( gdata->vmDead ) { 435 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at VM_INIT time"); 436 } 437 if (initOnStartup) 438 initialize(env, thread, EI_VM_INIT); 439 vmInitialized = JNI_TRUE; 440 LOG_MISC(("END cbEarlyVMInit")); 441 } 442 443 static void 444 disposeEnvironment(jvmtiEnv *jvmti_env) 445 { 446 jvmtiError error; 447 448 error = JVMTI_FUNC_PTR(jvmti_env,DisposeEnvironment)(jvmti_env); 449 if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY ) 450 error = JVMTI_ERROR_NONE; /* Hack! FIXUP when JVMTI has disposeEnv */ 451 /* What should error return say? */ 452 if (error != JVMTI_ERROR_NONE) { 453 ERROR_MESSAGE(("JDWP unable to dispose of JVMTI environment: %s(%d)", 454 jvmtiErrorText(error), error)); 455 } 456 gdata->jvmti = NULL; 457 } 458 459 static void JNICALL 460 cbEarlyVMDeath(jvmtiEnv *jvmti_env, JNIEnv *env) 461 { 462 LOG_CB(("cbEarlyVMDeath")); 463 if ( gdata->vmDead ) { 464 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM died more than once"); 465 } 466 disposeEnvironment(jvmti_env); 467 gdata->jvmti = NULL; 468 gdata->jvm = NULL; 469 gdata->vmDead = JNI_TRUE; 470 LOG_MISC(("END cbEarlyVMDeath")); 471 } 472 473 static void JNICALL 474 cbEarlyException(jvmtiEnv *jvmti_env, JNIEnv *env, 475 jthread thread, jmethodID method, jlocation location, 476 jobject exception, 477 jmethodID catch_method, jlocation catch_location) 478 { 479 jvmtiError error; 480 jthrowable currentException; 481 482 LOG_CB(("cbEarlyException: thread=%p", thread)); 483 484 if ( gdata->vmDead ) { 485 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initial Exception event"); 486 } 487 if (!vmInitialized) { 488 LOG_MISC(("VM is not initialized yet")); 489 return; 490 } 491 492 /* 493 * We want to preserve any current exception that might get wiped 494 * out during event handling (e.g. JNI calls). We have to rely on 495 * space for the local reference on the current frame because 496 * doing a PushLocalFrame here might itself generate an exception. 497 */ 498 499 currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env); 500 JNI_FUNC_PTR(env,ExceptionClear)(env); 501 502 if (initOnUncaught && catch_method == NULL) { 503 504 LOG_MISC(("Initializing on uncaught exception")); 505 initialize(env, thread, EI_EXCEPTION); 506 507 } else if (initOnException != NULL) { 508 509 jclass clazz; 510 511 /* Get class of exception thrown */ 512 clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, exception); 513 if ( clazz != NULL ) { 514 char *signature = NULL; 515 /* initing on throw, check */ 516 error = classSignature(clazz, &signature, NULL); 517 LOG_MISC(("Checking specific exception: looking for %s, got %s", 518 initOnException, signature)); 519 if ( (error==JVMTI_ERROR_NONE) && 520 (strcmp(signature, initOnException) == 0)) { 521 LOG_MISC(("Initializing on specific exception")); 522 initialize(env, thread, EI_EXCEPTION); 523 } else { 524 error = AGENT_ERROR_INTERNAL; /* Just to cause restore */ 525 } 526 if ( signature != NULL ) { 527 jvmtiDeallocate(signature); 528 } 529 } else { 530 error = AGENT_ERROR_INTERNAL; /* Just to cause restore */ 531 } 532 533 /* If initialize didn't happen, we need to restore things */ 534 if ( error != JVMTI_ERROR_NONE ) { 535 /* 536 * Restore exception state from before callback call 537 */ 538 LOG_MISC(("No initialization, didn't find right exception")); 539 if (currentException != NULL) { 540 JNI_FUNC_PTR(env,Throw)(env, currentException); 541 } else { 542 JNI_FUNC_PTR(env,ExceptionClear)(env); 543 } 544 } 545 546 } 547 548 LOG_MISC(("END cbEarlyException")); 549 550 } 551 552 typedef struct EnumerateArg { 553 jboolean isServer; 554 jdwpError error; 555 jint startCount; 556 } EnumerateArg; 557 558 static jboolean 559 startTransport(void *item, void *arg) 560 { 561 TransportSpec *transport = item; 562 EnumerateArg *enumArg = arg; 563 jdwpError serror; 564 565 LOG_MISC(("Begin startTransport")); 566 serror = transport_startTransport(enumArg->isServer, transport->name, 567 transport->address, transport->timeout); 568 if (serror != JDWP_ERROR(NONE)) { 569 ERROR_MESSAGE(("JDWP Transport %s failed to initialize, %s(%d)", 570 transport->name, jdwpErrorText(serror), serror)); 571 enumArg->error = serror; 572 } else { 573 /* (Don't overwrite any previous error) */ 574 575 enumArg->startCount++; 576 } 577 578 LOG_MISC(("End startTransport")); 579 580 return JNI_TRUE; /* Always continue, even if there was an error */ 581 } 582 583 static void 584 signalInitComplete(void) 585 { 586 /* 587 * Initialization is complete 588 */ 589 LOG_MISC(("signal initialization complete")); 590 debugMonitorEnter(initMonitor); 591 initComplete = JNI_TRUE; 592 debugMonitorNotifyAll(initMonitor); 593 debugMonitorExit(initMonitor); 594 } 595 596 /* 597 * Determine if initialization is complete. 598 */ 599 jboolean 600 debugInit_isInitComplete(void) 601 { 602 return initComplete; 603 } 604 605 /* 606 * Wait for all initialization to complete. 607 */ 608 void 609 debugInit_waitInitComplete(void) 610 { 611 debugMonitorEnter(initMonitor); 612 while (!initComplete) { 613 debugMonitorWait(initMonitor); 614 } 615 debugMonitorExit(initMonitor); 616 } 617 618 /* All process exit() calls come from here */ 619 void 620 forceExit(int exit_code) 621 { 622 /* make sure the transport is closed down before we exit() */ 623 transport_close(); 624 exit(exit_code); 625 } 626 627 /* All JVM fatal error exits lead here (e.g. we need to kill the VM). */ 628 static void 629 jniFatalError(JNIEnv *env, const char *msg, jvmtiError error, int exit_code) 630 { 631 JavaVM *vm; 632 char buf[512]; 633 634 gdata->vmDead = JNI_TRUE; 635 if ( msg==NULL ) 636 msg = "UNKNOWN REASON"; 637 vm = gdata->jvm; 638 if ( env==NULL && vm!=NULL ) { 639 jint rc = (*((*vm)->GetEnv))(vm, (void **)&env, JNI_VERSION_1_2); 640 if (rc != JNI_OK ) { 641 env = NULL; 642 } 643 } 644 if ( error != JVMTI_ERROR_NONE ) { 645 (void)snprintf(buf, sizeof(buf), "JDWP %s, jvmtiError=%s(%d)", 646 msg, jvmtiErrorText(error), error); 647 } else { 648 (void)snprintf(buf, sizeof(buf), "JDWP %s", buf); 649 } 650 if (env != NULL) { 651 (*((*env)->FatalError))(env, buf); 652 } else { 653 /* Should rarely ever reach here, means VM is really dead */ 654 print_message(stderr, "ERROR: JDWP: ", "\n", 655 "Can't call JNI FatalError(NULL, \"%s\")", buf); 656 } 657 forceExit(exit_code); 658 } 659 660 /* 661 * Initialize debugger back end modules 662 */ 663 static void 664 initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei) 665 { 666 jvmtiError error; 667 EnumerateArg arg; 668 jbyte suspendPolicy; 669 670 LOG_MISC(("Begin initialize()")); 671 currentSessionID = 0; 672 initComplete = JNI_FALSE; 673 674 if ( gdata->vmDead ) { 675 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initialize() time"); 676 } 677 678 /* Turn off the initial JVMTI event notifications */ 679 error = set_event_notification(JVMTI_DISABLE, EI_EXCEPTION); 680 if (error != JVMTI_ERROR_NONE) { 681 EXIT_ERROR(error, "unable to disable JVMTI event notification"); 682 } 683 error = set_event_notification(JVMTI_DISABLE, EI_VM_INIT); 684 if (error != JVMTI_ERROR_NONE) { 685 EXIT_ERROR(error, "unable to disable JVMTI event notification"); 686 } 687 error = set_event_notification(JVMTI_DISABLE, EI_VM_DEATH); 688 if (error != JVMTI_ERROR_NONE) { 689 EXIT_ERROR(error, "unable to disable JVMTI event notification"); 690 } 691 692 /* Remove initial event callbacks */ 693 (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks)); 694 error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks) 695 (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks)); 696 if (error != JVMTI_ERROR_NONE) { 697 EXIT_ERROR(error, "unable to clear JVMTI callbacks"); 698 } 699 700 commonRef_initialize(); 701 util_initialize(env); 702 threadControl_initialize(); 703 stepControl_initialize(); 704 invoker_initialize(); 705 debugDispatch_initialize(); 706 classTrack_initialize(env); 707 debugLoop_initialize(); 708 709 initMonitor = debugMonitorCreate("JDWP Initialization Monitor"); 710 711 712 /* 713 * Initialize transports 714 */ 715 arg.isServer = isServer; 716 arg.error = JDWP_ERROR(NONE); 717 arg.startCount = 0; 718 719 transport_initialize(); 720 (void)bagEnumerateOver(transports, startTransport, &arg); 721 722 /* 723 * Exit with an error only if 724 * 1) none of the transports was successfully started, and 725 * 2) the application has not yet started running 726 */ 727 if ((arg.error != JDWP_ERROR(NONE)) && 728 (arg.startCount == 0) && 729 initOnStartup) { 730 EXIT_ERROR(map2jvmtiError(arg.error), "No transports initialized"); 731 } 732 733 eventHandler_initialize(currentSessionID); 734 735 signalInitComplete(); 736 737 transport_waitForConnection(); 738 739 suspendPolicy = suspendOnInit ? JDWP_SUSPEND_POLICY(ALL) 740 : JDWP_SUSPEND_POLICY(NONE); 741 if (triggering_ei == EI_VM_INIT) { 742 LOG_MISC(("triggering_ei == EI_VM_INIT")); 743 eventHelper_reportVMInit(env, currentSessionID, thread, suspendPolicy); 744 } else { 745 /* 746 * TO DO: Kludgy way of getting the triggering event to the 747 * just-attached debugger. It would be nice to make this a little 748 * cleaner. There is also a race condition where other events 749 * can get in the queue (from other not-yet-suspended threads) 750 * before this one does. (Also need to handle allocation error below?) 751 */ 752 EventInfo info; 753 struct bag *initEventBag; 754 LOG_MISC(("triggering_ei != EI_VM_INIT")); 755 initEventBag = eventHelper_createEventBag(); 756 (void)memset(&info,0,sizeof(info)); 757 info.ei = triggering_ei; 758 eventHelper_recordEvent(&info, 0, suspendPolicy, initEventBag); 759 (void)eventHelper_reportEvents(currentSessionID, initEventBag); 760 bagDestroyBag(initEventBag); 761 } 762 763 if ( gdata->vmDead ) { 764 EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead before initialize() completes"); 765 } 766 LOG_MISC(("End initialize()")); 767 } 768 769 /* 770 * Restore all static data to the initialized state so that another 771 * debugger can connect properly later. 772 */ 773 void 774 debugInit_reset(JNIEnv *env) 775 { 776 EnumerateArg arg; 777 778 LOG_MISC(("debugInit_reset() beginning")); 779 780 currentSessionID++; 781 initComplete = JNI_FALSE; 782 783 eventHandler_reset(currentSessionID); 784 transport_reset(); 785 debugDispatch_reset(); 786 invoker_reset(); 787 stepControl_reset(); 788 threadControl_reset(); 789 util_reset(); 790 commonRef_reset(env); 791 classTrack_reset(); 792 793 /* 794 * If this is a server, we are now ready to accept another connection. 795 * If it's a client, then we've cleaned up some (more should be added 796 * later) and we're done. 797 */ 798 if (isServer) { 799 arg.isServer = JNI_TRUE; 800 arg.error = JDWP_ERROR(NONE); 801 arg.startCount = 0; 802 (void)bagEnumerateOver(transports, startTransport, &arg); 803 804 signalInitComplete(); 805 806 transport_waitForConnection(); 807 } else { 808 signalInitComplete(); /* Why? */ 809 } 810 811 LOG_MISC(("debugInit_reset() completed.")); 812 } 813 814 815 char * 816 debugInit_launchOnInit(void) 817 { 818 return launchOnInit; 819 } 820 821 jboolean 822 debugInit_suspendOnInit(void) 823 { 824 return suspendOnInit; 825 } 826 827 /* 828 * code below is shamelessly swiped from hprof. 829 */ 830 831 static int 832 get_tok(char **src, char *buf, int buflen, char sep) 833 { 834 int i; 835 char *p = *src; 836 for (i = 0; i < buflen; i++) { 837 if (p[i] == 0 || p[i] == sep) { 838 buf[i] = 0; 839 if (p[i] == sep) { 840 i++; 841 } 842 *src += i; 843 return i; 844 } 845 buf[i] = p[i]; 846 } 847 /* overflow */ 848 return 0; 849 } 850 851 static void 852 printUsage(void) 853 { 854 TTY_MESSAGE(( 855 " Java Debugger JDWP Agent Library\n" 856 " --------------------------------\n" 857 "\n" 858 " (see http://java.sun.com/products/jpda for more information)\n" 859 "\n" 860 "jdwp usage: java " AGENTLIB "=[help]|[<option>=<value>, ...]\n" 861 "\n" 862 "Option Name and Value Description Default\n" 863 "--------------------- ----------- -------\n" 864 "suspend=y|n wait on startup? y\n" 865 "transport=<name> transport spec none\n" 866 "address=<listen/attach address> transport spec \"\"\n" 867 "server=y|n listen for debugger? n\n" 868 "launch=<command line> run debugger on event none\n" 869 "onthrow=<exception name> debug on throw none\n" 870 "onuncaught=y|n debug on any uncaught? n\n" 871 "timeout=<timeout value> for listen/attach in milliseconds n\n" 872 "mutf8=y|n output modified utf-8 n\n" 873 "quiet=y|n control over terminal messages n\n" 874 "\n" 875 "Obsolete Options\n" 876 "----------------\n" 877 "strict=y|n\n" 878 "stdalloc=y|n\n" 879 "\n" 880 "Examples\n" 881 "--------\n" 882 " - Using sockets connect to a debugger at a specific address:\n" 883 " java " AGENTLIB "=transport=dt_socket,address=localhost:8000 ...\n" 884 " - Using sockets listen for a debugger to attach:\n" 885 " java " AGENTLIB "=transport=dt_socket,server=y,suspend=y ...\n" 886 "\n" 887 "Notes\n" 888 "-----\n" 889 " - A timeout value of 0 (the default) is no timeout.\n" 890 "\n" 891 "Warnings\n" 892 "--------\n" 893 " - The older " XRUN " interface can still be used, but will be removed in\n" 894 " a future release, for example:\n" 895 " java " XDEBUG " " XRUN ":[help]|[<option>=<value>, ...]\n" 896 )); 897 898 #ifdef DEBUG 899 900 TTY_MESSAGE(( 901 "\n" 902 "Debugging Options Description Default\n" 903 "----------------- ----------- -------\n" 904 "pause=y|n pause to debug PID n\n" 905 "coredump=y|n coredump at exit n\n" 906 "errorexit=y|n exit on any error n\n" 907 "logfile=filename name of log file none\n" 908 "logflags=flags log flags (bitmask) none\n" 909 " JVM calls = 0x001\n" 910 " JNI calls = 0x002\n" 911 " JVMTI calls = 0x004\n" 912 " misc events = 0x008\n" 913 " step logs = 0x010\n" 914 " locations = 0x020\n" 915 " callbacks = 0x040\n" 916 " errors = 0x080\n" 917 " everything = 0xfff\n" 918 "debugflags=flags debug flags (bitmask) none\n" 919 " USE_ITERATE_THROUGH_HEAP 0x01\n" 920 "\n" 921 "Environment Variables\n" 922 "---------------------\n" 923 "_JAVA_JDWP_OPTIONS\n" 924 " Options can be added externally via this environment variable.\n" 925 " Anything contained in it will get a comma prepended to it (if needed),\n" 926 " then it will be added to the end of the options supplied via the\n" 927 " " XRUN " or " AGENTLIB " command line option.\n" 928 )); 929 930 #endif 931 932 933 934 } 935 936 static jboolean checkAddress(void *bagItem, void *arg) 937 { 938 TransportSpec *spec = (TransportSpec *)bagItem; 939 if (spec->address == NULL) { 940 ERROR_MESSAGE(("JDWP Non-server transport %s must have a connection " 941 "address specified through the 'address=' option", 942 spec->name)); 943 return JNI_FALSE; 944 } else { 945 return JNI_TRUE; 946 } 947 } 948 949 static char * 950 add_to_options(char *options, char *new_options) 951 { 952 size_t originalLength; 953 char *combinedOptions; 954 955 /* 956 * Allocate enough space for both strings and 957 * comma in between. 958 */ 959 originalLength = strlen(options); 960 combinedOptions = jvmtiAllocate((jint)originalLength + 1 + 961 (jint)strlen(new_options) + 1); 962 if (combinedOptions == NULL) { 963 return NULL; 964 } 965 966 (void)strcpy(combinedOptions, options); 967 (void)strcat(combinedOptions, ","); 968 (void)strcat(combinedOptions, new_options); 969 970 return combinedOptions; 971 } 972 973 static jboolean 974 get_boolean(char **pstr, jboolean *answer) 975 { 976 char buf[80]; 977 *answer = JNI_FALSE; 978 /*LINTED*/ 979 if (get_tok(pstr, buf, (int)sizeof(buf), ',')) { 980 if (strcmp(buf, "y") == 0) { 981 *answer = JNI_TRUE; 982 return JNI_TRUE; 983 } else if (strcmp(buf, "n") == 0) { 984 *answer = JNI_FALSE; 985 return JNI_TRUE; 986 } 987 } 988 return JNI_FALSE; 989 } 990 991 /* atexit() callback */ 992 static void 993 atexit_finish_logging(void) 994 { 995 /* Normal exit(0) (not _exit()) may only reach here */ 996 finish_logging(); /* Only first call matters */ 997 } 998 999 static jboolean 1000 parseOptions(char *options) 1001 { 1002 TransportSpec *currentTransport = NULL; 1003 char *end; 1004 char *current; 1005 int length; 1006 char *str; 1007 char *errmsg; 1008 1009 /* Set defaults */ 1010 gdata->assertOn = DEFAULT_ASSERT_ON; 1011 gdata->assertFatal = DEFAULT_ASSERT_FATAL; 1012 logfile = DEFAULT_LOGFILE; 1013 1014 /* Options being NULL will end up being an error. */ 1015 if (options == NULL) { 1016 options = ""; 1017 } 1018 1019 /* Check for "help" BEFORE we add any environmental settings */ 1020 if ((strcmp(options, "help")) == 0) { 1021 printUsage(); 1022 forceExit(0); /* Kill entire process, no core dump wanted */ 1023 } 1024 1025 /* These buffers are never freed */ 1026 { 1027 char *envOptions; 1028 1029 /* 1030 * Add environmentally specified options. 1031 */ 1032 envOptions = getenv("_JAVA_JDWP_OPTIONS"); 1033 if (envOptions != NULL) { 1034 options = add_to_options(options, envOptions); 1035 if ( options==NULL ) { 1036 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); 1037 } 1038 } 1039 1040 /* 1041 * Allocate a buffer for names derived from option strings. It should 1042 * never be longer than the original options string itself. 1043 * Also keep a copy of the options in gdata->options. 1044 */ 1045 length = (int)strlen(options); 1046 gdata->options = jvmtiAllocate(length + 1); 1047 if (gdata->options == NULL) { 1048 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); 1049 } 1050 (void)strcpy(gdata->options, options); 1051 names = jvmtiAllocate(length + 1); 1052 if (names == NULL) { 1053 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options"); 1054 } 1055 1056 transports = bagCreateBag(sizeof(TransportSpec), 3); 1057 if (transports == NULL) { 1058 EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"transports"); 1059 } 1060 1061 } 1062 1063 current = names; 1064 end = names + length; 1065 str = options; 1066 1067 while (*str) { 1068 char buf[100]; 1069 /*LINTED*/ 1070 if (!get_tok(&str, buf, (int)sizeof(buf), '=')) { 1071 goto syntax_error; 1072 } 1073 if (strcmp(buf, "transport") == 0) { 1074 currentTransport = bagAdd(transports); 1075 /*LINTED*/ 1076 if (!get_tok(&str, current, (int)(end - current), ',')) { 1077 goto syntax_error; 1078 } 1079 currentTransport->name = current; 1080 current += strlen(current) + 1; 1081 } else if (strcmp(buf, "address") == 0) { 1082 if (currentTransport == NULL) { 1083 errmsg = "address specified without transport"; 1084 goto bad_option_with_errmsg; 1085 } 1086 /*LINTED*/ 1087 if (!get_tok(&str, current, (int)(end - current), ',')) { 1088 goto syntax_error; 1089 } 1090 currentTransport->address = current; 1091 current += strlen(current) + 1; 1092 } else if (strcmp(buf, "timeout") == 0) { 1093 if (currentTransport == NULL) { 1094 errmsg = "timeout specified without transport"; 1095 goto bad_option_with_errmsg; 1096 } 1097 /*LINTED*/ 1098 if (!get_tok(&str, current, (int)(end - current), ',')) { 1099 goto syntax_error; 1100 } 1101 currentTransport->timeout = atol(current); 1102 current += strlen(current) + 1; 1103 } else if (strcmp(buf, "launch") == 0) { 1104 /*LINTED*/ 1105 if (!get_tok(&str, current, (int)(end - current), ',')) { 1106 goto syntax_error; 1107 } 1108 launchOnInit = current; 1109 current += strlen(current) + 1; 1110 } else if (strcmp(buf, "onthrow") == 0) { 1111 /* Read class name and convert in place to a signature */ 1112 *current = 'L'; 1113 /*LINTED*/ 1114 if (!get_tok(&str, current + 1, (int)(end - current - 1), ',')) { 1115 goto syntax_error; 1116 } 1117 initOnException = current; 1118 while (*current != '\0') { 1119 if (*current == '.') { 1120 *current = '/'; 1121 } 1122 current++; 1123 } 1124 *current++ = ';'; 1125 *current++ = '\0'; 1126 } else if (strcmp(buf, "assert") == 0) { 1127 /*LINTED*/ 1128 if (!get_tok(&str, current, (int)(end - current), ',')) { 1129 goto syntax_error; 1130 } 1131 if (strcmp(current, "y") == 0) { 1132 gdata->assertOn = JNI_TRUE; 1133 gdata->assertFatal = JNI_FALSE; 1134 } else if (strcmp(current, "fatal") == 0) { 1135 gdata->assertOn = JNI_TRUE; 1136 gdata->assertFatal = JNI_TRUE; 1137 } else if (strcmp(current, "n") == 0) { 1138 gdata->assertOn = JNI_FALSE; 1139 gdata->assertFatal = JNI_FALSE; 1140 } else { 1141 goto syntax_error; 1142 } 1143 current += strlen(current) + 1; 1144 } else if (strcmp(buf, "pause") == 0) { 1145 if ( !get_boolean(&str, &dopause) ) { 1146 goto syntax_error; 1147 } 1148 if ( dopause ) { 1149 do_pause(); 1150 } 1151 } else if (strcmp(buf, "coredump") == 0) { 1152 if ( !get_boolean(&str, &docoredump) ) { 1153 goto syntax_error; 1154 } 1155 } else if (strcmp(buf, "errorexit") == 0) { 1156 if ( !get_boolean(&str, &(gdata->doerrorexit)) ) { 1157 goto syntax_error; 1158 } 1159 } else if (strcmp(buf, "exitpause") == 0) { 1160 errmsg = "The exitpause option removed, use -XX:OnError"; 1161 goto bad_option_with_errmsg; 1162 } else if (strcmp(buf, "precrash") == 0) { 1163 errmsg = "The precrash option removed, use -XX:OnError"; 1164 goto bad_option_with_errmsg; 1165 } else if (strcmp(buf, "logfile") == 0) { 1166 /*LINTED*/ 1167 if (!get_tok(&str, current, (int)(end - current), ',')) { 1168 goto syntax_error; 1169 } 1170 logfile = current; 1171 current += strlen(current) + 1; 1172 } else if (strcmp(buf, "logflags") == 0) { 1173 /*LINTED*/ 1174 if (!get_tok(&str, current, (int)(end - current), ',')) { 1175 goto syntax_error; 1176 } 1177 /*LINTED*/ 1178 logflags = (unsigned)strtol(current, NULL, 0); 1179 } else if (strcmp(buf, "debugflags") == 0) { 1180 /*LINTED*/ 1181 if (!get_tok(&str, current, (int)(end - current), ',')) { 1182 goto syntax_error; 1183 } 1184 /*LINTED*/ 1185 gdata->debugflags = (unsigned)strtol(current, NULL, 0); 1186 } else if ( strcmp(buf, "suspend")==0 ) { 1187 if ( !get_boolean(&str, &suspendOnInit) ) { 1188 goto syntax_error; 1189 } 1190 } else if ( strcmp(buf, "server")==0 ) { 1191 if ( !get_boolean(&str, &isServer) ) { 1192 goto syntax_error; 1193 } 1194 } else if ( strcmp(buf, "strict")==0 ) { /* Obsolete, but accept it */ 1195 if ( !get_boolean(&str, &isStrict) ) { 1196 goto syntax_error; 1197 } 1198 } else if ( strcmp(buf, "quiet")==0 ) { 1199 if ( !get_boolean(&str, &(gdata->quiet)) ) { 1200 goto syntax_error; 1201 } 1202 } else if ( strcmp(buf, "onuncaught")==0 ) { 1203 if ( !get_boolean(&str, &initOnUncaught) ) { 1204 goto syntax_error; 1205 } 1206 } else if ( strcmp(buf, "mutf8")==0 ) { 1207 if ( !get_boolean(&str, &(gdata->modifiedUtf8)) ) { 1208 goto syntax_error; 1209 } 1210 } else if ( strcmp(buf, "stdalloc")==0 ) { /* Obsolete, but accept it */ 1211 if ( !get_boolean(&str, &useStandardAlloc) ) { 1212 goto syntax_error; 1213 } 1214 } else { 1215 goto syntax_error; 1216 } 1217 } 1218 1219 /* Setup logging now */ 1220 if ( logfile!=NULL ) { 1221 setup_logging(logfile, logflags); 1222 (void)atexit(&atexit_finish_logging); 1223 } 1224 1225 if (bagSize(transports) == 0) { 1226 errmsg = "no transport specified"; 1227 goto bad_option_with_errmsg; 1228 } 1229 1230 /* 1231 * TO DO: Remove when multiple transports are allowed. (replace with 1232 * check below. 1233 */ 1234 if (bagSize(transports) > 1) { 1235 errmsg = "multiple transports are not supported in this release"; 1236 goto bad_option_with_errmsg; 1237 } 1238 1239 1240 if (!isServer) { 1241 jboolean specified = bagEnumerateOver(transports, checkAddress, NULL); 1242 if (!specified) { 1243 /* message already printed */ 1244 goto bad_option_no_msg; 1245 } 1246 } 1247 1248 /* 1249 * The user has selected to wait for an exception before init happens 1250 */ 1251 if ((initOnException != NULL) || (initOnUncaught)) { 1252 initOnStartup = JNI_FALSE; 1253 1254 if (launchOnInit == NULL) { 1255 /* 1256 * These rely on the launch=/usr/bin/foo 1257 * suboption, so it is an error if user did not 1258 * provide one. 1259 */ 1260 errmsg = "Specify launch=<command line> when using onthrow or onuncaught suboption"; 1261 goto bad_option_with_errmsg; 1262 } 1263 } 1264 1265 return JNI_TRUE; 1266 1267 syntax_error: 1268 ERROR_MESSAGE(("JDWP option syntax error: %s=%s", AGENTLIB, options)); 1269 return JNI_FALSE; 1270 1271 bad_option_with_errmsg: 1272 ERROR_MESSAGE(("JDWP %s: %s=%s", errmsg, AGENTLIB, options)); 1273 return JNI_FALSE; 1274 1275 bad_option_no_msg: 1276 ERROR_MESSAGE(("JDWP %s: %s=%s", "invalid option", AGENTLIB, options)); 1277 return JNI_FALSE; 1278 } 1279 1280 /* All normal exit doors lead here */ 1281 void 1282 debugInit_exit(jvmtiError error, const char *msg) 1283 { 1284 enum exit_codes { EXIT_NO_ERRORS = 0, EXIT_JVMTI_ERROR = 1, EXIT_TRANSPORT_ERROR = 2 }; 1285 1286 // Prepare to exit. Log error and finish logging 1287 LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error, 1288 ((msg == NULL) ? "" : msg))); 1289 1290 // coredump requested by command line. Keep JVMTI data dirty 1291 if (error != JVMTI_ERROR_NONE && docoredump) { 1292 LOG_MISC(("Dumping core as requested by command line")); 1293 finish_logging(); 1294 abort(); 1295 } 1296 1297 finish_logging(); 1298 1299 // Cleanup the JVMTI if we have one 1300 if (gdata != NULL) { 1301 gdata->vmDead = JNI_TRUE; 1302 if (gdata->jvmti != NULL) { 1303 // Dispose of jvmti (gdata->jvmti becomes NULL) 1304 disposeEnvironment(gdata->jvmti); 1305 } 1306 } 1307 1308 // We are here with no errors. Kill entire process and exit with zero exit code 1309 if (error == JVMTI_ERROR_NONE) { 1310 forceExit(EXIT_NO_ERRORS); 1311 return; 1312 } 1313 1314 // No transport initilized. 1315 // As we don't have any details here exiting with separate exit code 1316 if (error == AGENT_ERROR_TRANSPORT_INIT) { 1317 forceExit(EXIT_TRANSPORT_ERROR); 1318 return; 1319 } 1320 1321 // We have JVMTI error. Call hotspot jni_FatalError handler 1322 jniFatalError(NULL, msg, error, EXIT_JVMTI_ERROR); 1323 1324 // hotspot calls os:abort() so we should never reach code below, 1325 // but guard against possible hotspot changes 1326 1327 // Last chance to die, this kills the entire process. 1328 forceExit(EXIT_JVMTI_ERROR); 1329 }