BTrace简介

BTrace是一个安全动态的跟踪java程序的工具。BTrace通过hotswap技术,动态地注入字节码到运行的java程序中。

术语

  • Probe Point
    在何处执行我们希望注入的trace语句, 这里的”何处”可以是具体的跟踪地点和执行事件,。在BTrace中通过各种注解来指定
  • Trace Actions or Actions
    我们希望执行的trace语句
  • Action Methods
    定义在trace脚本中的trace语句, 具体来说就是脚本中的无返回值静态方法

BTrace 程序结构

BTrace程序是由一个或多个如以下示例一样拥有BTrace注释的方法构成的。

public static void

BTrace注释是用来标识需要跟踪的地方(Probe Point)。跟踪的行为在静态的方法体里面定义,这些方法被称为“action”方法

BTrace限制

为了保证trace语句对目标跟踪程序的侵入是只读的(不能改变目标跟踪程序的状态)且有限的(跟踪脚本代码必须在有限的时间内完成), BTrace对trace脚本有一些限制
BTrace class不能新建类, 新建数组, 抛异常, 捕获异常,
不能调用实例方法以及静态方法(com.sun.btrace.BTraceUtils除外)
不能将目标程序的类和对象赋值
不能定义外部, 内部, 匿名, 本地类
不能有同步块和方法
不能有循环
不能实现接口, 不能扩展类
不能使用assert语句, 不能使用class字面值

简单的BTrace示例

  1. 下载BTrace包
    https://kenai.com/projects/btrace/downloads/directory/releases
    我下载的版本是 release-1.2.5.1
  2. 解压缩

    hsu@ubuntu:~/btrace$ ls
    bin                COPYRIGHT    README.txt
    btrace-bin.tar.gz  docs         samples
    build              LICENSE.txt  THIRDPARTYLICENSEREADME.txt
    

    打开bin文件夹执行如下语句

    chmod +x btrace
  3. 目标程序内容

    package com.btrace.example;
    import java.util.Random;
    public class Case1 {
    public static void main(String[] args) throws Exception {
        Random random = new Random();
        CaseObject object = new CaseObject();
        boolean result = true;
        while (result) {
            result = object.execute(random.nextInt(1000));
            Thread.sleep(1000);
        }
    }
    }
    
    package com.btrace.example;
    public class CaseObject {
    private static int sleepTotalTime = 0;
    
    public boolean execute(int sleepTime) throws Exception {
        System.out.println("sleep: " + sleepTime);
        sleepTotalTime += sleepTime;
        Thread.sleep(sleepTime);
        return true;
    }
    }
    
  4. btrace脚本

    package com.btrace.example;
    import static com.sun.btrace.BTraceUtils.*;
    import com.sun.btrace.annotations.*;
    @BTrace
    public class TraceMethodArgsAndReturn {
    @OnMethod(clazz = "com.btrace.example.CaseObject", method = "execute", location = @Location(Kind.RETURN))
    public static void traceExecute(@Self CaseObject instance, int sleepTime,
        @Return boolean result) {
    println("call CaseObject.execute");
    println(strcat("sleepTime is:", str(sleepTime)));
    println(strcat("sleepTotalTime is:",
            str(get(field("com.btrace.example.CaseObject", "sleepTotalTime"), instance))));
    println(strcat("return value is:", str(result)));
    }
    }
    package com.btrace.example;
    import static com.sun.btrace.BTraceUtils.*;
    import com.sun.btrace.annotations.*;
    
    @BTrace
    public class TraceMethodExecuteTime {
    
    @TLS
    static long beginTime;
    
    @OnMethod(clazz = "com.btrace.example.CaseObject", method = "execute")
    public static void traceExecuteBegin() {
        beginTime = timeMillis();
    }
    
    @OnMethod(clazz = "com.btrace.example.CaseObject", method = "execute", location = @Location(Kind.RETURN))
    public static void traceExecute(int sleepTime, @Return boolean result) {
        println(strcat(
                strcat("CaseObject.execute time is:", str(timeMillis()
                        - beginTime)), "ms"));
    }
    }
    
  5. 执行BTrace脚本
    首先取得目标java进程id(pid), 然后执行命令行: btrace
    完整的BTrace命令:

    btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]

    -I 没有这个表明跳过预编译
    include-path: 指定用来编译脚本的头文件路径(关于预编译可参考例子ThreadBean.java)
    port : btrace agent端口, 默认是2020
    classpath : 编译所需类路径, 一般是指btrace-client.jar等类所在路径
    pid : java进程id
    btrace-script: btrace脚本, 如果是java文件, 则是未编译, class文件, 则是已编译过的
    args: 传递给btrace脚本的参数, 在脚本中可以通过 (), length()来获取这些参数(定义在BTraceUtils中)

编译好后的btrace脚本 不用指定classpath
hsu@ubuntu:~/workspace_btrace$ /home/hsu/btrace/bin/btrace 6786            /home/hsu/workspace_btrace/BtraceExample/bin/com/btrace/example/TraceMethodArgsAndReturn.class 

btrace脚本源代码 需要指定classpath
hsu@ubuntu:~/workspace_btrace$ /home/hsu/btrace/bin/btrace  -cp /home/hsu/workspace_btrace/BtraceExample/bin/ 6786  /home/hsu/workspace_btrace/BtraceExample/src/com/btrace/example/TraceMethodArgsAndReturn.java 

官网上还有很多BTrace的example
有一个很好的实际应用中的例子 http://blog.csdn.net/mgoann/article/details/7268657

实现原理

这篇文章http://agapple.iteye.com/blog/1005918讲的很好,建议大家去看看

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值