`
liudaoru
  • 浏览: 1575774 次
  • 性别: 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

    `gdb`(GNU调试器)和`strace`是两种强大的Linux系统级工具,它们主要用于理解和解决与程序执行相关的问题。在这里,我们将深入探讨这两个工具及其在ARM平台上的应用。 `gdb`是一个开源的、跨平台的调试器,它支持...

    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 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-5.15 arm和arm64架构,Android可用

    《strace-5.15在Android上的应用与解析》 在信息技术领域,尤其是在系统调试和性能分析中,strace是一个不可或缺的工具。它能够帮助我们跟踪和记录Linux系统调用,以及进程间的信号传递,从而揭示程序在操作系统...

    strace for windows 已编译 straceNT.exe

    标题提及的是"strace for windows 已编译 straceNT.exe",这表明我们讨论的是一个适用于Windows操作系统的strace工具,它已经被预先编译成可执行文件straceNT.exe。strace是一个在Unix-like系统中广泛使用的系统调用...

    strace-4.5.

    《深入理解strace工具:基于strace-4.5.15版本的探索》 在Linux操作系统中,strace是一个非常实用的系统调用跟踪工具,它能够帮助开发者和系统管理员深入了解程序与操作系统内核之间的交互。本文将围绕strace-...

    linux的strace命令(详解)

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

    arm平台的strace

    标题"arm平台的strace"指的是在ARM架构的计算机系统上使用的strace工具。strace是一个非常实用的系统调用跟踪工具,它允许开发者监控和记录程序执行过程中的系统调用以及接收到的信号,这对于调试、性能分析以及理解...

    strace跟踪工具使用手册

    Strace是一个在Linux环境下用于诊断、调试和跟踪系统调用和进程间通信的工具。它通过跟踪和记录指定进程对内核的调用和接收的信号,将系统调用的名字、参数、返回值打印出来,这对于解决和定位问题非常有帮助。 在...

    strace_pstack-master.zip_pstack_strace

    在Linux系统中,`strace`和`pstack`是两个非常重要的系统调用跟踪工具,它们对于理解和调试进程的行为有着不可替代的作用。本压缩包`strace_pstack-master.zip`包含了与这两个工具相关的脚本,旨在帮助用户深入学习...

    strace-4.5.15.tar.bz2.rar

    《深入理解strace工具:以strace-4.5.15为例》 在Linux操作系统中,strace是一个非常实用的系统调用跟踪工具,它能够帮助开发者和系统管理员了解程序在运行过程中与操作系统的交互细节,包括系统调用的使用、参数...

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

    在嵌入式Linux系统中,调试工具的使用对于开发者来说至关重要,其中`strace`是一个非常实用的系统调用跟踪工具。它可以帮助我们监控和记录应用程序执行时对系统调用的使用情况,以及相关的信号处理。这篇内容将详细...

    strace-4.5.20.tar.bz2

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

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

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

    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_source_code.tar.gz

    《深入剖析strace源码与Aarch64-Linux-GNU平台编译实践》 strace,这个在Linux世界中不可或缺的系统调用追踪工具,是开发者和系统管理员的得力助手。它允许我们监控进程对系统调用的使用情况,从而洞察程序运行的...

    Strace(Source_Code).zip_gnu strace pudn_strace

    Strace是一款强大的Linux系统工具,用于跟踪进程执行时的系统调用和信号。它能帮助开发者深入了解程序在操作系统级别如何工作,特别是在解决程序错误、性能问题或者分析与系统交互细节时非常有用。"Strace(Source_...

    strace-4.11 源码

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

Global site tag (gtag.js) - Google Analytics