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