Building Elephant Tracks
1. First, copy Makefile.inc to Makefile.local; in Makefile.local you will set local build parameters for your machine, in particular, you must set the following
2. make; make install
There is disagreement between different versions of jni.h on the const-ness of certain parameters. This can lead to the following error when attempting to build Elephant Tracks:
ETCallBackHandler.cpp: In function ‘_jobject* instNewObjectA(JNIEnv*, jclass, jmethodID, const jvalue*)’:
ETCallBackHandler.cpp:1385:66: warning: invalid conversion from ‘const jvalue*’ to ‘jvalue*’
This can be resolved by removing the -Werror g++ flag,
and adding -fpermissive.
Running Elephant Tracks
First, make sure that INSTALL_DIR is in the LD_LIBRARY_PATH
Then run any Java program with Elephant Tracks like so:
java -classpath <other-paths>:$ASMJAR -Xbootclasspath/a:$INSTALL_DIR \ -agentlib:ElephantTracks=<ElephantTracks Options>
Are represented as name=value pairs, and may be given on the command like so:
Note that JVMs often impose an (undocumented) limit on the length of the command strings passed to a JVMTI agent such as Elephant Tracks, and will silently truncate if this is limit is exceeded. For this reason, it is recommend that infrequently changing options are stored in an option file, and specify that option file on the command line (see below).
may be passed on the command line), one option per line.
This is the path ElephantTracks will use to start its own Java process (not the one running your program). It must include INSTALL_DIR, INSTALL_DIR/elephantTracksRewriter.jar, and the asm-3.3 jar file.
it is in. (for example, /usr/bin/java, not /usr/bin).
traceFile=>(gzip > foo.trace.gz)
Would pipe the trace output to gzip, and redirect the output from gzip to foo.trace.gz
generally give better performance, but will use more memory (approximately 40 bytes per record).
Names File Records
The entries in the names file map names of methods to numerical ids use in the trace.
Lines that start with # are comments.
C 0xcccc class-name [0xssss] (I:0xiiii)*
cccc = class id; ssss = superclass id;
iiii = superinterface id
I 0xiiii interface-name [0xssss] (I:0xiiii)*
C or I will be output when the id is assigned, which is on first
*mention*, and will be output again, possibly with more info,
such as superclass / superinterfaces, when *processed*. We
could perhaps distinguish a mention from a definition if you
think it would be easier ...
E 0xcccc class-name
marks end of processing a class/interface *definition*
(so now you know all the methods and fields)
F I/S 0xffff name 0xcccc class-name field-type
I = instance; S = static
ffff = field id; cccc = declaring class id
field-type is a descriptor (I, etc., or Jclassname; etc.)
N 0xmmmm 0xcccc class-name method-name descriptor flags
mmmm = method id; cccc = class id
flags can include I or S for instance or static,
with N added if native
S 0xmmmm 0xcccc 0xssss descriptor dims
For allocation sites
mmmm = method id; cccc = declaring class id;
ssss = site id (unique in run)
descriptor = type of thing allocated
dims = number of dimensions (0 for a scalar object)
Trace File Records
The entiries in the trace file represent events in the program execution.
Lines that start with # are comments.
There are several different kinds of allocation record, based on how the object was allocated. They all have the same general form:
<Type Character> <object-id> <size> <type> <site> <length> <thread-id>
A - Array allocation
I - Initial Heap Allocation (Allocated before Elephant Tracks started)
N - Allocated via the NEW byte code in the traced java program
P - Preexisting object; these are objects for which Elephant Tracks missed the actual object allocation, but discovered later.This can be due to objects from the constant pool, or VM bugs.
V - Objects allocated by the virtual machine.
The new object has ID object-id, which is used to refer to the object in later events; the size in bytes; the type (a Java type as a string); length field is 0 for non-arrays, and the length of the array for arrays, the ID of the allocating thread.
The size is the size of the object in bytes as reported by the VM (this includes object headers and possibly other VM structures).
D <object-id> <thread-id>
Object-id died, and its death occured in thread_id.
U <old-target-id> <object-id> <new-target-id> <field-id> <thread-id>
The field field-id in object object-id that used to point to old-target-id now points at new-target-id, and this update occured in thread-id.
An object-id of 0 indicates that this is an update to a static field.
M <method-id> <receiver-object-id> <thread-id>
A call to the method method-id with receiver object receiver-object-id in thread thread-id.
A origin receiver of 0 indicates that this was a static method
E <method-id> <receiver-object-id> <thread-id>
Return from method method-id with receiver object receiver-object-id in thread thread-id.
A receiver of 0 indicates this was a static method.
X <method-id> <receiver-object-id> <exception-id> <thread-id>
Exceptional exit from a method method-id, with reciever object receiver-object-id, exception object exception-id, in thread thread-id
T <method-id> <receiver-id> <exception-object-id> <thread-id>
An exception was thrown in the given method, with the given receiver, and with the exception obejct itself having the given id.
H <method-id> <receiver-id> <exception-object-id> <thread-id>
An exception was handled in the given method, with the given receiver, and with the exception object itself having the given id.