7 Replies Latest reply: Sep 21, 2008 3:52 PM by 843810 RSS

    help on writing & calling method written in JVMTI agent in java program

    843810
      hello All,
      I want to write simple JVMTI agent function that will ruturn number of classes loaded in JVM memory in numeric format. Also I would like to access & display this information in a java program.

      Can someone please help me on this?
        • 1. Re: help on writing & calling method written in JVMTI agent in java program
          843810
          GetLoadedClasses api returns number of classes loaded in jvm.

          http://java.sun.com/javase/6/docs/platform/jvmti/jvmti.html#GetLoadedClasses

          Write a jni function and then call it from java.

          Like for example:

          foo.java:
          public class foo() {
             
               native int loadedClasses();
          
               ing numOfClasses() {
          
                  return loadedClasses();
          
               }
          
          }
          jvmti.c
          JNIEXPORT jint JNICALL Java_foo_ladedClasses(JNIEnv * env, jobject obj) {
          
                int loadedClassCount;
          
                call jvmti GetLoadedClass function.
             
                return loadedClassCount;
          
          }
          • 2. Re: help on writing & calling method written in JVMTI agent in java program
            843810
            Hi Swamy...

            Thanks for your reply.....

            Can you please exlain how to "call jvmti GetLoadedClass function.", inside the method "Java_foo_ladedClasses". Also how the other JVMTI objects initialized by Agent_onLoad will be available to this method?





            I tried it as below:-


            ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


            JNIEXPORT jint JNICALL Java_DLLTest_getNumberOfClasses
            (JNIEnv *, jobject){
            jclass *classes;
            jint count;

            jvmti->GetLoadedClasses(&count, &classes);
            check_jvmti_error(jvmti, err, "get loaded classes");
            return count;
            }


            +++++++++++++++++++++++++++++++++


            But I got the compilation error :-


            +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


            1>c:\documents and settings\prash\desktop\dllforjava\dlltest\dlltest\dlltest.cpp(354) : error C2065: 'jvmti' : undeclared identifier
            1>c:\documents and settings\prash\desktop\dllforjava\dlltest\dlltest\dlltest.cpp(354) : error C2227: left of '->GetLoadedClasses' must point to class/struct/union/generic type
            1> type is ''unknown-type''


            +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++





            Also I will not be loading agent by using "java -agentlib:........", instead I want to load agent by System.loadlibrary(.....), in this scenario the Agent_Onload will bet invoked?

            Please reply...

            Many thanks in advance...

            --pras

            Edited by: prash on Sep 21, 2008 11:02 AM
            • 3. Re: help on writing & calling method written in JVMTI agent in java program
              843810
              Hi Swamy,

              I tried with your suggession Now I am getting some weired exception:-

              +++++++++++++++++++++++++++++++++++++++++++++++++++++
              #
              # An unexpected error has been detected by HotSpot Virtual Machine:
              #
              # EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x100125d4, pid=3892, tid=2988
              #
              # Java VM: Java HotSpot(TM) Client VM (1.5.0-b64 mixed mode, sharing)
              # Problematic frame:
              # C [DLLTest.dll+0x125d4]
              #
              # An error report file with more information is saved as hs_err_pid3892.log
              #
              # If you would like to submit a bug report, please visit:
              # http://java.sun.com/webapps/bugreport/crash.jsp
              #
              inside Java_DLLTest_getDLLTest method++++++++++++++++++++++++++++++++++++++++++++++++++++++

              Also my Agent CPP file for your reference is:-
              ++++++++++++++++++++++++++++++++++++++
              // DLLTest.cpp : Defines the exported functions for the DLL application.
              //
              
              #include "stdafx.h"
              #include <stdio.h>
              #include <stddef.h>
              #include <stdlib.h>
              #include <string.h>
              #include <iostream>
              
              #include "C:\Program Files\Java\jdk1.6.0_06\include\jni.h"
              #include "C:\Program Files\Java\jdk1.6.0_06\include\jvmti.h"
              #include <agent_util.h>
              #include "C:\pal\workspace\hello\src\DLLTest.h"
              
              
              
              using namespace std;
              /* Global static data */
              static jvmtiEnv *jvmti = NULL;
              
              typedef struct {
                  jboolean      vmDeathCalled;
                  jboolean      dumpInProgress;
                  jrawMonitorID lock;
                  jvmtiEnv *jvmti;
              } GlobalData;
              
              
              /* Typedef to hold class details */
              static GlobalData globalData, *gdata = &globalData;
              
              typedef struct {
                  char *signature;
                  int   count;
                  int   space;
              } ClassDetails;
              
              
              /* Enter agent monitor protected section */
              static void
              enterAgentMonitor(jvmtiEnv *jvmti)
              {
                  jvmtiError err;
                  err = jvmti->RawMonitorEnter(gdata->lock);
                  cout << err << "raw monitor enter";
              }
              
              /* Exit agent monitor protected section */
              static void
              exitAgentMonitor(jvmtiEnv *jvmti)
              {
                  jvmtiError err;
                  err = jvmti->RawMonitorExit(gdata->lock);
                  cout << err << "raw monitor exit";
              }
              
              
              static jint JNICALL 
              cbHeapObject(jlong class_tag, jlong size, jlong* tag_ptr, jint length,
                         void* user_data)
              {
                  if ( class_tag != (jlong)0 ) {
                      ClassDetails *d;
              
                      d = (ClassDetails*)(void*)(ptrdiff_t)class_tag;
                      (*((jint*)(user_data)))++;
                      d->count++;
                      d->space += (int)size;
                  }
                  return JVMTI_VISIT_OBJECTS;
              }
              
              /* Send message to stdout or whatever the data output location is */
              void
              stdout_message(const char * format, ...)
              {
                  va_list ap;
              
                  va_start(ap, format);
                  (void)vfprintf(stdout, format, ap);
                  va_end(ap);
              }
              
              
              
              /* Compare two ClassDetails */
              static int
              compareDetails(const void *p1, const void *p2)
              {
                  return ((ClassDetails*)p2)->space - ((ClassDetails*)p1)->space;
              }
              
              
              /* All memory allocated by JVMTI must be freed by the JVMTI Deallocate
               *   interface.
               */
              void
              deallocate(jvmtiEnv *jvmti, void *ptr)
              {
                  jvmtiError error;
              
                  error = jvmti->Deallocate((unsigned char *)ptr);
                  check_jvmti_error(jvmti, error, "Cannot deallocate memory");
              }
              
              /* Send message to stderr or whatever the error output location is and exit  */
              void
              fatal_error(const char * format, ...)
              {
                  va_list ap;
              
                  va_start(ap, format);
                  (void)vfprintf(stderr, format, ap);
                  (void)fflush(stderr);
                  va_end(ap);
                  exit(3);
              }
              
              
              /* ------------------------------------------------------------------- */
              /* Generic JVMTI utility functions */
              
              /* Every JVMTI interface returns an error code, which should be checked
               *   to avoid any cascading errors down the line.
               *   The interface GetErrorName() returns the actual enumeration constant
               *   name, making the error messages much easier to understand.
               */
              void
              check_jvmti_error(jvmtiEnv *jvmti, jvmtiError errnum, const char *str)
              {
                  if ( errnum != JVMTI_ERROR_NONE ) {
                  char       *errnum_str;
              
                  errnum_str = NULL;
                  (void)jvmti->GetErrorName(errnum, &errnum_str);
              
                  fatal_error("ERROR: JVMTI: %d(%s): %s\n", errnum, 
                      (errnum_str==NULL?"Unknown":errnum_str),
                      (str==NULL?"":str));
                  }
              }
              
              
              JNIEXPORT void JNICALL Java_HelloJNI_sayHellotomanu
                (JNIEnv *, jobject)
              {
              return;
              }
              
              
              /* Callback for JVMTI_EVENT_DATA_DUMP_REQUEST (Ctrl-\ or at exit) */
              static void JNICALL
              dataDumpRequest(jvmtiEnv *jvmti)
              {
                  enterAgentMonitor(jvmti); {
                      if ( !gdata->vmDeathCalled && !gdata->dumpInProgress ) {
                          jvmtiHeapCallbacks heapCallbacks;
                          ClassDetails      *details;
                          jvmtiError         err;
                          jclass            *classes;
                          jint               totalCount;
                          jint               count;
                          jint               i;
              
                          gdata->dumpInProgress = JNI_TRUE;
              
                          /* Get all the loaded classes */
                          err = jvmti->GetLoadedClasses(&count, &classes);
                         check_jvmti_error(jvmti, err, "get loaded classes");
              
                          /* Setup an area to hold details about these classes */
                          details = (ClassDetails*)calloc(sizeof(ClassDetails), count);
                          if ( details == NULL ) {
                             fatal_error("ERROR: Ran out of malloc space\n");
                          }
                          for ( i = 0 ; i < count ; i++ ) {
                              char *sig;
              
                              /* Get and save the class signature */
                              err = jvmti->GetClassSignature(classes, &sig, NULL);
              check_jvmti_error(jvmti, err, "get class signature");
              if ( sig == NULL ) {
              fatal_error("ERROR: No class signature found\n");
              }
              details[i].signature = strdup(sig);
              deallocate(jvmti, sig);

              /* Tag this jclass */
              err = jvmti->SetTag(classes[i],
              (jlong)(ptrdiff_t)(void*)(&details[i]));
              check_jvmti_error(jvmti, err, "set object tag");
              }

              /* Iterate through the heap and count up uses of jclass */
              (void)memset(&heapCallbacks, 0, sizeof(heapCallbacks));
              heapCallbacks.heap_iteration_callback = &cbHeapObject;
              totalCount = 0;
              err = jvmti->IterateThroughHeap(JVMTI_HEAP_FILTER_CLASS_UNTAGGED, NULL,
              &heapCallbacks, (const void *)&totalCount);
              check_jvmti_error(jvmti, err, "iterate through heap");

              /* Remove tags */
              for ( i = 0 ; i < count ; i++ ) {
              /* Un-Tag this jclass */
              err = jvmti->SetTag(classes[i], (jlong)0);
              check_jvmti_error(jvmti, err, "set object tag");
              }

              /* Sort details by space used */
              qsort(details, count, sizeof(ClassDetails), &compareDetails);

              /* Print out sorted table */
              stdout_message("Heap View, Total of %d objects found.\n\n",
              totalCount);

              stdout_message("Space Count Class Signature\n");
              stdout_message("---------- ---------- ----------------------\n");

              for ( i = 0 ; i < count ; i++ ) {
              if ( details[i].space == 0 || i > 20 ) {
              break;
              }
              stdout_message("%10d %10d %s\n",
              details[i].space, details[i].count, details[i].signature);
              }
              stdout_message("---------- ---------- ----------------------\n\n");

              /* Free up all allocated space */
              deallocate(jvmti, classes);
              for ( i = 0 ; i < count ; i++ ) {
              if ( details[i].signature != NULL ) {
              free(details[i].signature);
              }
              }
              free(details);

              gdata->dumpInProgress = JNI_FALSE;
              }
              } exitAgentMonitor(jvmti);
              }



              static void JNICALL
              vmInit(jvmtiEnv jvmti, JNIEnv env, jthread thread)
              {
              enterAgentMonitor(jvmti); {
              jvmtiError err;

              err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
              JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
              cout << jvmti << err << "set event notification";
              } exitAgentMonitor(jvmti);

              }


              static void JNICALL
              vmDeath(jvmtiEnv jvmti, JNIEnv env)
              {
              jvmtiError err;
              cout << "inside vmDeath method";
              /* Make sure everything has been garbage collected */
              err = jvmti->ForceGarbageCollection();
              check_jvmti_error(jvmti, err, "force garbage collection");

              /* Disable events and dump the heap information */
              enterAgentMonitor(jvmti); {
              err = jvmti->SetEventNotificationMode(JVMTI_DISABLE,
              JVMTI_EVENT_DATA_DUMP_REQUEST, NULL);
              check_jvmti_error(jvmti, err, "set event notification");

              dataDumpRequest(jvmti);

              gdata->vmDeathCalled = JNI_TRUE;
              } exitAgentMonitor(jvmti);
              }


              /* Agent_OnLoad() is called first, we prepare for a VM_INIT event here. */
              JNIEXPORT jint JNICALL
              Agent_OnLoad(JavaVM vm, char options, void *reserved)
              {
              //jvmtiEnv *jvmti;
              jint rc;
              jvmtiError err;
              jvmtiCapabilities capabilities;
              jvmtiEventCallbacks callbacks;
              static GlobalData data;

              (void)memset((void*)&data, 0, sizeof(data));
              gdata = &data;


              /* Get JVMTI environment */
              // jvmti = NULL;
              rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION);
              gdata->jvmti=jvmti;
              if (rc != JNI_OK) {
              cout << "ERROR: Unable to create jvmtiEnv, error=%d\n"<< rc;
              return -1;
              }
              if ( jvmti == NULL ) {
              cout << "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(&capabilities);
              check_jvmti_error(jvmti, err, "add capabilities");


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

              /* Set callbacks and enable event notifications */
              memset(&callbacks, 0, sizeof(callbacks));
              cout << "Hello.......................";
              callbacks.VMInit = &vmInit;
              callbacks.VMDeath = &vmDeath;
              callbacks.DataDumpRequest = &dataDumpRequest;
              err = jvmti->SetEventCallbacks(&callbacks, sizeof(callbacks));
              check_jvmti_error(jvmti, err, "set event callbacks");
              err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
              JVMTI_EVENT_VM_INIT, NULL);
              check_jvmti_error(jvmti, err, "set event notifications");
              err = jvmti->SetEventNotificationMode(JVMTI_ENABLE,
              JVMTI_EVENT_VM_DEATH, NULL);
              check_jvmti_error(jvmti, err, "set event notifications");


              return 0;
              }

              /* Agent_OnUnload() is called last */
              JNIEXPORT void JNICALL
              Agent_OnUnload(JavaVM *vm)
              {
              }

              //}



              JNIEXPORT jint JNICALL Java_DLLTest_getDLLTest
              (JNIEnv *, jobject){
              jclass *classes;
              jint count;

              cout << "inside Java_DLLTest_getDLLTest method";
              jvmti->GetLoadedClasses(&count, &classes);
              cout << gdata->vmDeathCalled;
              return count;
              }
              & corresponding Java program for calling this agent is:-
              
              +++++++++++++++++++++++
              
              public class DLLTest {
              
                  public native int getDLLTest();
              
                  public native int getNuberofClassesLoaded();
              
                  static {
                      System.loadLibrary("DLLTest");
                  }
              
                  public static void main(String[] args) {
                      System.out.println(new DLLTest().getDLLTest());
                  }
              
              }
              
              ++++++++++++++++++++++
              
              
              Can you please help me why I am getting this error...
              
              Many thanks in advance..
              
              --pras                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                
              • 4. Re: help on writing & calling method written in JVMTI agent in java program
                843810
                prash wrote:
                Hi Swamy...

                Thanks for your reply.....


                Can you please exlain how to "call jvmti GetLoadedClass function.", inside the method "Java_foo_ladedClasses". Also how the other JVMTI objects initialized by Agent_onLoad will be available to this method?
                jvmti->GetLoadedClasses(&count, &classes);

                >
                Also I will not be loading agent by using "java -agentlib:........", instead I want to load agent by System.loadlibrary(.....), in this scenario the Agent_Onload will bet invoked?
                If you load jvmti agent using System.loadLibrary() it will invoke JNI_OnLoad. Agent_OnLoad() is not called so use
                JNI_OnLoad() callback to initialize jvmtiEnv. See jni examples for how to write JNI_OnLoad callback.

                Disadvantage of loading jvmti agent using System.loadLibrary() is you may not get some capabilities. Read jvmti doc for more information.
                • 5. Re: help on writing & calling method written in JVMTI agent in java program
                  843810
                  I can't debug your code but I guess you jvmtiEnv is not initialized. Set a break point in Agent_OnLoad and step through the code.
                  • 6. Re: help on writing & calling method written in JVMTI agent in java program
                    843810
                    Ok. Here is code for you.

                    jvmti.cpp
                    #include <stdio.h>
                    #include <stdlib.h>
                    #include <string.h>
                    #include "jni.h"
                    #include "jvmti.h"
                    
                    extern "C" {
                      jvmtiEnv *jvmti;
                    
                      JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) {
                        jint rc;
                        rc = vm->GetEnv((void **)&jvmti, JVMTI_VERSION);
                        if (rc != JNI_OK) {
                          return -1;
                        }
                        return JNI_VERSION_1_2;
                      }
                    
                      JNIEXPORT jint JNICALL Java_Foo_getNumberOfLoadedClasses(JNIEnv *, jobject){
                         jclass *classes;
                         jint count;
                    
                         jvmti->GetLoadedClasses(&count, &classes);
                      
                         return count;
                      }
                    }
                    Foo.java:
                    public class Foo {
                        static native int getNumberOfLoadedClasses(); 
                        static {
                         System.loadLibrary("jvmti");
                        }
                        public static void main(String argv[]) {
                         System.out.println (" Number of loaded Classes " + 
                                       getNumberOfLoadedClasses());
                        }
                    }
                    Do not use -agentlib:jvmti option for this example.
                    • 7. Re: help on writing & calling method written in JVMTI agent in java program
                      843810
                      Hi Swamy,

                      Thanks again for your patience & help. I am now one more step ahead in my JVMTI learning.

                      Many thanks!!!

                      --pras