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