| <html> | |
| <head> <title>JVM TI Demonstration Code</title> </head> | |
| <h1>JVM TI Demonstration Code</h1> | |
| <p> | |
| The | |
| Java<sup><font size=-2>TM</font></sup> Virtual Machine Tools Interface (JVM TI) | |
| is a native tool interface provided in JDK 5.0 and newer. | |
| Native libraries that use JVM TI and are loaded into the | |
| Java Virtual Machine | |
| via the -agentlib, -agentpath, or -Xrun (deprecated) interfaces, are | |
| called Agents. | |
| <p> | |
| <A HREF="http://java.sun.com/j2se/latest/docs/guide/jvmti">JVM TI</A> | |
| was designed to work with the | |
| Java Native Interface | |
| (<A HREF="http://java.sun.com/j2se/latest/docs/guide/jni">JNI</A>), | |
| and eventually displace the | |
| Java Virtual Machine Debugging Interface | |
| (<A HREF="http://java.sun.com/j2se/1.5.0/docs/guide/jpda/jvmdi-spec.html">JVMDI</A>) | |
| and the | |
| Java Virtual Machine Profiling Interface | |
| (<A HREF="http://java.sun.com/j2se/1.5.0/docs/guide/jvmpi/index.html">JVMPI</A>). | |
| <p> | |
| We have created a set of demonstration agents that should | |
| help show many of the features and abilities of the | |
| interface. This list of demonstration agents will change over time. | |
| They are provided as educational tools and as starting | |
| points for Java tool development. | |
| <p> | |
| These agents are built with every JDK build and some basic testing is performed | |
| on a regular basis, but no extensive testbases currently | |
| exist for these agents. | |
| Every JDK installation should include all the pre-built binaries and sources for | |
| all these agents, just look in the demo/jvmti directory of your JDK. | |
| <h2>Using or Running These Agents</h2> | |
| <p> | |
| Using these agents will require the VM to locate the shared library file | |
| before any actual Java code is run. | |
| The JDK installation should contain all the agent libraries in | |
| the ${JAVA_HOME}/demo/jvmti/<i>agent-name</i>/lib directories. | |
| The Solaris 64bit version would be contained in the sparcv9 or amd64 | |
| subdirectory. | |
| If 'java' complains that it can't find the library, | |
| you may need to add the directory containing the library into the | |
| LD_LIBRARY_PATH environment variable (Unix), or the PATH environment | |
| variable (Windows). | |
| This is system and platform specific. | |
| If you are using 64bit Solaris (e.g. 'java -d64'), | |
| you should use LD_LIBRARY_PATH64. | |
| Some agents such as hprof (heap/cpu profiler) and jdwp (debugger backend) | |
| are located inside the primary JDK directories and will always be found | |
| in those locations. | |
| <p> | |
| The agents that instrument classfiles | |
| (i.e. BCI, usually through the java_crw_demo library) | |
| such as hprof, heapTracker, mtrace, and minst, | |
| also need to have the Java classes they use available in the bootclasspath. | |
| The one used by hprof is already in the bootclasspath, and the | |
| other agents will make attempts at automatically adding their jar file | |
| (e.g. heapTracker.jar, mtrace.jar, or minst.jar) to the bootclasspath | |
| with AddToBootstrapClassLoaderSearch from JVM TI at startup | |
| (see the agent_util code). | |
| This is done by locating this jar file at | |
| ${JAVA_HOME}/demo/jvmti/<i>agent-name</i> | |
| where JAVA_HOME is obtained by calling GetSystemProperty from JVM TI | |
| with "java.home". | |
| We recognize that this is not ideal, but felt that as just demonstration | |
| code it was acceptable. | |
| Ideally the agent could find out the actual directory it came from and | |
| locate the jar file relative to that location. | |
| Our demonstration agents currently do not do this. | |
| <p> | |
| If you choose to modify or change these agents, the above information | |
| is important in making everything is found. | |
| It is recommended that you change the name of the agent when you | |
| modify it to avoid conflicts with the existing demo agents. | |
| Or better yet, go to http://jdk.dev.java.net and submit your | |
| changes to the agent as an RFE to the JDK. | |
| <h2> Demonstration Agents Available </h2> | |
| <ul> | |
| <li> | |
| <A HREF="versionCheck">versionCheck</A> | |
| <br> | |
| This is a extremely small agent that does nothing but check the | |
| version string supplied in the jvmti.h file, with the version | |
| number supplied by the VM at runtime. | |
| </li> | |
| <li> | |
| <A HREF="compiledMethodLoad">compiledMethodLoad</A> | |
| <br> | |
| This is a small agent that traces CompiledMethodLoad events along | |
| with the HotSpot specific compile_info parameter. | |
| </li> | |
| <li> | |
| <A HREF="mtrace">mtrace</A> | |
| <br> | |
| This is a small agent that does method tracing. | |
| It uses Bytecode Instrumentation (BCI) via the java_crw_demo library. | |
| </li> | |
| <li> | |
| <A HREF="minst">minst</A> | |
| <br> | |
| This is an even smaller agent that does just method entry tracing. | |
| It also uses Bytecode Instrumentation (BCI) via the java_crw_demo library, | |
| but the instrumentation code is pure Java (no Java native methods used). | |
| NOTE: Be sure to check out java.lang.instrument for a way to avoid | |
| native code agents completely. | |
| </li> | |
| <li> | |
| <A HREF="gctest">gctest</A> | |
| <br> | |
| This is a small agent that does garbage collection counting. | |
| </li> | |
| <li> | |
| <A HREF="heapViewer">heapViewer</A> | |
| <br> | |
| This is a small agent that does some basic heap inspections. | |
| </li> | |
| <li> | |
| <A HREF="heapTracker">heapTracker</A> | |
| <br> | |
| This is a small agent that does BCI to capture object creation | |
| and track them. | |
| It uses Bytecode Instrumentation (BCI) via the java_crw_demo library. | |
| </li> | |
| <li> | |
| <A HREF="waiters">waiters</A> | |
| <br> | |
| This is a small agent that gets information about threads | |
| waiting on monitors. | |
| </li> | |
| <li> | |
| <A HREF="hprof">hprof</A> | |
| <br> | |
| This is a large agent that does heap and cpu profiling. | |
| This demo agent is actually built into the | |
| Java Runtime Environment (JRE). | |
| It uses Bytecode Instrumentation (BCI) via the java_crw_demo library. | |
| <br> | |
| <b>Note:</b> hprof is NOT a small or simple agent, the other smaller demos | |
| should be looked at first. | |
| </li> | |
| </ul> | |
| <h2>Agent Support</h2> | |
| <ul> | |
| <li> | |
| <A HREF="java_crw_demo">java_crw_demo</A> | |
| <br> | |
| This is a demo C library that does class file to class file | |
| transformations or BCI (Bytecode Instrumentation). | |
| It is used by several of the above agents. | |
| </li> | |
| </ul> | |
| <h2>Native Library Build Hints</h2> | |
| <p> | |
| All libraries loaded into java are assumed to be MT-safe (Multi-thread safe). | |
| This means that multiple threads could be executing the code at the same | |
| time, and static or global data may need to be placed in critical | |
| sections. See the Raw Monitor interfaces for more information. | |
| <p> | |
| All native libraries loaded into the | |
| Java Virtual Machine, | |
| including Agent libraries, | |
| need to be compiled and built in a compatible way. | |
| Certain native compilation options or optimizations should be avoided, | |
| and some are required. | |
| More information on this options is available in the man pages for | |
| the various compilers. | |
| <p> | |
| Some native compiler and linker options can create fatal or | |
| erroneous behavior when native agent libraries are operating | |
| inside the Java Virtual Machine. | |
| It would take too many words to describe all the possible issues with all | |
| the native compiler options, optimizations, and settings. | |
| Here are some recommendations on the basic compiler and linker options | |
| we recommend: | |
| <ul> | |
| <h3> Solaris </h3> | |
| <li> | |
| On Solaris, using the Sun Studio 11 C compiler, | |
| the typical compile and link command lines might look something like: | |
| <br> | |
| For 32bit SPARC: | |
| <br> | |
| <code><ul> | |
| cc -xO2 -mt -xregs=no%appl -xmemalign=4s -xarch=v8 -KPIC -c <i>*.c</i> | |
| <br> | |
| cc -mt -xarch=v8 -z defs -ztext -G -o <i>libXXX.so *.o</i> -lc | |
| </code></ul> | |
| <br> | |
| For 64bit SPARC: | |
| <br> | |
| <code><ul> | |
| cc -xO2 -mt -xregs=no%appl -xarch=v9 -KPIC -c <i>*.c</i> | |
| <br> | |
| cc -mt -xarch=v9 -z defs -ztext -G -o <i>libXXX.so *.o</i> -lc | |
| </code></ul> | |
| <br> | |
| For X86: | |
| <br> | |
| <code><ul> | |
| cc -xO2 -mt -xregs=no%frameptr -KPIC -c <i>*.c</i> | |
| <br> | |
| cc -mt -z defs -ztext -G -o <i>libXXX.so *.o</i> -lc | |
| </code></ul> | |
| <br> | |
| For AMD64: | |
| <br> | |
| <code><ul> | |
| cc -xO2 -mt -xregs=no%frameptr -xarch=amd64 -KPIC -c <i>*.c</i> | |
| <br> | |
| cc -mt -xarch=amd64 -z defs -ztext -G -o <i>libXXX.so *.o</i> -lc | |
| </code></ul> | |
| <br> | |
| </li> | |
| <li> | |
| Architecture/File Format: | |
| For SPARC 32bit use <code>-xarch=v8</code>, | |
| for SPARC 64bit use <code>-xarch=v9</code>, | |
| for X86 (32-bit) | |
| <i> | |
| leave the option off or use <code>-xarch=generic</code> | |
| </i>, | |
| and for AMD64 (64bit) use <code>-xarch=amd64</code> | |
| with both C and C++. | |
| <br> | |
| This is to be specific as to the architecture and the file format | |
| of the .o files (and ultimately of the .so). | |
| </li> | |
| <li> | |
| MT-Safe, Position Independent: Use <code>-KPIC -mt</code> | |
| with both C and C++. | |
| </li> | |
| <li> | |
| Register usage: For SPARC (both 32bit and 64bit) use | |
| <code>-xregs=no%appl</code> and for X86 and AMD64 use <code>-xregs=no%frameptr</code> | |
| with both C and C++. | |
| </li> | |
| <li> | |
| Alignment: For SPARC 32bit use -xmemalign=4s and for SPARC 64bit do NOT use <code>-xmemalign=4</code> | |
| with both C and C++. | |
| </li> | |
| <li> | |
| Dependencies: Use <code>ldd -r <i>LibraryName</i></code>. | |
| <br> | |
| After the shared library has been built, the utility | |
| <code>ldd</code> can be used to verify that all dependent libraries | |
| have been satisfied, and all externs can be found. | |
| If <code>ldd</code> says anything is missing, it is very likely that the JVM will also | |
| be unable to load this library. | |
| This usually means that you missed some <code>-l<i>name</i></code> | |
| options when building the library, or perhaps forgot a <code>-R path</code> | |
| option that tells the library where to look for libraries at runtime. | |
| </li> | |
| <h3> Linux </h3> | |
| <li> | |
| On Linux, using the gcc version 3.2, | |
| the typical compile and link command lines might look something like: | |
| <br> | |
| For X86: | |
| <br> | |
| <code><ul> | |
| gcc -O2 -fPIC -pthread -DLINUX -c <i>*.c</i> | |
| <br> | |
| gcc -z defs -static-libgcc -shared -o <i>libXXX.so *.o</i> -lc | |
| </code></ul> | |
| <br> | |
| For AMD64: | |
| <br> | |
| <code><ul> | |
| gcc -O2 -fPIC -pthread -DLINUX -D_LP64=1 -c <i>*.c</i> | |
| <br> | |
| gcc -z defs -static-libgcc -shared -o <i>libXXX.so *.o</i> -lc | |
| </code></ul> | |
| <br> | |
| </li> | |
| <li> | |
| MT-Safe, Position Independent: | |
| Use <code>-fPIC -pthread</code>. | |
| </li> | |
| <li> | |
| Agent Demo Code: Needs -DLINUX | |
| </li> | |
| <li> | |
| Register Usage: Use <code>-fno-omit-frame-pointer</code>. | |
| <br> | |
| It is important that these libraries have frame pointer register usage, see the above comments on the Solaris | |
| <code>-xregs=no%frameptr</code> | |
| option. | |
| </li> | |
| <li> | |
| Library: Use -static-libgcc. | |
| <br> | |
| When building the shared library (-shared option), this option | |
| allows for maximum portability of the library between different | |
| flavors of Linux. | |
| The problem we have seen with Linux is that we cannot depend | |
| on a compatible shared gcc library existing on all the versions of | |
| Linux we can run on. | |
| By doing this static link, the version script becomes more | |
| important, making sure you don't expose any extern symbols | |
| you didn't intend to. | |
| </li> | |
| <li> | |
| Dependencies: Use <code>ldd -r <i>LibraryName</i></code>. | |
| <br> | |
| Provides the same checking as Solaris (see above). | |
| </li> | |
| <h3> Windows </h3> | |
| <li> | |
| On Windows and using the Microsoft C++ Compiler Visual Studio .NET 2003, | |
| the typical compile and link command lines might look something like: | |
| <br> | |
| For X86: | |
| <br> | |
| <code><ul> | |
| cl /O1 /MD /D _STATIC_CPPLIB /c <i>*.c</i> | |
| <br> | |
| link /dll /opt:REF /out:<i>XXX.dll *.obj</i> | |
| </code></ul> | |
| <br> | |
| For AMD64: | |
| <br> | |
| <code><ul> | |
| cl /O1 /MD /D _STATIC_CPPLIB /c <i>*.c</i> | |
| <br> | |
| link /dll /opt:REF /out:<i>XXX.dll *.obj</i> | |
| </code></ul> | |
| <br> | |
| </li> | |
| <li> | |
| Library: Use <code>/opt:REF </code> when building the dll. | |
| </li> | |
| <li> | |
| MS DLL Runtime: Use the <code>/MD /D _STATIC_CPPLIB</code> option. | |
| <br> | |
| This causes your dll to become dependent on just MSVCR*.DLL. | |
| The option /D _STATIC_CPPLIB prevents you from becoming dependent on the | |
| C++ library MSVCP*.DLL. | |
| This is what we use in the JDK, but there are probably many combinations | |
| that you could safely use, unfortunately there are many combinations | |
| of runtimes that will not work. | |
| Check the Microsoft site on proper use of runtimes. | |
| </li> | |
| <li> | |
| Dependencies: Use VC++ <code>dumpbin /exports</code> and the VC++ "Dependency Walker". | |
| <br> | |
| Provides dependency information similar to <code>ldd</code>. | |
| </li> | |
| </ul> | |
| <h2>For More Information</h2> | |
| <p> | |
| Remember, the complete source to all these agents is contained in the JDK | |
| installations at demo/jvmti. | |
| <p> | |
| For more detailed information on JVM TI, refer to | |
| <A HREF="http://java.sun.com/j2se/latest/docs/guide/jvmti"> | |
| http://java.sun.com/j2se/latest/docs/guide/jvmti.</A> | |
| <p> | |
| More information on using JNI and building native libraries refer to: | |
| <A HREF="http://java.sun.com/j2se/latest/docs/guide/jni"> | |
| http://java.sun.com/j2se/latest/docs/guide/jni</A>. | |
| <p> | |
| Additional information can also be found by doing a search on "jvmti" at | |
| <A HREF="http://java.sun.com/j2se">http://java.sun.com/j2se</A>. | |
| Various technical articles are also available through this website. | |
| And don't forget the | |
| Java Tutorials at | |
| <A HREF="http://java.sun.com/docs/books/tutorial">http://java.sun.com/docs/books/tutorial</A> | |
| for getting a quick start on all the various interfaces. | |
| <h2>Comments and Feedback</h2> | |
| <p> | |
| Comments regarding JVM TI or on any of these demonstrations should be | |
| sent through | |
| <A HREF="http://java.sun.com/mail">http://java.sun.com/mail/</A> | |
| </html> |