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