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