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