`
liudaoru
  • 浏览: 1559503 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

bStrace & sTrace[z]

阅读更多

 

两种不同的动态分析工具,BTrace主要针对java分析,STrace适合Linux下的应用分析。

 

======================================

 

BTrace:http://hi.baidu.com/whzkinger/blog/item/0f1271277c82760f918f9d04.html

 

STrace:跟踪程式执行时的系统调用和所接收的信号,http://www.yuanma.org/data/2007/0201/article_2213.htm

 

今天,Team Leader推荐了一个非常棒的动态跟踪分析工具 – BTrace。由于对它的实现原理非常感兴趣,于是花了点时间研究了一下,顺便写点心得。

什么是BTrace?
BTrace是SUN Kenai云计算开发平台下的一个开源项目。旨在为java提供安全可靠的动态跟踪分析工具。

Btrace基于动态字节码修改技术(Hotswap)来实现运行时java程序的跟踪和替换。(还记得javarebel不?)
Btrace的脚本是用纯java编写的,基于一套官方提供的annotation,使跟踪逻辑实现起来异常简单。

实现原理

用一个简单的公式来表述(从左往右的使用顺序):
Sun Attach API + BTrace脚本解析引擎 + Objectweb ASM + JDK6 Instumentation

1,Sun Attach API是充当动态加载 agent 的角色。
看下面的例子:

VirtualMachine vm = VirtualMachine.attach("1688"); // 1688是进程id
String agentJarPath = "E:\\agent.jar"; // agent jar路径
vm.loadAgent(agentJarPath); // 加载agent

这个例子动态地为一个已经启动的java附加一个agent上去.

 

2,BTrace解析引擎解析BTrace脚本。
摘自官方的一个例子:

import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class HelloWorld {
    @OnMethod(
        clazz="java.lang.Thread",
        method="start"
    )

    public static void func() {
        println("about to start a thread!");
    }
}

@OnMethod告诉Btrace解析引擎需要代理的类和方法。
这个例子的作用是当java.lang.Thread类的任意一个对象调用 start 方法后,会调用 func 方法。

 

3,解析完脚本后,Btrace会使用ASM将脚本里标注的类java.lang.Thread的字节码重写,植入跟踪代码或新的逻辑。
在上面那个例子中,Java.lang.Thread 这个类的字节码被重写了。并在start方法体尾部植入了 func 方法的调用.
ASM的使用,本文不做延伸。

 

4,利用instrumentation的retransformClasses,将原始字节码替换掉。
instrumentation例子:

import java.lang.instrument.ClassDefinition;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;

public class AgentMain {
    public static void agentmain(String agentArgs, Instrumentation inst)
            throws ClassNotFoundException, UnmodifiableClassException,
            InterruptedException {
        inst.addTransformer(new ClassFileTransformer() {
            public byte[] transform(ClassLoader l, String className, Class c, ProtectionDomain pd, byte[] b) throws IllegalClassFormatException {
                // BTrace解析脚本,利用asm重写bytecode,然后classLoader加载
            }
        }, true);
        inst.retransformClasses(java.lang.Thread.class);
    }
}

 

关于instrumentation的一些猜测
因为 instrumentation 不能添加,修改方法,字段名,所以我怀疑它的实现原理是用 JIT 生成机器码,利用机器码的优先执行来做class替换的。JIT本身会将调用次数频繁的方法编译成机器码。
还有一种猜测就是,备份堆里的老bytecode,然后直接替换为新的。不过这种方式貌似有点暴力。

另外,替换后的字节码是在新线程内才会生效的,老线程依旧用老的字节码在执行。
替换的类原有的字段值是保持不变的。

局限性

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.

上面是摘自官方的使用限制列表,从内容上可以看,BTrace的神通仅仅局限于只读操作。不仅强制要求java脚本需要提供public static方法.
而且,脚本里无法实例化对象,数组,不能抛异常或捕捉,不能有循环,内部类等等。
针对一些特殊对象,BTrace也是无能为力的。比如java.lang.Integer,Array等。

不过话说回来,BTrace应付大部分应用场景还是绰绰有余的。

打破局限性约束

1,自己做instrumentation的类替换,绕过BTrace的安全检查。
2,基于JVM TI自己写工具,上面的局限性将荡然无存,并且可以实现的功能会多很多。

参考资料:
BTrace 用户指南 http://kenai.com/projects/btrace/pages/UserGuide
BTrace 开发者指南 http://kenai.com/projects/btrace/pages/DeveloperGuide
Instrumentation文档http://java.sun.com/javase/6/docs/technotes/guides/instrumentation/index.html
Attach API 文档http://java.sun.com/javase/6/docs/technotes/guides/attach/index.html


全文转载自我的新博客文章 java动态跟踪分析工具BTrace实现原理 ,讨论请在javaeye。

分享到:
评论

相关推荐

    gdb-6.7&strace-4.5.15

    arm平台调试工具,gdb和strace

    免安装strace strace.zip

    免安装strace [root@vmtca-2003 strace-5.1]# ldd strace linux-vdso.so.1 (0x00007ffc14ffb000) librt.so.1 => /lib64/librt.so.1 (0x00007fe620539000) libc.so.6 => /lib64/libc.so.6 (0x00007fe620174000) ...

    strace调试工具移植.zip

    strace strace strace strace strace strace strace strace strace strace strace strace strace strace strace strace

    strace 各种架构的静态编译版本

    strace-armv4l 23-Sep-2014 12:38 277K strace-armv4tl 23-Sep-2014 12:39 295K strace-armv5l 23-Sep-2014 12:39 295K strace-armv6l 23-Sep-2014 12:39 295K strace-i486 23-Sep-2014 12:37 249K strace-i586...

    strace-4.5.20.tar.bz2

    strace 命令是一种强大的工具, 能够显示任何由用户空间程式发出的系统调用. strace 显示这些调用的参数并返回符号形式的值. strace 从内核接收信息, 而且无需以任何特别的方式来构建内核. strace 的每一行输出包括...

    strace-4.5.16.tar.bz2

    1.下载 strace-4.5.16.tar.bz2,不要下载最新的strace-4.5.18.tar.bz2,因为后者编译会出错。下载网址是:http://sourceforge.net/project/showfiles.php?group_id=2861&package_id=2819; 2.配置。./configure --...

    strace-4.11 源码

    strace-4.11 源码。 strace是一个可用于诊断、调试和教学的Linux用户空间跟踪器。我们用它来监控用户空间进程和内核的交互,比如系统调用、信号传递、进程状态变更等

    linux的strace命令(详解)

    linux的strace命令(详解) strace 命令是一种强大的工具,它能够显示所有由用户空间程序发出的系统调用。 strace 显示这些调用的参数并返回符号形式的值。strace 从内核接收信息,而且不需要以任何特殊的方式来构建...

    使用 strace 命令来监控内存分配,找出OOM的原因

    使用 strace 命令来监控内存分配,找出OOM的原因 由于使用 Netty 导致的,那错误日志里可能会出现 OutOfDirectMemoryError 错误 如果直接是 DirectByteBuffer,那会报 OutOfMemoryError Direct buffer memory

    strace-4.5.

    strace-4.5.15.tar(1).

    strace mv A B

    本附件是执行strace mv A B打印出的调用栈

    strace-5.12.tar.xz

    strace-5.12移植 配置 ./configure --prefix=$PWD/arm_strace --host=arm-linux CC=arm-linux-gnueabihf-gcc LD=arm-none-linux-gnueabihf-ld make && make install

    strace python3.6部分日志.txt

    strace python3.6部分日志,定位No module named 'pip'问题

    strace工具5.3版本

    Strace is a diagnostic, debugging and instructional userspace utility for Linux. It is used to monitor and tamper with interactions between processes and the Linux kernel, which include system calls, ...

    strace for windows 已编译 straceNT.exe

    之前上传了strace for windows 源码,但有些人表示 不会编译,现在上传已经编译后的straceNT.exe,可以直接运行。编译环境为Windows 10 x64位操作系统。

    arm平台的strace

    移植strace到arm平台,并编译为静态连接,直接把strace拷到/bin下即可使用

    strace跟踪工具使用手册

    非常详细地介绍了strace系统调用跟踪工具的使用方法,列举了工程实践中常遇到的调试手段和解决方法。

    嵌入式linux下移植strace调试应用程序工具源码

    该压缩包是嵌入式linux下移植strace调试工具源码包,并且最重要里面还有一份移植文档,该文档内容会手把手教你编译安装和使用strace调试工具

    ARM调试工具strace4.7

    strace4.7,解决使用4.3.3无法调试的问题,亲测可用,可以对ARM板进行调试。

Global site tag (gtag.js) - Google Analytics