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 }