/*
 * Copyright 1998-2005 Sun Microsystems, Inc.  All Rights Reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Sun designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Sun in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
 * CA 95054 USA or visit www.sun.com if you need additional information or
 * have any questions.
 */

#include <ctype.h>

#include "util.h"
#include "commonRef.h"
#include "debugDispatch.h"
#include "eventHandler.h"
#include "eventHelper.h"
#include "threadControl.h"
#include "stepControl.h"
#include "transport.h"
#include "classTrack.h"
#include "debugLoop.h"
#include "bag.h"
#include "invoker.h"

/* How the options get to OnLoad: */
#define XDEBUG "-Xdebug"
#define XRUN "-Xrunjdwp"
#define AGENTLIB "-agentlib:jdwp"

/* Debug version defaults */
#ifdef DEBUG
    #define DEFAULT_ASSERT_ON           JNI_TRUE
    #define DEFAULT_ASSERT_FATAL        JNI_TRUE
    #define DEFAULT_LOGFILE             "jdwp.log"
#else
    #define DEFAULT_ASSERT_ON           JNI_FALSE
    #define DEFAULT_ASSERT_FATAL        JNI_FALSE
    #define DEFAULT_LOGFILE             NULL
#endif

static jboolean vmInitialized;
static jrawMonitorID initMonitor;
static jboolean initComplete;
static jbyte currentSessionID;

/*
 * Options set through the OnLoad options string. All of these values
 * are set once at VM startup and never reset.
 */
static jboolean isServer = JNI_FALSE;     /* Listens for connecting debuggers? */
static jboolean isStrict = JNI_FALSE;     /* Unused */
static jboolean useStandardAlloc = JNI_FALSE;  /* Use standard malloc/free? */
static struct bag *transports;            /* of TransportSpec */

static jboolean initOnStartup = JNI_TRUE;   /* init immediately */
static char *initOnException = NULL;        /* init when this exception thrown */
static jboolean initOnUncaught = JNI_FALSE; /* init when uncaught exc thrown */

static char *launchOnInit = NULL;           /* launch this app during init */
static jboolean suspendOnInit = JNI_TRUE;   /* suspend all app threads after init */
static jboolean dopause = JNI_FALSE;        /* pause for debugger attach */
static jboolean docoredump = JNI_FALSE;     /* core dump on exit */
static char *logfile = NULL;                /* Name of logfile (if logging) */
static unsigned logflags = 0;               /* Log flags */

static char *names;                         /* strings derived from OnLoad options */

/*
 * Elements of the transports bag
 */
typedef struct TransportSpec {
    char *name;
    char *address;
    long timeout;
} TransportSpec;

/*
 * Forward Refs
 */
static void JNICALL cbEarlyVMInit(jvmtiEnv*, JNIEnv *, jthread);
static void JNICALL cbEarlyVMDeath(jvmtiEnv*, JNIEnv *);
static void JNICALL cbEarlyException(jvmtiEnv*, JNIEnv *,
            jthread, jmethodID, jlocation, jobject, jmethodID, jlocation);

static void initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei);
static jboolean parseOptions(char *str);

/*
 * Phase 1: Initial load.
 *
 * OnLoad is called by the VM immediately after the back-end
 * library is loaded. We can do very little in this function since
 * the VM has not completed initialization. So, we parse the JDWP
 * options and set up a simple initial event callbacks for JVMTI events.
 * When a triggering event occurs, that callback will begin debugger initialization.
 */

/* Get a static area to hold the Global Data */
static BackendGlobalData *
get_gdata(void)
{
    static BackendGlobalData s;
    (void)memset(&s, 0, sizeof(BackendGlobalData));
    return &s;
}

static jvmtiError
set_event_notification(jvmtiEventMode mode, EventIndex ei)
{
    jvmtiError error;
    error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventNotificationMode)
                (gdata->jvmti, mode, eventIndex2jvmti(ei), NULL);
    if (error != JVMTI_ERROR_NONE) {
        ERROR_MESSAGE(("JDWP unable to configure initial JVMTI event %s: %s(%d)",
                    eventText(ei), jvmtiErrorText(error), error));
    }
    return error;
}

/* Logic to determine JVMTI version compatibility */
static jboolean
compatible_versions(jint major_runtime,     jint minor_runtime,
                    jint major_compiletime, jint minor_compiletime)
{
#if 1 /* FIXUP: We allow version 0 to be compatible with anything */
    /* Special check for FCS of 1.0. */
    if ( major_runtime == 0 || major_compiletime == 0 ) {
        return JNI_TRUE;
    }
#endif
    /* Runtime major version must match. */
    if ( major_runtime != major_compiletime ) {
        return JNI_FALSE;
    }
    /* Runtime minor version must be >= the version compiled with. */
    if ( minor_runtime < minor_compiletime ) {
        return JNI_FALSE;
    }
    /* Assumed compatible */
    return JNI_TRUE;
}

/* OnLoad startup:
 *   Returning JNI_ERR will cause the java_g VM to core dump, be careful.
 */
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
    jvmtiError error;
    jvmtiCapabilities needed_capabilities;
    jvmtiCapabilities potential_capabilities;
    jint              jvmtiCompileTimeMajorVersion;
    jint              jvmtiCompileTimeMinorVersion;
    jint              jvmtiCompileTimeMicroVersion;

    /* See if it's already loaded */
    if ( gdata!=NULL && gdata->isLoaded==JNI_TRUE ) {
        ERROR_MESSAGE(("Cannot load this JVM TI agent twice, check your java command line for duplicate jdwp options."));
        return JNI_ERR;
    }

    /* If gdata is defined and the VM died, why are we here? */
    if ( gdata!=NULL && gdata->vmDead ) {
        ERROR_MESSAGE(("JDWP unable to load, VM died"));
        return JNI_ERR;
    }

    /* Get global data area */
    gdata = get_gdata();
    if (gdata == NULL) {
        ERROR_MESSAGE(("JDWP unable to allocate memory"));
        return JNI_ERR;
    }
    gdata->isLoaded = JNI_TRUE;

    /* Start filling in gdata */
    gdata->jvm = vm;
    vmInitialized = JNI_FALSE;
    gdata->vmDead = JNI_FALSE;

    /* Npt and Utf function init */
    NPT_INITIALIZE(&(gdata->npt), NPT_VERSION, NULL);
    if (gdata->npt == NULL) {
        ERROR_MESSAGE(("JDWP: unable to initialize NPT library"));
        return JNI_ERR;
    }
    gdata->npt->utf = (gdata->npt->utfInitialize)(NULL);
    if (gdata->npt->utf == NULL) {
        ERROR_MESSAGE(("JDWP: UTF function initialization failed"));
        return JNI_ERR;
    }

    /* Get the JVMTI Env, IMPORTANT: Do this first! For jvmtiAllocate(). */
    error = JVM_FUNC_PTR(vm,GetEnv)
                (vm, (void **)&(gdata->jvmti), JVMTI_VERSION_1);
    if (error != JNI_OK) {
        ERROR_MESSAGE(("JDWP unable to access JVMTI Version 1 (0x%x),"
                         " is your J2SE a 1.5 or newer version?"
                         " JNIEnv's GetEnv() returned %d",
                         JVMTI_VERSION_1, error));
        forceExit(1); /* Kill entire process, no core dump */
    }

    /* Check to make sure the version of jvmti.h we compiled with
     *      matches the runtime version we are using.
     */
    jvmtiCompileTimeMajorVersion  = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MAJOR )
                                        >> JVMTI_VERSION_SHIFT_MAJOR;
    jvmtiCompileTimeMinorVersion  = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MINOR )
                                        >> JVMTI_VERSION_SHIFT_MINOR;
    jvmtiCompileTimeMicroVersion  = ( JVMTI_VERSION & JVMTI_VERSION_MASK_MICRO )
                                        >> JVMTI_VERSION_SHIFT_MICRO;

    /* Check for compatibility */
    if ( !compatible_versions(jvmtiMajorVersion(), jvmtiMinorVersion(),
                jvmtiCompileTimeMajorVersion, jvmtiCompileTimeMinorVersion) ) {

        ERROR_MESSAGE(("This jdwp native library will not work with this VM's "
                       "version of JVMTI (%d.%d.%d), it needs JVMTI %d.%d[.%d].",
                       jvmtiMajorVersion(),
                       jvmtiMinorVersion(),
                       jvmtiMicroVersion(),
                       jvmtiCompileTimeMajorVersion,
                       jvmtiCompileTimeMinorVersion,
                       jvmtiCompileTimeMicroVersion));

        /* Do not let VM get a fatal error, we don't want a core dump here. */
        forceExit(1); /* Kill entire process, no core dump wanted */
    }

    /* Parse input options */
    if (!parseOptions(options)) {
        /* No message necessary, should have been printed out already */
        /* Do not let VM get a fatal error, we don't want a core dump here. */
        forceExit(1); /* Kill entire process, no core dump wanted */
    }

    LOG_MISC(("Onload: %s", options));

    /* Get potential capabilities */
    (void)memset(&potential_capabilities,0,sizeof(potential_capabilities));
    error = JVMTI_FUNC_PTR(gdata->jvmti,GetPotentialCapabilities)
                (gdata->jvmti, &potential_capabilities);
    if (error != JVMTI_ERROR_NONE) {
        ERROR_MESSAGE(("JDWP unable to get potential JVMTI capabilities: %s(%d)",
                        jvmtiErrorText(error), error));
        return JNI_ERR;
    }

    /* Fill in ones that we must have */
    (void)memset(&needed_capabilities,0,sizeof(needed_capabilities));
    needed_capabilities.can_access_local_variables              = 1;
    needed_capabilities.can_generate_single_step_events         = 1;
    needed_capabilities.can_generate_exception_events           = 1;
    needed_capabilities.can_generate_frame_pop_events           = 1;
    needed_capabilities.can_generate_breakpoint_events          = 1;
    needed_capabilities.can_suspend                             = 1;
    needed_capabilities.can_generate_method_entry_events        = 1;
    needed_capabilities.can_generate_method_exit_events         = 1;
    needed_capabilities.can_generate_garbage_collection_events  = 1;
    needed_capabilities.can_maintain_original_method_order      = 1;
    needed_capabilities.can_generate_monitor_events             = 1;
    needed_capabilities.can_tag_objects                         = 1;

    /* And what potential ones that would be nice to have */
    needed_capabilities.can_force_early_return
                = potential_capabilities.can_force_early_return;
    needed_capabilities.can_generate_field_modification_events
                = potential_capabilities.can_generate_field_modification_events;
    needed_capabilities.can_generate_field_access_events
                = potential_capabilities.can_generate_field_access_events;
    needed_capabilities.can_get_bytecodes
                = potential_capabilities.can_get_bytecodes;
    needed_capabilities.can_get_synthetic_attribute
                = potential_capabilities.can_get_synthetic_attribute;
    needed_capabilities.can_get_owned_monitor_info
                = potential_capabilities.can_get_owned_monitor_info;
    needed_capabilities.can_get_current_contended_monitor
                = potential_capabilities.can_get_current_contended_monitor;
    needed_capabilities.can_get_monitor_info
                = potential_capabilities.can_get_monitor_info;
    needed_capabilities.can_pop_frame
                = potential_capabilities.can_pop_frame;
    needed_capabilities.can_redefine_classes
                = potential_capabilities.can_redefine_classes;
    needed_capabilities.can_redefine_any_class
                = potential_capabilities.can_redefine_any_class;
    needed_capabilities.can_get_owned_monitor_stack_depth_info
        = potential_capabilities.can_get_owned_monitor_stack_depth_info;
    needed_capabilities.can_get_constant_pool
                = potential_capabilities.can_get_constant_pool;
    {
        needed_capabilities.can_get_source_debug_extension      = 1;
        needed_capabilities.can_get_source_file_name            = 1;
        needed_capabilities.can_get_line_numbers                = 1;
        needed_capabilities.can_signal_thread
                = potential_capabilities.can_signal_thread;
    }

    /* Add the capabilities */
    error = JVMTI_FUNC_PTR(gdata->jvmti,AddCapabilities)
                (gdata->jvmti, &needed_capabilities);
    if (error != JVMTI_ERROR_NONE) {
        ERROR_MESSAGE(("JDWP unable to get necessary JVMTI capabilities."));
        forceExit(1); /* Kill entire process, no core dump wanted */
    }

    /* Initialize event number mapping tables */
    eventIndexInit();

    /* Set the initial JVMTI event notifications */
    error = set_event_notification(JVMTI_ENABLE, EI_VM_DEATH);
    if (error != JVMTI_ERROR_NONE) {
        return JNI_ERR;
    }
    error = set_event_notification(JVMTI_ENABLE, EI_VM_INIT);
    if (error != JVMTI_ERROR_NONE) {
        return JNI_ERR;
    }
    if (initOnUncaught || (initOnException != NULL)) {
        error = set_event_notification(JVMTI_ENABLE, EI_EXCEPTION);
        if (error != JVMTI_ERROR_NONE) {
            return JNI_ERR;
        }
    }

    /* Set callbacks just for 3 functions */
    (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
    gdata->callbacks.VMInit             = &cbEarlyVMInit;
    gdata->callbacks.VMDeath            = &cbEarlyVMDeath;
    gdata->callbacks.Exception  = &cbEarlyException;
    error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
                (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
    if (error != JVMTI_ERROR_NONE) {
        ERROR_MESSAGE(("JDWP unable to set JVMTI event callbacks: %s(%d)",
                        jvmtiErrorText(error), error));
        return JNI_ERR;
    }

    LOG_MISC(("OnLoad: DONE"));
    return JNI_OK;
}

JNIEXPORT void JNICALL
Agent_OnUnload(JavaVM *vm)
{

    gdata->isLoaded = JNI_FALSE;

    /* Cleanup, but make sure VM is alive before using JNI, and
     *   make sure JVMTI environment is ok before deallocating
     *   memory allocated through JVMTI, which all of it is.
     */

    /*
     * Close transport before exit
     */
    if (transport_is_open()) {
        transport_close();
    }
}

/*
 * Phase 2: Initial events. Phase 2 consists of waiting for the
 * event that triggers full initialization. Under normal circumstances
 * (initOnStartup == TRUE) this is the JVMTI_EVENT_VM_INIT event.
 * Otherwise, we delay initialization until the app throws a
 * particular exception. The triggering event invokes
 * the bulk of the initialization, including creation of threads and
 * monitors, transport setup, and installation of a new event callback which
 * handles the complete set of events.
 *
 * Since the triggering event comes in on an application thread, some of the
 * initialization is difficult to do here. Specifically, this thread along
 * with all other app threads may need to be suspended until a debugger
 * connects. These kinds of tasks are left to the third phase which is
 * invoked by one of the spawned debugger threads, the event handler.
 */

/*
 * Wait for a triggering event; then kick off debugger
 * initialization. A different event callback will be installed by
 * debugger initialization, and this function will not be called
 * again.
 */

    /*
     * TO DO: Decide whether we need to protect this code with
     * a lock. It might be too early to create a monitor safely (?).
     */

static void JNICALL
cbEarlyVMInit(jvmtiEnv *jvmti_env, JNIEnv *env, jthread thread)
{
    LOG_CB(("cbEarlyVMInit"));
    if ( gdata->vmDead ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at VM_INIT time");
    }
    if (initOnStartup)
        initialize(env, thread, EI_VM_INIT);
    vmInitialized = JNI_TRUE;
    LOG_MISC(("END cbEarlyVMInit"));
}

static void
disposeEnvironment(jvmtiEnv *jvmti_env)
{
    jvmtiError error;

    error = JVMTI_FUNC_PTR(jvmti_env,DisposeEnvironment)(jvmti_env);
    if ( error == JVMTI_ERROR_MUST_POSSESS_CAPABILITY )
        error = JVMTI_ERROR_NONE;  /* Hack!  FIXUP when JVMTI has disposeEnv */
    /* What should error return say? */
    if (error != JVMTI_ERROR_NONE) {
        ERROR_MESSAGE(("JDWP unable to dispose of JVMTI environment: %s(%d)",
                        jvmtiErrorText(error), error));
    }
    gdata->jvmti = NULL;
}

static void JNICALL
cbEarlyVMDeath(jvmtiEnv *jvmti_env, JNIEnv *env)
{
    LOG_CB(("cbEarlyVMDeath"));
    if ( gdata->vmDead ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM died more than once");
    }
    disposeEnvironment(jvmti_env);
    gdata->jvmti = NULL;
    gdata->jvm = NULL;
    gdata->vmDead = JNI_TRUE;
    LOG_MISC(("END cbEarlyVMDeath"));
}

static void JNICALL
cbEarlyException(jvmtiEnv *jvmti_env, JNIEnv *env,
        jthread thread, jmethodID method, jlocation location,
        jobject exception,
        jmethodID catch_method, jlocation catch_location)
{
    jvmtiError error;
    jthrowable currentException;

    LOG_CB(("cbEarlyException: thread=%p", thread));

    if ( gdata->vmDead ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initial Exception event");
    }
    if (!vmInitialized)  {
        LOG_MISC(("VM is not initialized yet"));
        return;
    }

    /*
     * We want to preserve any current exception that might get wiped
     * out during event handling (e.g. JNI calls). We have to rely on
     * space for the local reference on the current frame because
     * doing a PushLocalFrame here might itself generate an exception.
     */

    currentException = JNI_FUNC_PTR(env,ExceptionOccurred)(env);
    JNI_FUNC_PTR(env,ExceptionClear)(env);

    if (initOnUncaught && catch_method == NULL) {

        LOG_MISC(("Initializing on uncaught exception"));
        initialize(env, thread, EI_EXCEPTION);

    } else if (initOnException != NULL) {

        jclass clazz;

        /* Get class of exception thrown */
        clazz = JNI_FUNC_PTR(env,GetObjectClass)(env, exception);
        if ( clazz != NULL ) {
            char *signature = NULL;
            /* initing on throw, check */
            error = classSignature(clazz, &signature, NULL);
            LOG_MISC(("Checking specific exception: looking for %s, got %s",
                        initOnException, signature));
            if ( (error==JVMTI_ERROR_NONE) &&
                (strcmp(signature, initOnException) == 0)) {
                LOG_MISC(("Initializing on specific exception"));
                initialize(env, thread, EI_EXCEPTION);
            } else {
                error = AGENT_ERROR_INTERNAL; /* Just to cause restore */
            }
            if ( signature != NULL ) {
                jvmtiDeallocate(signature);
            }
        } else {
            error = AGENT_ERROR_INTERNAL; /* Just to cause restore */
        }

        /* If initialize didn't happen, we need to restore things */
        if ( error != JVMTI_ERROR_NONE ) {
            /*
             * Restore exception state from before callback call
             */
            LOG_MISC(("No initialization, didn't find right exception"));
            if (currentException != NULL) {
                JNI_FUNC_PTR(env,Throw)(env, currentException);
            } else {
                JNI_FUNC_PTR(env,ExceptionClear)(env);
            }
        }

    }

    LOG_MISC(("END cbEarlyException"));

}

typedef struct EnumerateArg {
    jboolean isServer;
    jdwpError error;
    jint startCount;
} EnumerateArg;

static jboolean
startTransport(void *item, void *arg)
{
    TransportSpec *transport = item;
    EnumerateArg *enumArg = arg;
    jdwpError serror;

    LOG_MISC(("Begin startTransport"));
    serror = transport_startTransport(enumArg->isServer, transport->name,
                                     transport->address, transport->timeout);
    if (serror != JDWP_ERROR(NONE)) {
        ERROR_MESSAGE(("JDWP Transport %s failed to initialize, %s(%d)",
                transport->name, jdwpErrorText(serror), serror));
        enumArg->error = serror;
    } else {
        /* (Don't overwrite any previous error) */

        enumArg->startCount++;
    }

    LOG_MISC(("End startTransport"));

    return JNI_TRUE;   /* Always continue, even if there was an error */
}

static void
signalInitComplete(void)
{
    /*
     * Initialization is complete
     */
    LOG_MISC(("signal initialization complete"));
    debugMonitorEnter(initMonitor);
    initComplete = JNI_TRUE;
    debugMonitorNotifyAll(initMonitor);
    debugMonitorExit(initMonitor);
}

/*
 * Determine if  initialization is complete.
 */
jboolean
debugInit_isInitComplete(void)
{
    return initComplete;
}

/*
 * Wait for all initialization to complete.
 */
void
debugInit_waitInitComplete(void)
{
    debugMonitorEnter(initMonitor);
    while (!initComplete) {
        debugMonitorWait(initMonitor);
    }
    debugMonitorExit(initMonitor);
}

/* All process exit() calls come from here */
void
forceExit(int exit_code)
{
    /* make sure the transport is closed down before we exit() */
    transport_close();
    exit(exit_code);
}

/* All JVM fatal error exits lead here (e.g. we need to kill the VM). */
static void
jniFatalError(JNIEnv *env, const char *msg, jvmtiError error, int exit_code)
{
    JavaVM *vm;
    char buf[512];

    gdata->vmDead = JNI_TRUE;
    if ( msg==NULL )
        msg = "UNKNOWN REASON";
    vm = gdata->jvm;
    if ( env==NULL && vm!=NULL ) {
        jint rc = (*((*vm)->GetEnv))(vm, (void **)&env, JNI_VERSION_1_2);
        if (rc != JNI_OK ) {
            env = NULL;
        }
    }
    if ( error != JVMTI_ERROR_NONE ) {
        (void)snprintf(buf, sizeof(buf), "JDWP %s, jvmtiError=%s(%d)",
                    msg, jvmtiErrorText(error), error);
    } else {
        (void)snprintf(buf, sizeof(buf), "JDWP %s", buf);
    }
    if (env != NULL) {
        (*((*env)->FatalError))(env, buf);
    } else {
        /* Should rarely ever reach here, means VM is really dead */
        print_message(stderr, "ERROR: JDWP: ", "\n",
                "Can't call JNI FatalError(NULL, \"%s\")", buf);
    }
    forceExit(exit_code);
}

/*
 * Initialize debugger back end modules
 */
static void
initialize(JNIEnv *env, jthread thread, EventIndex triggering_ei)
{
    jvmtiError error;
    EnumerateArg arg;
    jbyte suspendPolicy;

    LOG_MISC(("Begin initialize()"));
    currentSessionID = 0;
    initComplete = JNI_FALSE;

    if ( gdata->vmDead ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead at initialize() time");
    }

    /* Turn off the initial JVMTI event notifications */
    error = set_event_notification(JVMTI_DISABLE, EI_EXCEPTION);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "unable to disable JVMTI event notification");
    }
    error = set_event_notification(JVMTI_DISABLE, EI_VM_INIT);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "unable to disable JVMTI event notification");
    }
    error = set_event_notification(JVMTI_DISABLE, EI_VM_DEATH);
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "unable to disable JVMTI event notification");
    }

    /* Remove initial event callbacks */
    (void)memset(&(gdata->callbacks),0,sizeof(gdata->callbacks));
    error = JVMTI_FUNC_PTR(gdata->jvmti,SetEventCallbacks)
                (gdata->jvmti, &(gdata->callbacks), sizeof(gdata->callbacks));
    if (error != JVMTI_ERROR_NONE) {
        EXIT_ERROR(error, "unable to clear JVMTI callbacks");
    }

    commonRef_initialize();
    util_initialize(env);
    threadControl_initialize();
    stepControl_initialize();
    invoker_initialize();
    debugDispatch_initialize();
    classTrack_initialize(env);
    debugLoop_initialize();

    initMonitor = debugMonitorCreate("JDWP Initialization Monitor");


    /*
     * Initialize transports
     */
    arg.isServer = isServer;
    arg.error = JDWP_ERROR(NONE);
    arg.startCount = 0;

    transport_initialize();
    (void)bagEnumerateOver(transports, startTransport, &arg);

    /*
     * Exit with an error only if
     * 1) none of the transports was successfully started, and
     * 2) the application has not yet started running
     */
    if ((arg.error != JDWP_ERROR(NONE)) &&
        (arg.startCount == 0) &&
        initOnStartup) {
        EXIT_ERROR(map2jvmtiError(arg.error), "No transports initialized");
    }

    eventHandler_initialize(currentSessionID);

    signalInitComplete();

    transport_waitForConnection();

    suspendPolicy = suspendOnInit ? JDWP_SUSPEND_POLICY(ALL)
                                  : JDWP_SUSPEND_POLICY(NONE);
    if (triggering_ei == EI_VM_INIT) {
        LOG_MISC(("triggering_ei == EI_VM_INIT"));
        eventHelper_reportVMInit(env, currentSessionID, thread, suspendPolicy);
    } else {
        /*
         * TO DO: Kludgy way of getting the triggering event to the
         * just-attached debugger. It would be nice to make this a little
         * cleaner. There is also a race condition where other events
         * can get in the queue (from other not-yet-suspended threads)
         * before this one does. (Also need to handle allocation error below?)
         */
        EventInfo info;
        struct bag *initEventBag;
        LOG_MISC(("triggering_ei != EI_VM_INIT"));
        initEventBag = eventHelper_createEventBag();
        (void)memset(&info,0,sizeof(info));
        info.ei = triggering_ei;
        eventHelper_recordEvent(&info, 0, suspendPolicy, initEventBag);
        (void)eventHelper_reportEvents(currentSessionID, initEventBag);
        bagDestroyBag(initEventBag);
    }

    if ( gdata->vmDead ) {
        EXIT_ERROR(AGENT_ERROR_INTERNAL,"VM dead before initialize() completes");
    }
    LOG_MISC(("End initialize()"));
}

/*
 * Restore all static data to the initialized state so that another
 * debugger can connect properly later.
 */
void
debugInit_reset(JNIEnv *env)
{
    EnumerateArg arg;

    LOG_MISC(("debugInit_reset() beginning"));

    currentSessionID++;
    initComplete = JNI_FALSE;

    eventHandler_reset(currentSessionID);
    transport_reset();
    debugDispatch_reset();
    invoker_reset();
    stepControl_reset();
    threadControl_reset();
    util_reset();
    commonRef_reset(env);
    classTrack_reset();

    /*
     * If this is a server, we are now ready to accept another connection.
     * If it's a client, then we've cleaned up some (more should be added
     * later) and we're done.
     */
    if (isServer) {
        arg.isServer = JNI_TRUE;
        arg.error = JDWP_ERROR(NONE);
        arg.startCount = 0;
        (void)bagEnumerateOver(transports, startTransport, &arg);

        signalInitComplete();

        transport_waitForConnection();
    } else {
        signalInitComplete(); /* Why? */
    }

    LOG_MISC(("debugInit_reset() completed."));
}


char *
debugInit_launchOnInit(void)
{
    return launchOnInit;
}

jboolean
debugInit_suspendOnInit(void)
{
    return suspendOnInit;
}

/*
 * code below is shamelessly swiped from hprof.
 */

static int
get_tok(char **src, char *buf, int buflen, char sep)
{
    int i;
    char *p = *src;
    for (i = 0; i < buflen; i++) {
        if (p[i] == 0 || p[i] == sep) {
            buf[i] = 0;
            if (p[i] == sep) {
                i++;
            }
            *src += i;
            return i;
        }
        buf[i] = p[i];
    }
    /* overflow */
    return 0;
}

static void
printUsage(void)
{
     TTY_MESSAGE((
 "               Java Debugger JDWP Agent Library\n"
 "               --------------------------------\n"
 "\n"
 "  (see http://java.sun.com/products/jpda for more information)\n"
 "\n"
 "jdwp usage: java " AGENTLIB "=[help]|[<option>=<value>, ...]\n"
 "\n"
 "Option Name and Value            Description                       Default\n"
 "---------------------            -----------                       -------\n"
 "suspend=y|n                      wait on startup?                  y\n"
 "transport=<name>                 transport spec                    none\n"
 "address=<listen/attach address>  transport spec                    \"\"\n"
 "server=y|n                       listen for debugger?              n\n"
 "launch=<command line>            run debugger on event             none\n"
 "onthrow=<exception name>         debug on throw                    none\n"
 "onuncaught=y|n                   debug on any uncaught?            n\n"
 "timeout=<timeout value>          for listen/attach in milliseconds n\n"
 "mutf8=y|n                        output modified utf-8             n\n"
 "quiet=y|n                        control over terminal messages    n\n"
 "\n"
 "Obsolete Options\n"
 "----------------\n"
 "strict=y|n\n"
 "stdalloc=y|n\n"
 "\n"
 "Examples\n"
 "--------\n"
 "  - Using sockets connect to a debugger at a specific address:\n"
 "    java " AGENTLIB "=transport=dt_socket,address=localhost:8000 ...\n"
 "  - Using sockets listen for a debugger to attach:\n"
 "    java " AGENTLIB "=transport=dt_socket,server=y,suspend=y ...\n"
 "\n"
 "Notes\n"
 "-----\n"
 "  - A timeout value of 0 (the default) is no timeout.\n"
 "\n"
 "Warnings\n"
 "--------\n"
 "  - The older " XRUN " interface can still be used, but will be removed in\n"
 "    a future release, for example:\n"
 "        java " XDEBUG " " XRUN ":[help]|[<option>=<value>, ...]\n"
    ));

#ifdef DEBUG

     TTY_MESSAGE((
 "\n"
 "Debugging Options            Description                       Default\n"
 "-----------------            -----------                       -------\n"
 "pause=y|n                    pause to debug PID                n\n"
 "coredump=y|n                 coredump at exit                  n\n"
 "errorexit=y|n                exit on any error                 n\n"
 "logfile=filename             name of log file                  none\n"
 "logflags=flags               log flags (bitmask)               none\n"
 "                               JVM calls     = 0x001\n"
 "                               JNI calls     = 0x002\n"
 "                               JVMTI calls   = 0x004\n"
 "                               misc events   = 0x008\n"
 "                               step logs     = 0x010\n"
 "                               locations     = 0x020\n"
 "                               callbacks     = 0x040\n"
 "                               errors        = 0x080\n"
 "                               everything    = 0xfff\n"
 "debugflags=flags             debug flags (bitmask)           none\n"
 "                               USE_ITERATE_THROUGH_HEAP 0x01\n"
 "\n"
 "Environment Variables\n"
 "---------------------\n"
 "_JAVA_JDWP_OPTIONS\n"
 "    Options can be added externally via this environment variable.\n"
 "    Anything contained in it will get a comma prepended to it (if needed),\n"
 "    then it will be added to the end of the options supplied via the\n"
 "    " XRUN " or " AGENTLIB " command line option.\n"
    ));

#endif



}

static jboolean checkAddress(void *bagItem, void *arg)
{
    TransportSpec *spec = (TransportSpec *)bagItem;
    if (spec->address == NULL) {
        ERROR_MESSAGE(("JDWP Non-server transport %s must have a connection "
                "address specified through the 'address=' option",
                spec->name));
        return JNI_FALSE;
    } else {
        return JNI_TRUE;
    }
}

static  char *
add_to_options(char *options, char *new_options)
{
    size_t originalLength;
    char *combinedOptions;

    /*
     * Allocate enough space for both strings and
     * comma in between.
     */
    originalLength = strlen(options);
    combinedOptions = jvmtiAllocate((jint)originalLength + 1 +
                                (jint)strlen(new_options) + 1);
    if (combinedOptions == NULL) {
        return NULL;
    }

    (void)strcpy(combinedOptions, options);
    (void)strcat(combinedOptions, ",");
    (void)strcat(combinedOptions, new_options);

    return combinedOptions;
}

static jboolean
get_boolean(char **pstr, jboolean *answer)
{
    char buf[80];
    *answer = JNI_FALSE;
    /*LINTED*/
    if (get_tok(pstr, buf, (int)sizeof(buf), ',')) {
        if (strcmp(buf, "y") == 0) {
            *answer = JNI_TRUE;
            return JNI_TRUE;
        } else if (strcmp(buf, "n") == 0) {
            *answer = JNI_FALSE;
            return JNI_TRUE;
        }
    }
    return JNI_FALSE;
}

/* atexit() callback */
static void
atexit_finish_logging(void)
{
    /* Normal exit(0) (not _exit()) may only reach here */
    finish_logging(0);  /* Only first call matters */
}

static jboolean
parseOptions(char *options)
{
    TransportSpec *currentTransport = NULL;
    char *end;
    char *current;
    int length;
    char *str;
    char *errmsg;

    /* Set defaults */
    gdata->assertOn     = DEFAULT_ASSERT_ON;
    gdata->assertFatal  = DEFAULT_ASSERT_FATAL;
    logfile             = DEFAULT_LOGFILE;

    /* Options being NULL will end up being an error. */
    if (options == NULL) {
        options = "";
    }

    /* Check for "help" BEFORE we add any environmental settings */
    if ((strcmp(options, "help")) == 0) {
        printUsage();
        forceExit(0); /* Kill entire process, no core dump wanted */
    }

    /* These buffers are never freed */
    {
        char *envOptions;

        /*
         * Add environmentally specified options.
         */
        envOptions = getenv("_JAVA_JDWP_OPTIONS");
        if (envOptions != NULL) {
            options = add_to_options(options, envOptions);
            if ( options==NULL ) {
                EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options");
            }
        }

        /*
         * Allocate a buffer for names derived from option strings. It should
         * never be longer than the original options string itself.
         * Also keep a copy of the options in gdata->options.
         */
        length = (int)strlen(options);
        gdata->options = jvmtiAllocate(length + 1);
        if (gdata->options == NULL) {
            EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options");
        }
        (void)strcpy(gdata->options, options);
        names = jvmtiAllocate(length + 1);
        if (names == NULL) {
            EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"options");
        }

        transports = bagCreateBag(sizeof(TransportSpec), 3);
        if (transports == NULL) {
            EXIT_ERROR(AGENT_ERROR_OUT_OF_MEMORY,"transports");
        }

    }

    current = names;
    end = names + length;
    str = options;

    while (*str) {
        char buf[100];
        /*LINTED*/
        if (!get_tok(&str, buf, (int)sizeof(buf), '=')) {
            goto syntax_error;
        }
        if (strcmp(buf, "transport") == 0) {
            currentTransport = bagAdd(transports);
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            currentTransport->name = current;
            current += strlen(current) + 1;
        } else if (strcmp(buf, "address") == 0) {
            if (currentTransport == NULL) {
                errmsg = "address specified without transport";
                goto bad_option_with_errmsg;
            }
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            currentTransport->address = current;
            current += strlen(current) + 1;
        } else if (strcmp(buf, "timeout") == 0) {
            if (currentTransport == NULL) {
                errmsg = "timeout specified without transport";
                goto bad_option_with_errmsg;
            }
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            currentTransport->timeout = atol(current);
            current += strlen(current) + 1;
        } else if (strcmp(buf, "launch") == 0) {
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            launchOnInit = current;
            current += strlen(current) + 1;
        } else if (strcmp(buf, "onthrow") == 0) {
            /* Read class name and convert in place to a signature */
            *current = 'L';
            /*LINTED*/
            if (!get_tok(&str, current + 1, (int)(end - current - 1), ',')) {
                goto syntax_error;
            }
            initOnException = current;
            while (*current != '\0') {
                if (*current == '.') {
                    *current = '/';
                }
                current++;
            }
            *current++ = ';';
            *current++ = '\0';
        } else if (strcmp(buf, "assert") == 0) {
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            if (strcmp(current, "y") == 0) {
                gdata->assertOn = JNI_TRUE;
                gdata->assertFatal = JNI_FALSE;
            } else if (strcmp(current, "fatal") == 0) {
                gdata->assertOn = JNI_TRUE;
                gdata->assertFatal = JNI_TRUE;
            } else if (strcmp(current, "n") == 0) {
                gdata->assertOn = JNI_FALSE;
                gdata->assertFatal = JNI_FALSE;
            } else {
                goto syntax_error;
            }
            current += strlen(current) + 1;
        } else if (strcmp(buf, "pause") == 0) {
            if ( !get_boolean(&str, &dopause) ) {
                goto syntax_error;
            }
            if ( dopause ) {
                do_pause();
            }
        } else if (strcmp(buf, "coredump") == 0) {
            if ( !get_boolean(&str, &docoredump) ) {
                goto syntax_error;
            }
        } else if (strcmp(buf, "errorexit") == 0) {
            if ( !get_boolean(&str, &(gdata->doerrorexit)) ) {
                goto syntax_error;
            }
        } else if (strcmp(buf, "exitpause") == 0) {
            errmsg = "The exitpause option removed, use -XX:OnError";
            goto bad_option_with_errmsg;
        } else if (strcmp(buf, "precrash") == 0) {
            errmsg = "The precrash option removed, use -XX:OnError";
            goto bad_option_with_errmsg;
        } else if (strcmp(buf, "logfile") == 0) {
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            logfile = current;
            current += strlen(current) + 1;
        } else if (strcmp(buf, "logflags") == 0) {
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            /*LINTED*/
            logflags = (unsigned)strtol(current, NULL, 0);
        } else if (strcmp(buf, "debugflags") == 0) {
            /*LINTED*/
            if (!get_tok(&str, current, (int)(end - current), ',')) {
                goto syntax_error;
            }
            /*LINTED*/
            gdata->debugflags = (unsigned)strtol(current, NULL, 0);
        } else if ( strcmp(buf, "suspend")==0 ) {
            if ( !get_boolean(&str, &suspendOnInit) ) {
                goto syntax_error;
            }
        } else if ( strcmp(buf, "server")==0 ) {
            if ( !get_boolean(&str, &isServer) ) {
                goto syntax_error;
            }
        } else if ( strcmp(buf, "strict")==0 ) { /* Obsolete, but accept it */
            if ( !get_boolean(&str, &isStrict) ) {
                goto syntax_error;
            }
        } else if ( strcmp(buf, "quiet")==0 ) {
            if ( !get_boolean(&str, &(gdata->quiet)) ) {
                goto syntax_error;
            }
        } else if ( strcmp(buf, "onuncaught")==0 ) {
            if ( !get_boolean(&str, &initOnUncaught) ) {
                goto syntax_error;
            }
        } else if ( strcmp(buf, "mutf8")==0 ) {
            if ( !get_boolean(&str, &(gdata->modifiedUtf8)) ) {
                goto syntax_error;
            }
        } else if ( strcmp(buf, "stdalloc")==0 ) { /* Obsolete, but accept it */
            if ( !get_boolean(&str, &useStandardAlloc) ) {
                goto syntax_error;
            }
        } else {
            goto syntax_error;
        }
    }

    /* Setup logging now */
    if ( logfile!=NULL ) {
        setup_logging(logfile, logflags);
        (void)atexit(&atexit_finish_logging);
    }

    if (bagSize(transports) == 0) {
        errmsg = "no transport specified";
        goto bad_option_with_errmsg;
    }

    /*
     * TO DO: Remove when multiple transports are allowed. (replace with
     * check below.
     */
    if (bagSize(transports) > 1) {
        errmsg = "multiple transports are not supported in this release";
        goto bad_option_with_errmsg;
    }


    if (!isServer) {
        jboolean specified = bagEnumerateOver(transports, checkAddress, NULL);
        if (!specified) {
            /* message already printed */
            goto bad_option_no_msg;
        }
    }

    /*
     * The user has selected to wait for an exception before init happens
     */
    if ((initOnException != NULL) || (initOnUncaught)) {
        initOnStartup = JNI_FALSE;

        if (launchOnInit == NULL) {
            /*
             * These rely on the launch=/usr/bin/foo
             * suboption, so it is an error if user did not
             * provide one.
             */
            errmsg = "Specify launch=<command line> when using onthrow or onuncaught suboption";
            goto bad_option_with_errmsg;
        }
    }

    return JNI_TRUE;

syntax_error:
    ERROR_MESSAGE(("JDWP option syntax error: %s=%s", AGENTLIB, options));
    return JNI_FALSE;

bad_option_with_errmsg:
    ERROR_MESSAGE(("JDWP %s: %s=%s", errmsg, AGENTLIB, options));
    return JNI_FALSE;

bad_option_no_msg:
    ERROR_MESSAGE(("JDWP %s: %s=%s", "invalid option", AGENTLIB, options));
    return JNI_FALSE;
}

/* All normal exit doors lead here */
void
debugInit_exit(jvmtiError error, const char *msg)
{
    int exit_code = 0;

    /* Pick an error code */
    if ( error != JVMTI_ERROR_NONE ) {
        exit_code = 1;
        if ( docoredump ) {
            finish_logging(exit_code);
            abort();
        }
    }
    if ( msg==NULL ) {
        msg = "";
    }

    LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error, msg));

    gdata->vmDead = JNI_TRUE;

    /* Let's try and cleanup the JVMTI, if we even have one */
    if ( gdata->jvmti != NULL ) {
        /* Dispose of jvmti (gdata->jvmti becomes NULL) */
        disposeEnvironment(gdata->jvmti);
    }

    /* Finish up logging. We reach here if JDWP is doing the exiting. */
    finish_logging(exit_code);  /* Only first call matters */

    /* Let's give the JNI a FatalError if non-exit 0, which is historic way */
    if ( exit_code != 0 ) {
        JNIEnv *env = NULL;
        jniFatalError(env, msg, error, exit_code);
    }

    /* Last chance to die, this kills the entire process. */
    forceExit(exit_code);
}
