转自:http://kenwublog.com/btrace-theory-analysis
今天,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
转载请注明原文链接:http://kenwublog.com/btrace-theory-analysis
相关推荐
你还在为各种意想不到的状况烦恼吗?不知如何去及时了解jvm的运行情况吗?java线程、内存使用情况等都可以通过Btrace进行跟踪分析,了解系统运行情况,方便易用!
BTrace整个实现的原理是Java Agent+ASM+Java instrument+ Java Complier Api
BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace for OpenSolaris应用程序)。 BTrace动态地测试目标应用程序的类以注入跟踪代码(“字节代码跟踪”)。
BTrace是用于Java平台的安全,动态跟踪工具。 BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS)。 BTrace动态地检测目标应用程序的类以注入跟踪代码(“字节码跟踪”)。 ...
Linux与Java性能跟踪与分析工具.ppt ,讲得很不错,值得你拥有
主要介绍了Java软件生产监控工具Btrace使用方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
编译原理课程设计---java实现算符优先分析法
性能工具之Java调试工具BTrace入门(csdn)————程序
Java虚拟机实现原理分析.pdf
利用Java编写词法分析器,从文件cifafx.txt中读取程序,并对程序进行词法分析。
编译原理语义分析java实现 语义分析 歧义分析
c语言,Java,词法分析,词法分析界面,编译原理课程实验,这是完整的可运行源代码,是用intellij IDEA写的
1、项目开发工具为MyEclipse2014 2、使用了Struts2框架作为控制层 3、HTML5图形用户界面 4、JAVA语言写后端 该项目完成的功能有:自动消去规则左递归;自动计算出First、Follow集;自动构造预测分析表;可输入句子...
语法分析器java实现,包含词法分析器。程序代码作为词法分析器的输入,词法分析器的输出作为语法分析器的输入,由语法分析器输出语法分析的结果。
Btrace:java性能调优及问题追踪工具 Btrace:java性能调优及问题追踪工具
通过java实现编译原理中的词法分析功能主要包括: 1).识别简单语言的单词符号 2.识别简单语言的基本字、标识符、无符号整数、运算符和界符 例如: 输入: x:=9; if x>0 then x:=2*x+1/3 fi #(可以文件方式读入) ...
linux和windows通用,1.3.11...BTrace是一种安全,动态的Java跟踪工具。BTrace通过动态(字节码)检测正在运行的Java程序的类来工作。BTrace将跟踪操作插入到正在运行的Java程序的类中,并对跟踪的程序类进行热交换。
编译原理-LR0语法分析-java
由于这学期学了编译原理这门课,实验要求写词法分析器以及语法分析器,这才写的,不同网络其他的代码,我采用的是java实现的,也算费了好多脑细胞,希望能大伙看看咋样,不喜勿喷哦,各自学习就是了!
编译原理课程中的算符优先分析算法,Java实现