Btrace是一个jvm probe工具,可以灵活地声明刺探点并注入刺探逻辑。它自带的samples中有非常多的例子,本文列举了从这些例子中总结出来的刺探点声明。
构造函数刺探,重载的构造函数也可以
@BTrace public class OnThrow { // store current exception in a thread local // variable (@TLS annotation). Note that we can't // store it in a global variable! @TLS static Throwable currentException; // introduce probe into every constructor of java.lang.Throwable // class and store "this" in the thread local variable. @OnMethod( clazz="java.lang.Throwable", method="<init>" ) public static void onthrow(@Self Throwable self) { currentException = self; } @OnMethod( clazz="java.lang.Throwable", method="<init>" ) public static void onthrow(@Self Throwable self, String s) { currentException = self; } @OnMethod( clazz="java.lang.Throwable", method="<init>" ) public static void onthrow(@Self Throwable self, String s, Throwable cause) { currentException = self; } @OnMethod( clazz="java.lang.Throwable", method="<init>" ) public static void onthrow(@Self Throwable self, Throwable cause) { currentException = self; } // when any constructor of java.lang.Throwable returns // print the currentException's stack trace. @OnMethod( clazz="java.lang.Throwable", method="<init>", location=@Location(Kind.RETURN) ) public static void onthrowreturn() { if (currentException != null) { Threads.jstack(currentException); println("====================="); currentException = null; } } }
刺探一个类的所有子类
@BTrace public class Classload { @OnMethod( clazz="+java.lang.ClassLoader", method="defineClass", location=@Location(Kind.RETURN) ) public static void defineclass(@Return Class cl) { println(Strings.strcat("loaded ", Reflective.name(cl))); Threads.jstack(); println("=========================="); } } 另一个例子, @BTrace public class SubtypeTracer { @OnMethod( clazz="+java.lang.Runnable", method="run" ) public static void onRun(@ProbeClassName String pcn, @ProbeMethodName String pmn) { // on every Runnable.run() method entry print class.method print(pcn); print('.'); println(pmn); } }
使用正则表达式刺探多个方法
@BTrace public class AllMethods { @OnMethod( clazz="/javax\\.swing\\..*/", method="/.*/" ) public static void m(@ProbeClassName String probeClass, @ProbeMethodName String probeMethod) { print(Strings.strcat("entered ", probeClass)); println(Strings.strcat(".", probeMethod)); } }
刺探获得锁之后以及释放锁之前
@BTrace public class AllSync { @OnMethod( clazz="/javax\\.swing\\..*/", method="/.*/", location=@Location(value=Kind.SYNC_ENTRY, where=Where.AFTER) ) public static void onSyncEntry(Object obj) { println(Strings.strcat("after synchronized entry: ", identityStr(obj))); } @OnMethod( clazz="/javax\\.swing\\..*/", method="/.*/", location=@Location(Kind.SYNC_EXIT) ) public static void onSyncExit(Object obj) { println(Strings.strcat("before synchronized exit: ", identityStr(obj))); } }