Exemple #1
0
/* 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);
}
Exemple #2
0
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;
}
Exemple #3
0
/* All normal exit doors lead here */
void
debugInit_exit(jvmtiError error, const char *msg)
{
    enum exit_codes { EXIT_NO_ERRORS = 0, EXIT_JVMTI_ERROR = 1, EXIT_TRANSPORT_ERROR = 2 };

    // Prepare to exit. Log error and finish logging
    LOG_MISC(("Exiting with error %s(%d): %s", jvmtiErrorText(error), error,
              ((msg == NULL) ? "" : msg)));

    // coredump requested by command line. Keep JVMTI data dirty
    if (error != JVMTI_ERROR_NONE && docoredump) {
        LOG_MISC(("Dumping core as requested by command line"));
        finish_logging();
        abort();
    }

    finish_logging();

    // Cleanup the JVMTI if we have one
    if (gdata != NULL) {
        gdata->vmDead = JNI_TRUE;
        if (gdata->jvmti != NULL) {
            // Dispose of jvmti (gdata->jvmti becomes NULL)
            disposeEnvironment(gdata->jvmti);
        }
    }

    // We are here with no errors. Kill entire process and exit with zero exit code
    if (error == JVMTI_ERROR_NONE) {
        forceExit(EXIT_NO_ERRORS);
        return;
    }

    // No transport initilized.
    // As we don't have any details here exiting with separate exit code
    if (error == AGENT_ERROR_TRANSPORT_INIT) {
        forceExit(EXIT_TRANSPORT_ERROR);
        return;
    }

    // We have JVMTI error. Call hotspot jni_FatalError handler
    jniFatalError(NULL, msg, error, EXIT_JVMTI_ERROR);

    // hotspot calls os:abort() so we should never reach code below,
    // but guard against possible hotspot changes

    // Last chance to die, this kills the entire process.
    forceExit(EXIT_JVMTI_ERROR);
}
Exemple #4
0
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;
}
Exemple #5
0
/* 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);
}
Exemple #6
0
/* OnLoad startup:
 *   Returning JNI_ERR will cause the java_g VM to core dump, be careful.
 */
JNIEXPORT jint JNICALL
DEF_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;

    /* 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;
}