btrace命令行使用
位于bin目录下面主要有6个脚本,3个windows的,另外3个是Linux的,分别是btrace、btracec、btracer。具体功能如下:
1、btrace
功能: 用于运行BTrace跟踪程序。
命令格式:
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp build/ 1200 AllCalls1.Java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可通过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。
2. btracec
功能: 用于预编译BTrace脚本,用于在编译时期验证脚本正确性。
btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数意义同btrace命令一致,directory表示编译结果输出目录。
3. btracer
功能: btracer命令同时启动应用程序和BTrace脚本,即在应用程序启动过程中使用BTrace脚本。而btrace命令针对已运行程序执行BTrace脚本。
命令格式:
btracer <pre-compiled-btrace.class> <application-main-class> <application-args>
参数说明:
pre-compiled-btrace.class表示经过btracec编译后的BTrace脚本。
application-main-class表示应用程序代码;
application-args表示应用程序参数。
该命令的等价写法为:
java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]* <MainClass> <AppArguments>
btrace脚本限制
In particular, a BTrace class
can not create new objects.
can not create new arrays.
can not throw exceptions.
can not catch exceptions.
can not make arbitrary instance or static method calls - only the public static methods of com.sun.btrace.BTraceUtils class may be called from a BTrace program.
can not assign to static or instance fields of target program's classes and objects. But, BTrace class can assign to it's own static fields ("trace state" can be mutated).
can not have instance fields and methods. Only static public void returning methods are allowed for a BTrace class. And all fields have to be static.
can not have outer, inner, nested or local classes.
can not have synchronized blocks or synchronized methods.
can not have loops (for, while, do..while)
can not extend arbitrary class (super class has to be java.lang.Object)
can not implement interfaces.
can not contains assert statements.
can not use class literals.
jvisualvm 插件
BTrace提供了jvisualvm插件,强烈推荐在jvisualvm中编写和测试BTrace脚本,启动、关闭、发送事件、增加classpath都非常方便。
btrace实例
[java] view plain copy print?
package baby.btrace;
public class CaseObject{
private static int sleepTotalTime=0;
private int sleepTotalTime2=0;
public boolean execute(int sleepTime) throws Exception{
System.out.println("sleep: "+sleepTime);
sleepTotalTime+=sleepTime;
sleepTotalTime2=sleepTotalTime+1;
sleep(sleepTime);
if(sleepTime%2==0)
return true;
else
return false;
}
public void sleep(int sleepTime) throws Exception {
Thread.sleep(sleepTime);
}
}
[java] view plain copy print?
package baby.btrace;
import java.util.Random;
public class CaseObjectMain {
int times = 10;
public static void main(String[] args) {
CaseObjectMain main= new CaseObjectMain();
try {
main.begin();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void begin() throws Exception{
CaseObject object=new CaseObject();
while(true){
times++;
boolean result=doWork(object);
Thread.sleep(1000);
}
}
public boolean doWork(CaseObject object) throws Exception{
Random random=new Random();
boolean temp= object.execute(random.nextInt(1000));
return temp;
}
}
1、获取返回值,参数等信息
[plain] view plain copy print?
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript {
/* put your code here */
/*指明要查看的方法,类*/
@OnMethod(
clazz="baby.btrace.CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
/*主要两个参数是对象自己的引用 和 返回值,其它参数都是方法调用时传入的参数*/
public static void traceExecute(@Self baby.btrace.CaseObject object,int sleepTime, @Return boolean result){
println("调用堆栈!!");
println(strcat("返回结果是:",str(result)));
jstack();
println(strcat("时间是:",str(sleepTime)));
}
}
2、获取对象属性值
[plain] view plain copy print?
/* BTrace Script Template */
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript {
/* put your code here */
/*指明要查看的方法,类*/
@OnMethod(
clazz="baby.btrace.CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
/*主要两个参数是对象自己的引用 和 返回值,其它参数都是方法调用时传入的参数*/
public static void traceExecute(@Self baby.btrace.CaseObject object,int sleepTime, @Return boolean result){
println("调用堆栈!!");
println(strcat("返回结果是:",str(result)));
jstack();
println(strcat("时间是:",str(sleepTime)));
}
}
3、获取方法执行时长
[plain] view plain copy print?
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript3 {
@TLS private static long startTime = 0;
@OnMethod(
clazz="baby.btrace.CaseObject",
method="execute"
)
public static void startExecute(){
startTime = timeNanos();
}
@OnMethod(
clazz="baby.btrace.CaseObject",
method="execute",
location=@Location(Kind.RETURN)
)
public static void endExecute(@Duration long duration){
long time = timeNanos() - startTime;
println(strcat("execute time(nanos): ", str(time)));
println(strcat("duration(nanos): ", str(duration)));
}
}
4、正则匹配和获取方法执行次数
[plain] view plain copy print?
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript4 {
private static long count;
@OnMethod(
clazz="/.*/",
method="execute",
location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")
)
public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,
@TargetInstance Object instance, @TargetMethodOrField String method){
println("====== ");
println(strcat("ProbeClassName: ",pcm));
println(strcat("ProbeMethodName: ",pmn));
println(strcat("TargetInstance: ",str(classOf(instance))));
println(strcat("TargetMethodOrField : ",str(method)));
count++;
}
@OnEvent
public static void getCount(){
println(strcat("count: ", str(count)));
}
}
5、正则和事件交互
[plain] view plain copy print?
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TracingScript5 {
private static long count;
@OnMethod(
clazz="/.*/",
method="execute",
location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")
)
public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,
@TargetInstance Object instance, @TargetMethodOrField String method){
println("====== ");
println(strcat("ProbeClassName: ",pcm));
println(strcat("ProbeMethodName: ",pmn));
println(strcat("TargetInstance: ",str(classOf(instance))));
println(strcat("TargetMethodOrField : ",str(method)));
count++;
}
@OnEvent
public static void getCount(){
println(strcat("count: ", str(count)));
}
@OnEvent("A")
public static void getCountA(){
println("==AAAA==== ");
println(strcat("count: ", str(count)));
}
@OnEvent("B")
public static void getCountB(){
println("==BBB==== ");
println(strcat("count: ", str(count)));
}
}
VisualVM 在线跟踪调试工具
最新推荐文章于 2024-09-12 10:25:47 发布