Btrace provides annotations to allow users to specify probes and actions easily.
For example, with the annotation, we can specify the control stops at the thread.start(), and carry out the action of printing several words to console.
Seems, BTrace is well designed to include versatile probes (annotations), including the synchronization operations.
I would give it a try before developing my own agents. If it is competent in my task, I will directly use it.
Otherwise, I might handle the refections (as in tamiflex) and develop my own agents.
Anyway, have a try on btrace first.
==============================
after trying the Btrace, I find it works badly, at least for my case.
Let us see their running example in the webpage: printing the message when a thread is started.
First, the annotation file:
// import all BTrace annotations
import com.sun.btrace.annotations.*;
// import statics from BTraceUtils class
import static com.sun.btrace.BTraceUtils.*;
// @BTrace annotation tells that this is a BTrace program
@BTrace
public class HelloWorld {
// @OnMethod annotation tells where to probe.
// In this example, we are interested in entry
// into the Thread.start() method.
@OnMethod(
clazz="java.lang.Thread",
method="start"
)
public static void func() {
// println is defined in BTraceUtils
// you can only call the static methods of BTraceUtils
println("about to start a thread!");
}
}
Then, the program being instrumented:
public class Simple
{
static int sharedV= 0;
static int sharedM =0;
public static void main (String [] args)
{
System.out.println(Thread.currentThread().hashCode());
System.out.println("to start");
Thread t1 = new Thread(){
public void run()
{
System.out.println("started");
//System.out.println(Thread.currentThread().hashCode());
synchronized ("ss") {
sharedV =1;
sharedM =2;
sharedV =3;
sharedM =4;
}
}
};
Thread t2 = new Thread(){
public void run()
{
sharedM =10;
sharedV =20;
}
};
t1.start();
t2.start ();
try {
t1.join();
t2.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Now, we ollow their instruction to compile and run the instrumentation code.
1 btracec HelloWorld.java
2 btracer HelloWorld.class Simple
No output is printed.
I open the debug mode, and find that, the instrumentation inappropriately happens after the thread.start() statements.
From the trace information (in the following), the instrumentation happens after the thread.start() is executed, therefore, the instrumentation does not affect the thread.start() at all. To conclude, the agent fails to finish its task: instrumenting the thread.start() and printing information. The underlying reason is that, it does not provide a timely update. I have to develop my own agents... disappointed with Btrace.
Finally, I understand why there are so few information about Btrace on the internet.
btrace DEBUG: debugMode is true btrace DEBUG: unsafeMode is true btrace DEBUG: dumpClasses is false btrace DEBUG: stdout is true btrace DEBUG: probe descriptor path is . btrace DEBUG: initial script is HelloWorld.class btrace DEBUG: verifying BTrace class btrace DEBUG: verified 'HelloWorld' successfully btrace DEBUG: created class filter btrace DEBUG: preprocessing BTrace class HelloWorld btrace DEBUG: preprocessed BTrace class HelloWorld btrace DEBUG: creating BTraceRuntime instance for HelloWorld btrace DEBUG: created BTraceRuntime instance for HelloWorld btrace DEBUG: removing @OnMethod, @OnProbe methods btrace DEBUG: removed @OnMethod, @OnProbe methods btrace DEBUG: sending Okay command btrace DEBUG: client HelloWorld: got com.sun.btrace.comm.OkayCommandlpxz@15ee671 btrace DEBUG: about to defineClass HelloWorld btrace DEBUG: defineClass succeeded for HelloWorld btrace DEBUG: parsed command line arguments btrace DEBUG: noServer is true, server not started btrace DEBUG: new Client created com.sun.btrace.agent.FileClientlpxz@6d084b btrace DEBUG: filtering loaded classes btrace DEBUG: client HelloWorld: skipping transform for java/util/Collections$EmptySet$1 btrace DEBUG: client HelloWorld: skipping transform for java/util/HashMap$EntrySet btrace DEBUG: client HelloWorld: skipping transform for java/util/HashMap$EntryIterator btrace DEBUG: candidate class java.lang.Thread added // why add it as a candidate? give me a timely update!!! btrace DEBUG: client HelloWorld: skipping transform for sun/misc/URLClassPath$FileLoader$1 btrace DEBUG: client HelloWorld: skipping transform for Simple btrace DEBUG: client HelloWorld: skipping transform for Simple$1 btrace DEBUG: client HelloWorld: skipping transform for Simple$2 15582114 to start btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/parser/SignatureParser btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/TypeArgument btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/TypeTree btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/Tree btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/SimpleClassTypeSignature btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/FieldTypeSignature btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/BaseType btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/TypeSignature btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/ReturnType btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/tree/ClassTypeSignature btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/scope/ClassScope btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/scope/Scope btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/scope/AbstractScope btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/factory/CoreReflectionFactory btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/factory/GenericsFactory btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/visitor/Reifier btrace DEBUG: skipping transform for BTrace class sun/reflect/generics/visitor/TypeTreeVisitor started // where is the agent? why does not it work? btrace DEBUG: client HelloWorld: skipping transform for java/lang/reflect/GenericArrayType btrace DEBUG: client HelloWorld: skipping transform for java/lang/annotation/RetentionPolicy btrace DEBUG: skipping transform for BTrace class sun/reflect/annotation/AnnotationType$1 btrace DEBUG: skipping transform for BTrace class sun/reflect/annotation/ExceptionProxy btrace DEBUG: client HelloWorld: skipping transform for java/lang/annotation/Retention btrace DEBUG: client HelloWorld: skipping transform for java/lang/annotation/Inherited btrace DEBUG: client HelloWorld: skipping transform for java/lang/Class$4 btrace DEBUG: skipping transform for BTrace class sun/reflect/annotation/AnnotationTypeMismatchExceptionProxy btrace DEBUG: skipping transform for BTrace class sun/reflect/annotation/AnnotationInvocationHandler btrace DEBUG: client HelloWorld: skipping transform for java/lang/reflect/InvocationHandler btrace DEBUG: client HelloWorld: skipping transform for java/lang/reflect/Proxy btrace DEBUG: client HelloWorld: skipping transform for java/util/WeakHashMap btrace DEBUG: client HelloWorld: skipping transform for java/util/WeakHashMap$Entry btrace DEBUG: client HelloWorld: skipping transform for java/util/Arrays$ArrayList btrace DEBUG: client HelloWorld: skipping transform for java/util/IdentityHashMap$KeySet btrace DEBUG: client HelloWorld: skipping transform for java/util/IdentityHashMap$KeyIterator btrace DEBUG: client HelloWorld: skipping transform for java/util/IdentityHashMap$IdentityHashMapIterator btrace DEBUG: client HelloWorld: skipping transform for java/io/DeleteOnExitHook btrace DEBUG: client HelloWorld: skipping transform for java/util/LinkedHashSet btrace DEBUG: client HelloWorld: skipping transform for java/util/LinkedHashMap$KeyIterator btrace DEBUG: client HelloWorld: skipping transform for java/util/LinkedHashMap$LinkedHashIterator btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator btrace DEBUG: skipping transform for BTrace class sun/security/action/GetBooleanAction btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$ConstantPool btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$ProxyMethod btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$MethodInfo btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$ConstantPool$ValueEntry btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$ConstantPool$Entry btrace DEBUG: client HelloWorld: skipping transform for java/io/DataOutputStream btrace DEBUG: client HelloWorld: skipping transform for java/io/DataOutput btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$ConstantPool$IndirectEntry btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$FieldInfo btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$PrimitiveTypeInfo btrace DEBUG: client HelloWorld: skipping transform for sun/misc/ProxyGenerator$ExceptionTableEntry btrace DEBUG: client HelloWorld: skipping transform for $Proxy0 btrace DEBUG: client HelloWorld: skipping transform for java/lang/annotation/Target btrace DEBUG: client HelloWorld: skipping transform for java/lang/annotation/ElementType btrace DEBUG: client HelloWorld: skipping transform for java/lang/annotation/Documented btrace DEBUG: client HelloWorld: skipping transform for $Proxy1 btrace DEBUG: client HelloWorld: skipping transform for $Proxy2 btrace DEBUG: client HelloWorld: skipping transform for $Proxy3 btrace DEBUG: client HelloWorld: skipping transform for java/util/LinkedHashMap$EntryIterator btrace DEBUG: added as ClassFileTransformer btrace DEBUG: client HelloWorld: got com.sun.btrace.comm.RetransformationStartNotificationlpxz@152513a btrace DEBUG: calling retransformClasses (1 classes to be retransformed) btrace DEBUG: client HelloWorld: instrumenting java/lang/Thread It is too late to instrument the Thread.class