Пример #1
0
/* Worker thread that waits for garbage collections */
static void JNICALL
worker(jvmtiEnv* jvmti, JNIEnv* jni, void *p)
{
    jvmtiError err;

    stdout_message("GC worker started...\n");

    for (;;) {
        err = (*jvmti)->RawMonitorEnter(jvmti, lock);
        check_jvmti_error(jvmti, err, "raw monitor enter");
        while (gc_count == 0) {
            err = (*jvmti)->RawMonitorWait(jvmti, lock, 0);
            if (err != JVMTI_ERROR_NONE) {
                err = (*jvmti)->RawMonitorExit(jvmti, lock);
                check_jvmti_error(jvmti, err, "raw monitor wait");
                return;
            }
        }
        gc_count = 0;

        err = (*jvmti)->RawMonitorExit(jvmti, lock);
        check_jvmti_error(jvmti, err, "raw monitor exit");

        /* Perform arbitrary JVMTI/JNI work here to do post-GC cleanup */
        stdout_message("post-GarbageCollectionFinish actions...\n");
    }
}
Пример #2
0
int
print_method_info(void * const value, void * const f_arg)
{
    (void) f_arg;

    const jmethodID     method_id = ((method_stat_t *)value)->id;
    const unsigned long counter   = ((method_stat_t *)value)->counter;

    jvmtiError  error;
    char       *name;
    char       *sig;
    char       *ptr;
    error = (*jvmti)->GetMethodName(jvmti, method_id, &name, &sig, &ptr);
    check_jvmti_error(jvmti, error, "Cannot get method name");

    jclass      decl_class;
    error = (*jvmti)->GetMethodDeclaringClass(jvmti, method_id, &decl_class);
    check_jvmti_error(jvmti, error, "Cannot get declaring class");

    char       *class_sig;
    char       *class_status;
    error = (*jvmti)->GetClassSignature(jvmti, decl_class, &class_sig, &class_status);
    check_jvmti_error(jvmti, error, "Cannot get class signature");

    printf("%ld\tclass %s -> %s(%s)\n", counter, class_sig, name, sig);

    jvmti_dealloc((unsigned char *) name);
    jvmti_dealloc((unsigned char *) sig);
    jvmti_dealloc((unsigned char *) ptr);
    jvmti_dealloc((unsigned char *) class_sig);
    jvmti_dealloc((unsigned char *) class_status);

    return MAP_OK;
}
Пример #3
0
/* Given a jvmtiEnv* and jobject, find the Monitor instance or create one */
Monitor *
Agent::get_monitor(jvmtiEnv *jvmti, JNIEnv *env, jobject object)
{
    jvmtiError err;
    Monitor   *m;
    jlong      tag;

    m   = NULL;
    tag = (jlong)0;
    err = jvmti->GetTag(object, &tag);
    check_jvmti_error(jvmti, err, "get tag");
    /*LINTED*/
    m = (Monitor *)(void *)(ptrdiff_t)tag;
    if ( m == NULL ) {
        m = new Monitor(jvmti, env, object);
        /* Save monitor on list */
        if (monitor_count == monitor_list_size) {
            monitor_list_size += monitor_list_grow_size;
            monitor_list = (Monitor**)realloc((void*)monitor_list,
                (monitor_list_size)*(int)sizeof(Monitor*));
        }
        monitor_list[monitor_count] = m;
        m->set_slot(monitor_count);
        monitor_count++;
        /*LINTED*/
        tag = (jlong)(ptrdiff_t)(void *)m;
        err = jvmti->SetTag(object, tag);
        check_jvmti_error(jvmti, err, "set tag");
    }
    return m;
}
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
    jint                rc;
    jvmtiError          err;
    jvmtiEventCallbacks callbacks;
    jvmtiEnv           *jvmti;

    /* Get JVMTI environment */
    rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION);
    if (rc != JNI_OK) {
        fatal_error("ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
        return -1;
    }

    /* Set callbacks and enable event notifications */
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.VMInit                  = &vm_init;
    err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
    check_jvmti_error(jvmti, err, "set event callbacks");
    err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                        JVMTI_EVENT_VM_INIT, NULL);
    check_jvmti_error(jvmti, err, "set event notify");
    return 0;
}
Пример #5
0
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *jvm, char *options, void *reserved)
{
  jvmtiEventCallbacks *evCbs;
  jvmtiCapabilities caps;
  jvmtiEnv *jvmti;
  jint rc;
  jint jvmtiVer;

  agent_options = options ? strdup(options) : "";
  evCbs = get_jvmti_callbacks();

  memset(evCbs, 0, sizeof(*evCbs));
  memset(&caps, 0, sizeof(caps));

  evCbs->VMInit = cbVMInit;
  evCbs->VMDeath = cbVMDeath;
  caps.can_generate_breakpoint_events = 1;
  caps.can_generate_method_entry_events = 1;
  caps.can_generate_method_exit_events = 1;
  caps.can_generate_exception_events = 1;
  caps.can_tag_objects = 1;
  caps.can_get_source_file_name = 1;
  caps.can_get_line_numbers = 1;
  caps.can_access_local_variables = 1;
  caps.can_generate_single_step_events = 1; /* Used for line-oriented stepping */
/*   caps.can_generate_frame_pop_events = 1; */
  caps.can_force_early_return = 1;

  rc = (*jvm)->GetEnv(jvm, (void **)&jvmti, JVMTI_VERSION_1_0);
  if(rc < 0)
  {
	fprintf(stderr, "Failed to get JVMTI env\n");
	return JNI_ERR;
  }

  Gagent.jvm = jvm;
  Gagent.jvmti = jvmti;
  Gagent.jerr = (*Gagent.jvmti)->GetVersionNumber(Gagent.jvmti, &jvmtiVer);
  check_jvmti_error(Gagent.jvmti, Gagent.jerr);
  printf("JVMTI version %d.%d.%d\n",
		 (jvmtiVer & JVMTI_VERSION_MASK_MAJOR) >> JVMTI_VERSION_SHIFT_MAJOR,
		 (jvmtiVer & JVMTI_VERSION_MASK_MINOR) >> JVMTI_VERSION_SHIFT_MINOR,
		 (jvmtiVer & JVMTI_VERSION_MASK_MICRO) >> JVMTI_VERSION_SHIFT_MICRO);
  Gagent.jerr = (*Gagent.jvmti)->AddCapabilities(Gagent.jvmti, &caps);
  check_jvmti_error(Gagent.jvmti, Gagent.jerr);
  Gagent.jerr = (*Gagent.jvmti)->SetEventCallbacks(Gagent.jvmti,
												   evCbs, sizeof(jvmtiEventCallbacks));
  check_jvmti_error(Gagent.jvmti, Gagent.jerr);
  /* Check that any calls to SetEventNotificationMode are valid in the
     OnLoad phase before calling here. */
  Gagent.jerr = event_change(Gagent.jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
  check_jvmti_error(Gagent.jvmti, Gagent.jerr);
  Gagent.jerr = event_change(Gagent.jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_DEATH, NULL);
  check_jvmti_error(Gagent.jvmti, Gagent.jerr);

  return JNI_OK;
}
Пример #6
0
/* Add demo jar file to boot class path (the BCI Tracker class must be 
 *     in the boot classpath)
 *
 *   WARNING: This code assumes that the jar file can be found at one of:
 *              ${JAVA_HOME}/demo/jvmti/${DEMO_NAME}/${DEMO_NAME}.jar
 *              ${JAVA_HOME}/../demo/jvmti/${DEMO_NAME}/${DEMO_NAME}.jar
 *            where JAVA_HOME may refer to the jre directory.
 *            Both these values are added to the boot classpath.
 *            These locations are only true for these demos, installed
 *            in the JDK area. Platform specific code could be used to
 *            find the location of the DLL or .so library, and construct a
 *            path name to the jar file, relative to the library location.
 */
void
add_demo_jar_to_bootclasspath(jvmtiEnv *jvmti, char *demo_name)
{
    jvmtiError error;
    char      *file_sep;
    int        max_len;
    char      *java_home;
    char       jar_path[FILENAME_MAX+1];
   
    java_home = NULL;
    error = (*jvmti)->GetSystemProperty(jvmti, "java.home", &java_home);
    check_jvmti_error(jvmti, error, "Cannot get java.home property value");
    if ( java_home == NULL || java_home[0] == 0 ) {
	fatal_error("ERROR: Java home not found\n");
    }
   
#ifdef WIN32
    file_sep = "\\";
#else
    file_sep = "/";
#endif
    
    max_len = (int)(strlen(java_home) + strlen(demo_name)*2 + 
			 strlen(file_sep)*5 + 
			 16 /* ".." "demo" "jvmti" ".jar" NULL */ );
    if ( max_len > (int)sizeof(jar_path) ) {
	fatal_error("ERROR: Path to jar file too long\n");
    }
    (void)strcpy(jar_path, java_home);
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, "demo");
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, "jvmti");
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, demo_name);
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, demo_name);
    (void)strcat(jar_path, ".jar");
    error = (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, (const char*)jar_path);
    check_jvmti_error(jvmti, error, "Cannot add to boot classpath");
    
    (void)strcpy(jar_path, java_home);
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, "..");
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, "demo");
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, "jvmti");
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, demo_name);
    (void)strcat(jar_path, file_sep);
    (void)strcat(jar_path, demo_name);
    (void)strcat(jar_path, ".jar");
    
    error = (*jvmti)->AddToBootstrapClassLoaderSearch(jvmti, (const char*)jar_path);
    check_jvmti_error(jvmti, error, "Cannot add to boot classpath");
}
Пример #7
0
JNIEXPORT jint JNICALL Agent_OnLoad(JavaVM *vm, char *options, void *reserved){
    PORT_ACCESS_FROM_JAVAVM(vm);
    VMI_ACCESS_FROM_JAVAVM(vm);
    jvmtiError jvmti_err;
    JNIEnv *env = NULL;
    static jvmtiEnv *jvmti;
    jvmtiCapabilities updatecapabilities;
    jint err = (*vm)->GetEnv(vm, (void **)&jnienv, JNI_VERSION_1_2);
    if(JNI_OK != err){
        return err;
    }

    if(!gdata){
        jvmtiCapabilities capabilities;
        jvmtiError jvmti_err;
        jvmtiEventCallbacks callbacks;

        gdata = hymem_allocate_memory(sizeof(AgentData));

        //get jvmti environment
        err = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION_1_0);
        if(JNI_OK != err){
            return err;
        }
        gdata->jvmti = jvmti;

        //get JVMTI potential capabilities
        jvmti_err = (*jvmti)->GetPotentialCapabilities(jvmti, &capabilities);
        check_jvmti_error(env, jvmti_err, "Cannot get JVMTI potential capabilities.");
        gsupport_redefine = (capabilities.can_redefine_classes == 1);

        //set events callback function
        (void)memset(&callbacks, 0, sizeof(callbacks));
        callbacks.ClassFileLoadHook = &callbackClassFileLoadHook;
        callbacks.VMInit = &callbackVMInit;
        jvmti_err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(jvmtiEventCallbacks));
        check_jvmti_error(env, jvmti_err, "Cannot set JVMTI event callback functions.");

        //enable classfileloadhook event
        jvmti_err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE, JVMTI_EVENT_VM_INIT, NULL);
        check_jvmti_error(env, jvmti_err, "Cannot set JVMTI VMInit event notification mode.");
    }

    err = Parse_Options(vm,jnienv, gdata->jvmti,options);

    //update capabilities JVMTI
    memset(&updatecapabilities, 0, sizeof(updatecapabilities));
    updatecapabilities.can_generate_all_class_hook_events = 1;
    updatecapabilities.can_redefine_classes = gsupport_redefine;
    //FIXME VM doesnot support the capbility right now.
    //capabilities.can_redefine_any_class = 1;
    jvmti_err = (*jvmti)->AddCapabilities(jvmti, &updatecapabilities);
    check_jvmti_error(env, jvmti_err, "Cannot add JVMTI capabilities.");

    return err;
}
Пример #8
0
/*
 * Callback to notify us when a GC finishes. When a GC finishes,
 * we wake up our GC thread and free all tags that need to be freed.
 */
static void JNICALL
gc_finish(jvmtiEnv* jvmti_env)
{
	jvmtiError err;
	err = gdata->jvmti->RawMonitorEnter(gcLock);
	check_jvmti_error(gdata->jvmti, err, "raw monitor enter");
	gc_count++;
	err = gdata->jvmti->RawMonitorNotify(gcLock);
	check_jvmti_error(gdata->jvmti, err, "raw monitor notify");
	err = gdata->jvmti->RawMonitorExit(gcLock);
	check_jvmti_error(gdata->jvmti, err, "raw monitor exit");
}
Пример #9
0
/* Callback for JVMTI_EVENT_GARBAGE_COLLECTION_FINISH */
static void JNICALL
gc_finish(jvmtiEnv* jvmti_env)
{
    jvmtiError err;

    stdout_message("GarbageCollectionFinish...\n");

    err = (*jvmti)->RawMonitorEnter(jvmti, lock);
    check_jvmti_error(jvmti, err, "raw monitor enter");
    gc_count++;
    err = (*jvmti)->RawMonitorNotify(jvmti, lock);
    check_jvmti_error(jvmti, err, "raw monitor notify");
    err = (*jvmti)->RawMonitorExit(jvmti, lock);
    check_jvmti_error(jvmti, err, "raw monitor exit");
}
Пример #10
0
// Exit a critical section by doing a JVMTI Raw Monitor Exit
static void exit_critical_section(jvmtiEnv *jvmti)
{
    jvmtiError error;
    error = (*jvmti)->RawMonitorExit(jvmti, gdata->lock);
    //    error = (*jvmti).RawMonitorExit( gdata->lock);
    check_jvmti_error(jvmti, error, "Cannot exit with raw monitor");
}
Пример #11
0
void tl_init(jvmtiEnv * env) {
  jvmti_env = env;

  jvmtiError error = (*jvmti_env)->CreateRawMonitor(jvmti_env, "thread id",
      &threadID_lock);
  check_jvmti_error(jvmti_env, error, "Cannot create raw monitor");
}
Пример #12
0
/* All memory allocated by JVMTI must be freed by the JVMTI Deallocate
 *   interface.
 */
void
deallocate(jvmtiEnv *jvmti, void *ptr)
{
    jvmtiError error;

#ifdef DEBUG
    size_t *p = (size_t *) ptr;
    char *start = (char *) ptr;

    size_t len = p[-2];
    char *end = &start[len];

    size_t start_guard = p[-1];
    size_t end_guard = ((size_t *)end)[0];

    if (start_guard != 0xdfdfdfdfdfdfdfdf) {
        fatal_error("start guard got stomped");
    }

    if (end_guard != 0xdfdfdfdfdfdfdfdf) {
        fatal_error("end guard got stomped");
    }

    ptr = &(p[-2]);
#endif

    error = (*jvmti)->Deallocate(jvmti, ptr);
    check_jvmti_error(jvmti, error, "Cannot deallocate memory");
}
Пример #13
0
/* Allocation of JVMTI managed memory */
void *
allocate(jvmtiEnv *jvmti, size_t len)
{
    jvmtiError error;
    void      *ptr = NULL;

#ifdef DEBUG
    size_t    *p = NULL;
    size_t     l = len;

    len += 3 * sizeof(size_t);
#endif

    error = (*jvmti)->Allocate(jvmti, (jlong) len, (unsigned char **)&ptr);
    check_jvmti_error(jvmti, error, "Cannot allocate memory");

#ifdef DEBUG
    memset(ptr, 0xdf, len);

    p = (size_t *) ptr;
    p[0] = l;

    ptr = &(p[2]);
#endif

    return ptr;
}
Пример #14
0
void deallocate(jvmtiEnv *jvmti, void *ptr)
{
  jvmtiError error;
    
  error = (*jvmti)->Deallocate(jvmti, ptr);
  check_jvmti_error(jvmti, error, "Cannot deallocate memory");
}
Пример #15
0
// VM Death callback
static void JNICALL callbackVMDeath(jvmtiEnv *jvmti_env, JNIEnv* jni_env)
{
    jvmtiError          err;
	/// Make sure everything has been garbage collected 
    err = jvmti->ForceGarbageCollection();
    check_jvmti_error(jvmti, err, "Forced garbage collection failed");

	enter_critical_section(jvmti); {
	err = jvmti->SetEventNotificationMode(JVMTI_DISABLE, 
			    JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
	check_jvmti_error(jvmti, err, "SetEventNotificationMode failure");
	
	
	} exit_critical_section(jvmti);

}
Пример #16
0
/*
 * Implementation of _setTag JNI function.
 */
JNIEXPORT static void JNICALL setObjExpression(JNIEnv *env, jclass klass,
		jobject o, jobject expr) {
	if (gdata->vmDead) {
		return;
	}
	if(!o)
	{
		return;
	}
	jvmtiError error;
	jlong tag;
	if (expr) {
		//First see if there's already something set here
		error =gdata->jvmti->GetTag(o,&tag);
		if(tag)
		{
			//Delete reference to old thing
			env->DeleteGlobalRef((jobject)(ptrdiff_t) tag);
		}
		//Set the tag, make a new global reference to it
		error = gdata->jvmti->SetTag(o, (jlong) (ptrdiff_t) (void*) env->NewGlobalRef(expr));
	} else {
		error = gdata->jvmti->SetTag(o, 0);
	}
	if(error == JVMTI_ERROR_WRONG_PHASE)
	return;
	check_jvmti_error(gdata->jvmti, error, "Cannot set object tag");
}
Пример #17
0
/* Callback for JVMTI_EVENT_VM_INIT */
static void JNICALL
cbVMInit(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
{
    enter_critical_section(jvmti);
    {
        char  tname[MAX_THREAD_NAME_LENGTH];
        static jvmtiEvent events[] =
        { JVMTI_EVENT_THREAD_START, JVMTI_EVENT_THREAD_END };
        int        i;

        /* The VM has started. */
        get_thread_name(jvmti, thread, tname, sizeof(tname));
        stdout_message("VMInit %s\n", tname);

        /* The VM is now initialized, at this time we make our requests
         *   for additional events.
         */

        for( i=0; i < (int)(sizeof(events)/sizeof(jvmtiEvent)); i++) {
            jvmtiError error;

            /* Setup event  notification modes */
            error = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                    events[i], (jthread)NULL);
            check_jvmti_error(jvmti, error, "Cannot set event notification");
        }

    }
    exit_critical_section(jvmti);
}
/* Get a name for a jthread */
static void
get_thread_name(jvmtiEnv *jvmti, jthread thread, char *tname, int maxlen)
{
    jvmtiThreadInfo info;
    jvmtiError      error;

    /* Make sure the stack variables are garbage free */
    (void)memset(&info,0, sizeof(info));

    /* Assume the name is unknown for now */
    (void)strcpy(tname, "Unknown");

    /* Get the thread information, which includes the name */
    error = (*jvmti)->GetThreadInfo(jvmti, thread, &info);
    check_jvmti_error(jvmti, error, "Cannot get thread info");

    /* The thread might not have a name, be careful here. */
    if ( info.name != NULL ) {
        int len;

        /* Copy the thread name into tname if it will fit */
        len = (int)strlen(info.name);
        if ( len < maxlen ) {
            (void)strcpy(tname, info.name);
        }

        /* Every string allocated by JVMTI needs to be freed */
        deallocate(jvmti, (void*)info.name);
    }
}
Пример #19
0
/*
 * Callback we get when the JVM is initialized. We use this time to setup our GC thread
 */
static void JNICALL callbackVMInit(jvmtiEnv * jvmti, JNIEnv * env, jthread thread)
{
	jvmtiError err;

	err = jvmti->RunAgentThread(alloc_thread(env), &gcWorker, NULL,
			JVMTI_THREAD_MAX_PRIORITY);
	check_jvmti_error(jvmti, err, "Unable to run agent cleanup thread");
}
Пример #20
0
/*
 * Since we create a global reference to whatever we tag an object with, we need to clean this up
 * when the tagged object is garbage collected - otherwise tags wouldn't ever be garbage collected.
 * When a tagged object is GC'ed, we add its tag to a deletion queue. We will process the queue at the next GC.
 */
static void JNICALL
cbObjectFree(jvmtiEnv *jvmti_env, jlong tag) {
	if (gdata->vmDead) {
		return;
	}
	jvmtiError error;
	if (tag) {
		error = gdata->jvmti->RawMonitorEnter(deleteQueueLock);
		check_jvmti_error(jvmti_env, error, "raw monitor enter");
		DeleteQueue* tmp = deleteQueue;
		deleteQueue = new DeleteQueue();
		deleteQueue->next = tmp;
		deleteQueue->obj = (jobject) (ptrdiff_t) tag;
		error = gdata->jvmti->RawMonitorExit(deleteQueueLock);
		check_jvmti_error(jvmti_env, error, "raw monitor exit");
	}
}
Пример #21
0
/* Enter raw monitor */
static void
menter(jvmtiEnv *jvmti, jrawMonitorID rmon)
{
    jvmtiError err;

    err = jvmti->RawMonitorEnter(rmon);
    check_jvmti_error(jvmti, err, "raw monitor enter");
}
Пример #22
0
/* Enter a critical section by doing a JVMTI Raw Monitor Enter */
static void
enter_critical_section(jvmtiEnv *jvmti)
{
    jvmtiError error;

    error = (*jvmti)->RawMonitorEnter(jvmti, gdata->lock);
    check_jvmti_error(jvmti, error, "Cannot enter with raw monitor");
}
Пример #23
0
/* Exit raw monitor */
static void
mexit(jvmtiEnv *jvmti, jrawMonitorID rmon)
{
    jvmtiError err;

    err = jvmti->RawMonitorExit(rmon);
    check_jvmti_error(jvmti, err, "raw monitor exit");
}
Пример #24
0
/* Exit agent monitor protected section */
static void
exitAgentMonitor(jvmtiEnv *jvmti)
{
    jvmtiError err;
    
    err = (*jvmti)->RawMonitorExit(jvmti, gdata->lock);
    check_jvmti_error(jvmti, err, "raw monitor exit");
}
Пример #25
0
/* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
    jint                rc;
    jvmtiError          err;
    jvmtiCapabilities   capabilities;
    jvmtiEventCallbacks callbacks;
    jvmtiEnv           *jvmti;

    /* Get JVMTI environment */
    jvmti = NULL;
    rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION);
    if (rc != JNI_OK) {
        fatal_error("ERROR: Unable to create jvmtiEnv, error=%d\n", rc);
        return -1;
    }
    if ( jvmti == NULL ) {
        fatal_error("ERROR: No jvmtiEnv* returned from GetEnv\n");
    }

    /* Get/Add JVMTI capabilities */
    (void)memset(&capabilities, 0, sizeof(capabilities));
    capabilities.can_tag_objects = 1;
    capabilities.can_generate_garbage_collection_events = 1;
    err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
    check_jvmti_error(jvmti, err, "add capabilities");

    /* Create the raw monitor */
    err = (*jvmti)->CreateRawMonitor(jvmti, "agent lock", &(gdata->lock));
    check_jvmti_error(jvmti, err, "create raw monitor");

    /* Set callbacks and enable event notifications */
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.VMInit                  = &vmInit;
    callbacks.VMDeath                 = &vmDeath;
    callbacks.DataDumpRequest         = &dataDumpRequest;
    err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
    check_jvmti_error(jvmti, err, "set event callbacks");
    err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                        JVMTI_EVENT_VM_INIT, NULL);
    check_jvmti_error(jvmti, err, "set event notifications");
    err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                        JVMTI_EVENT_VM_DEATH, NULL);
    check_jvmti_error(jvmti, err, "set event notifications");
    return 0;
}
Пример #26
0
// Enter a critical section by doing a JVMTI Raw Monitor Enter
static void enter_critical_section(jvmtiEnv *jvmti)
{
    jvmtiError error;

    error = (*jvmti)->RawMonitorEnter(jvmti, gdata->lock);  //the error function does not take 2 arguments
    //    error = (*jvmti).RawMonitorEnter(gdata->lock);
    check_jvmti_error(jvmti, error, "Cannot enter with raw monitor");
}
Пример #27
0
/* Agent_OnLoad() is called first, we prepare for a COMPILED_METHOD_LOAD
 * event here.
 */
JNIEXPORT jint JNICALL
Agent_OnLoad(JavaVM *vm, char *options, void *reserved)
{
    jint                rc;
    jvmtiError          err;
    jvmtiCapabilities   capabilities;
    jvmtiEventCallbacks callbacks;

    fp = fopen(OUTPUT_FILE, "w");
    if (fp == NULL) {
        fatal_error("ERROR: %s: Unable to create output file\n", OUTPUT_FILE);
        return -1;
    }

    /* Get JVMTI environment */
    rc = (*vm)->GetEnv(vm, (void **)&jvmti, JVMTI_VERSION);
    if (rc != JNI_OK) {
        fatal_error(
            "ERROR: Unable to create jvmtiEnv, GetEnv failed, error=%d\n", rc);
        return -1;
    }

    /* add JVMTI capabilities */
    memset(&capabilities,0, sizeof(capabilities));
    capabilities.can_generate_compiled_method_load_events = 1;
    err = (*jvmti)->AddCapabilities(jvmti, &capabilities);
    check_jvmti_error(jvmti, err, "add capabilities");

    /* set JVMTI callbacks for events */
    memset(&callbacks, 0, sizeof(callbacks));
    callbacks.CompiledMethodLoad = &compiled_method_load;
    err = (*jvmti)->SetEventCallbacks(jvmti, &callbacks, sizeof(callbacks));
    check_jvmti_error(jvmti, err, "set event callbacks");

    /* enable JVMTI events */
    err = (*jvmti)->SetEventNotificationMode(jvmti, JVMTI_ENABLE,
                        JVMTI_EVENT_COMPILED_METHOD_LOAD, NULL);
    check_jvmti_error(jvmti, err, "set event notify");

    /* create coordination monitor */
    err = (*jvmti)->CreateRawMonitor(jvmti, "agent lock", &lock);
    check_jvmti_error(jvmti, err, "create raw monitor");

    return 0;
}
Пример #28
0
void* allocate(jvmtiEnv *jvmti, jint len)
{
  jvmtiError error;
  void      *ptr;
    
  error = (*jvmti)->Allocate(jvmti, len, (unsigned char **)&ptr);
  check_jvmti_error(jvmti, error, "Cannot allocate memory");
  return ptr;
}
Пример #29
0
static char *
__thread_name (jvmtiEnv * jvmti) {
	assert (jvmti != NULL && jvm_is_initialized);

	jvmtiThreadInfo info;
	jvmtiError error = (* jvmti)->GetThreadInfo (jvmti, NULL, &info);
	check_jvmti_error (jvmti, error, "failed to get current thread info");

	return info.name;
}
Пример #30
0
/* Given a jvmtiEnv* and jthread, find the Thread instance */
Thread *
Agent::get_thread(jvmtiEnv *jvmti, JNIEnv *env, jthread thread)
{
    jvmtiError err;
    Thread    *t;

    /* This should always be in the Thread Local Storage */
    t = NULL;
    err = jvmti->GetThreadLocalStorage(thread, (void**)&t);
    check_jvmti_error(jvmti, err, "get thread local storage");
    if ( t == NULL ) {
        /* This jthread has never been seen before? */
        stdout_message("WARNING: Never before seen jthread?\n");
        t = new Thread(jvmti, env, thread);
        err = jvmti->SetThreadLocalStorage(thread, (const void*)t);
        check_jvmti_error(jvmti, err, "set thread local storage");
    }
    return t;
}