Click to enter _ more _java thousand ask
1, how to write JVMTI Agent program
Learn JPDA look here: JPDA is what
Learn JVMTI look here: Jvmti is what
We need to write the agent in C + + and the JVM will call back the following interface functions at different times:
*jvm*options*reserved*jvm*options*reserved*jvm)
The first one is called when the JVM is started, the second is called when the JVM runs out of attach, and the third is called when the JVM unloads.
Where the *JVM parameter is passed into the JAVAVM pointer, which can be used to manipulate the jvm;*options parameter is the command line passed in parameter; *reserved is a reserved parameter.
Gives a simple function to run the load mode implementation: Print all classes that have been loaded successfully in the JVM. Specific as follows:
/** JVMTI agent** Created on:2016-07-02* author:sunjie*/#include <jvmti.h>#include <string>#include <cstring>#include <iostream>#include <list>#include <map>#include <set>#include <stdlib.h>#include <jni_md.h>Jniexport jint jnicall Agent_onattach (JAVAVM *JVM,Char*options,void*reserved) {jvmtienv *jvmti; Jint result = Jvm->getenv ((void* *) &JVMTI, jvmti_version_1_1);if(Result! = JNI_OK) {printf("error:unable to access jvmti!\n"); } Jvmtierror Err = (jvmtierror)0; Jclass *classes; Jint count; Err = jvmti->getloadedclasses (&count, &classes);//Get class if(ERR) {printf("Error:jvmti getloadedclasses failed!\n"); } for(inti =0; I < count; i++) {Char*sig; Jvmti->getclasssignature (Classes[i], &sig, NULL);//Get and Print class signature printf("CLS sig=%s\n", SIG); }returnErr;} JniexportvoidJnicall agent_onunload (JAVAVM *vm) {// nothing to do}
We named it agent.cpp, the next step is to compile it into a dynamic link library, different operating system commands are not the same, here the Mac system, for example, as follows:
g++-I${JAVA_HOME}/include/-I${JAVA_HOME}/include/darwin Agent.-fPIC-shared-o libagent.so
Because it is a Mac system, the introduction of ${java_home}/include/darwin,linux and Windows corresponding to the should be/include/linux, \include\win32.
Once executed, we will see the generated libagent.so file.
2. How to test the agent program
We already have the agent, let's test it. The test needs to have a target JVM, so we'll simply simulate one, specifically as follows:
publicclass TestMain { publicstaticvoidmain(String[] args) throws InterruptedException { System.out.println("JVMTI agent Test start"); int0; while (true) { Thread.sleep(1000); i++; } }}
The purpose of the dead loop is not to let it end, so we can use the JVMTI agent to operate. After the run, the results are as follows:
JVMTI Agent Test Start
At this point we need to load our agent through ATTACHAPI for the running JVM, we first obtain the PID of the target JVM (obtained through process monitoring), and then specify the path of the agent dynamic repository, as follows:
Learn more attachapi see here: [What Attachapi is][4]
public Class Testagent {public static void main (string[] args) throws Attachnotsupportedexception, IOException, Agentloadexception, agentinitializationexception {String pid = "831" ; //Java process PID String Agentpath = "/users/sunjie/desktop/libagent.so" ; //agent.so path String options = null ; //the parameters of the incoming agent Virtualmachine virtualmachine = Com.sun.tools.attach.VirtualMachine.attach (PID); Virtualmachine.loadagentpath (Agentpath, Options); Virtualmachine.detach (); }}
Here we need to introduce the ${java_home}/lib/tools.jar package and introduce the Com.sun.tools.attach package. After running, the following results appear in the console of the target JVM:
JVMTI Agent Test Start
CLS Sig=ljava/lang/classloader$nativelibrary;
CLS Sig=ljava/util/concurrent/concurrentmap;
CLS Sig=ljava/lang/error;
CLS Sig=[ljava/lang/error;
CLS Sig=ljava/util/set;
CLS Sig=ljava/util/weakhashmap;
CLS Sig=ljava/lang/ref/reference;
CLS Sig=[ljava/lang/ref/reference;
CLS Sig=ljava/lang/stackoverflowerror;
CLS Sig=ljava/io/serializable;
....
Successfully prints out all the classes that have been loaded successfully.
Incidentally, if you use the boot load mode, you need to add the following parameters when you run Testmain:
java -agentlib:Agent=opt1 TestMain
Note that the *options parameter is passed in here: opt1, however, our agent did not use him.
Learn more about the JVMTI features here: [What features JVMTI provides][5]
Java thousand asked _08jdk detailed (014) _ How to write JVMTI Agent program