Btrace 远程调试

Btrace GitHub链接

下载Btrace到本地
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

$ wget https://github.com/btraceio/btrace/releases/download/v1.3.11.3/btrace-bin-1.3.11.3.zip

$ unzip btrace-bin-1.3.11.3.zip -d ./btrace //解压到指定文件夹


$ vim /etc/profile
export BTRACE_HOME=/home/btrace; ## btrace安装目录
export PATH=$PATH:$BTRACE_HOME/bin;


$ btrace --version
BTrace v.1.3.11.3 (20181217)


$ jps //查看Java项目进程Pid 也可以 ps -ef |grep xxx

13890 Bootstrap


$ cd /home/btrace/bin

$ btrace 13890 ../samples/AllMethods.java //btrace <PID> XXX.java 执行命令

属性注解

1
@TLS标注的属性可以在追踪脚本的方法中通讯

方法注解
1
2
3
4
5
6
7
8
9
10
11
@OnMethod:指定该方法在什么情况下被执行,clazz属性指定要跟踪的类的全限定类名,也可以用正则表达式,
“/类名的Pattern/”匹配,如/javax\\.swing\\..*/;用”+类名”追踪所有子类,
如+java.lang.Runnable;用”@xxx”追踪用该注解注解过的类,
如@javax.jws.WebService。method属性指定要追踪的方法名称,也可以用正则表达式。
location属性用@Location来指定该方法在目标方法执行前(后、异常、某行、某个方法调用)被执行。
@OnTimer:定时执行该方法。
@OnExit:当脚本运行Sys.exit(code)时执行该方法。
@OnError:当脚本运行抛出异常时执行该方法。
@OnEvent:脚本运行时Ctrl+C可以发送事件。
@OnLowMemory:指定一个内存阀值,低于阀值值执行该方法。
@OnProbe:指定一个xml文件来描述在什么时候执行该方法。
方法参数注解
1
2
3
4
5
6
7
8
@Self:指目标对象本身。
@Retrun:指目标程序方法返回值(需要配合Kind.RETURN)。
@ProbeClassName:指目标类名。
@ProbeMethodName:指目标方法名。
@targetInstance:指@Location指定的clazz和method的目标(需要配合Kind.CALL)。
@targetMethodOrField:指@Location指定的clazz和method的目标的方法或字段(需要配合Kind.CALL)。
@Duration:指目标方法执行时间,单位是纳秒(需要需要配合Kind.RETURN或Kind.ERROR一起使用)。
AnyType:获取对应请求的参数,泛指任意类型。
追踪时机参数
1
2
3
4
5
6
7
8

Kind.Entry:开始进入目标方法时,默认值?。
Kind.Return:目标方法返回时。
Kind.Error:异常没被捕获被抛出目标方法之外时?。
Kind.Throw:异常抛出时?。
Kind.Catch:异常被捕获时。
Kind.Call:被调用时。
Kind.Line:执行到某行时。

Btrace 实例Demo

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51

import com.sun.btrace.annotations.*;
import com.sun.btrace.services.impl.Printer;
import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;

import java.lang.reflect.Field;


/**
* 拦截时机
* 不写Location,默认就是刚进入函数的时候(Kind.ENTRY)
* 异常抛出(Throw),
* 异常被捕获(Catch),
* 异常没被捕获被抛出函数之外(Error),主要用于对某些异常情况的跟踪。
* clazz 类名
* method 方法名
*/
@BTrace
public class DappDemo {
@Injected(ServiceType.RUNTIME)
private static Printer printer;
@TLS
static long beginTime;

@OnMethod(clazz = "com.xxx", method = "xxx")
public static void getTime() {
beginTime = BTraceUtils.timeMillis();
}

@OnMethod(clazz = "com.xxx", method = "xxx", location = @Location(value = Kind.RETURN))
public static void btraceDemo(@Self Object self,Integer chain, @ProbeClassName String probeClass, @ProbeMethodName String probeMethod, @Return AnyType result) {
//打印耗时
printer.println(" 耗时--->[" + (BTraceUtils.timeMillis() - beginTime) + "]" + " ms");
//打印类名
printer.println(" ClassName--->[" + probeClass + "]");
//打印方法名
printer.println("MethodName--->[" + probeMethod + "]");
//打印入参
printer.println(" Param--->chain: [" + chain + "]");

printer.println(" Result--->[" + result);


printer.println("当前Name属性值: " +BTraceUtils.get(BTraceUtils.field(BTraceUtils.classForName("com.XXX",BTraceUtils.contextClassLoader()), name(属性昵称), result));
//打印耗时
printer.println(" ==============");

}

}