| <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 -mimpure-text -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 -mimpure-text -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 -mimpure-text. |
| <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 MSVCRT.DLL and/or |
| the newer C++ runtime MSVCR71.DLL. |
| The option /D _STATIC_CPPLIB prevents you from becoming dependent on the |
| C++ library MSVCP71.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> |