Btrace及Dtrace实战之BTRACE
最早接触的是btrace,那会在2010年就听说了,后来又听说了Dtrace,今天放假回来就总结总结这两个线上调试利器。
源码下载地址是:http://kenai.com/projects/btrace/downloads 看主页上的最近更新时间都是2年前了,release的更新更是在三年前,好东西虽然不常更新,但确经久待用。在iteye上搜索可下btrace,发现几篇老东家同事写的:
http://www.iteye.com/topic/1005918
http://www.iteye.com/topic/586630
都写的很好,从实现原理到代码级别的解读,我这里就不做重复的事情了,只写点自己的感受!
tips:
源码是通过,Mercurial管理的
下载代码:hg clone https://hg.kenai.com/hg/btrace~hg
它干什么的?
对于程序员来说最头大的问题之一就是线上出了故障了,但是我们无法debug来找出问题原因,同时在上线的时候日志级别限定了我们不可能把所有的细节都打印到log上,这个时候故障都等在哪里,能办的手段无非看源码,通过仔细看代码来找出问题,并编译重新上线解决,这种手段能解决一部分代码,但是对于一些隐藏较深的bug就无能为力了,例如OOM或是频繁的full gc,一般是一个很多的对象没有被释放或是一个对象被频繁的创建调用,若是大对象的问题还好说,通过jmap+MAT都可以找出,若是后者的话,就够你头大的了,笔者之前遇见一个OOM问题就是一个对象被频繁创建,最后查找时是一个开源软件包中的问题,这种方式指望通过看源码是很难解决的,那么还好有btrace脚本。
开始搞吧
即然上面提到了对象的调用创建,就先看看如何通过Btrace来查找一个类都被谁调用了,五步骤即可:
1)需要一个开始的类:
package com.zhaming.trace.btrace;
import java.util.Random;
public class StartObject {
public static void main(String[] args) throws InterruptedException {
Random random = new Random();
ActionObject actionObject = new ActionObject();
while (true) {
int sleepTime = random.nextInt(1000);
actionObject.work(sleepTime);
Thread.sleep(1000);
}
}
}
2)一个被执行的类:ActionObject
package com.zhaming.trace.btrace;
public class ActionObject {
private static int totalTimes = 0;
public int work(int sleepTime) throws InterruptedException {
System.out.println("sleep " + sleepTime);
totalTimes += sleepTime;
Thread.sleep(sleepTime);
return totalTimes;
}
}
3)查看的具体脚本:
package com.zhaming.trace.btrace;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace
public class TraceObject {
@OnMethod(clazz = "com.zhaming.trace.btrace.ActionObject", method = "work", location = @Location(value = Kind.CALL, clazz = "/.*/", method = "/.*/"))
public static void checkWhoCallMe() {
println("check who ActionObject.work method:");
jstack();
}
}
4)通过jps命令获取进程ID:
inter12@inter12-VirtualBox:~/install/soft/btrace/bin$ jps
10617 Jps
10600 StartObject
1876 org.eclipse.equinox.launcher_1.2.0.v20110502.jar
5)执行btrace脚本
inter12@inter12-VirtualBox:~/workspace/Light/target/classes$ btrace -cp /home/inter12/workspace/Light/target/classes 10600 /home/inter12/workspace/Light/src/main/java/com/zhaming/trace/btrace/TraceObject.java
check who ActionObject.work method:
com.zhaming.trace.btrace.ActionObject.work(ActionObject.java:9)
com.zhaming.trace.btrace.StartObject.main(StartObject.java:14)
check who ActionObject.work method:
com.zhaming.trace.btrace.ActionObject.work(ActionObject.java:9)
com.zhaming.trace.btrace.StartObject.main(StartObject.java:14)
在终端我们看到StartObject类中执行科ActionObject.work方法,如此即可找到我们想要的执行对象。
回到开头
现在再回过头来看看我们上面干了什么,第一到第二步都可以忽略,是为了准备测试的数据,直接看第三步骤,我们主要加了两个标注
@BTrace //这里告诉btrace这是一个调试脚本
public class TraceObject {
// // 这里说我们查看哪个类的哪个方法,最好的办法是写类名的全路径,比较存在重复类名的情况,个人实际试过,若是重复的话,会执行第一个被加载的类
@OnMethod(clazz = "com.zhaming.trace.btrace.ActionObject", method = "work", location = @Location(value = Kind.CALL, clazz = "/.*/", method = "/.*/"))
public static void checkWhoCallMe() {
// 对这些类的这些方法做什么操作,这里是简单的执行了jstatck命令,获取是谁调用了我那么执行的方法
println("check who ActionObject.work method:");
jstack();
}
}
最后的命令是: btrace -cp /home/inter12/workspace/Light/target/classes 10600 /home/inter12/workspace/Light/src/main/java/com/zhaming/trace/btrace/TraceObject.java(-cp后面跟的是你代码中依赖的类)
简缩后就是 btrace -cp 【指定的类路径】 【PID】 XXX.JAVA 如此就搞定了btrace,相当的简单!还有点需要注意的话,若你下载btrace是1.2版本之前的话,那么TraceObject中的类必须是静态的static,1.2版本以后没有这个要求!
若是想知道 ActionObject类中totalTimes的值的话,可以写下面的脚本
package com.zhaming.trace.btrace;
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
@BTrace
public class TraceObjectValue {
@OnMethod(clazz = "com.zhaming.trace.btrace.ActionObject", method = "work", location = @Location(Kind.RETURN))
public static void getMethodValueAndReturn(@Self com.zhaming.trace.btrace.ActionObject instance ,int sleepTime,@Return int totalTime) {
println("call ActionObject work method:");
println(strcat("sleepTime", str(sleepTime)));
println(strcat("return total timeL", str(get(field("com.zhaming.trace.btrace.ActionObject", "totalTimes"), instance))));
}
}
执行脚本:
inter12@inter12-VirtualBox:~/workspace/Light/target/classes$ btrace -cp /home/inter12/workspace/Light/target/classes 11939 /home/inter12/workspace/Light/src/main/java/com/zhaming/trace/btrace/TraceObjectValue.java
call ActionObject work method:
sleepTime45
return total timeL11267
call ActionObject work method:
sleepTime513
return total timeL11780
call ActionObject work method:
sleepTime845
若是得到一个方法的执行时间的话,可以参见如下:
package com.zhaming.trace.btrace;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace
public class TraceObjectCost {
@TLS
static long startTime;
@OnMethod(clazz = "com.zhaming.trace.btrace.ActionObject", method = "work", location = @Location(Kind.RETURN))
public static void start() {
startTime = timeMillis();
}
@OnMethod(clazz = "com.zhaming.trace.btrace.ActionObject", method = "work", location = @Location(Kind.RETURN))
public static void getMethodExecuteCost(int sleepTime,@Return int totalTime) {
String str = str(timeMillis() - startTime);
String strcat = strcat("execute work method cost:", str);
String strcat2 = strcat(strcat, " ms");
println(strcat2);
}
}
执行脚本:
inter12@inter12-VirtualBox:~/workspace/Light/target/classes$ btrace -cp /home/inter12/workspace/Light/target/classes 13191 /home/inter12/workspace/Light/src/main/java/com/zhaming/trace/btrace/TraceObjectCost.java
execute work method cost:1357295586155 ms
execute work method cost:1410 ms
execute work method cost:1005 ms
execute work method cost:1335 ms
execute work method cost:1448 ms
若是期望的到一个method哪几行被执行了的话,可以试试下面的脚本:
package com.zhaming.trace.btrace;
import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace
public class TraceObjectMethodLineCall {
@OnMethod(clazz="com.zhaming.trace.btrace.ActionObject",method="work",location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/"))
public static void lineCall(@Self com.zhaming.trace.btrace.ActionObject self, @TargetMethodOrField String method, @ProbeMethodName String probeMethod){
println(Strings.strcat(method, Strings.strcat(" in ", probeMethod)));
}
}
TargetMethodOrField :目标对象
ProbeMethodName :调用对象
执行脚本:
inter12@inter12-VirtualBox:~/workspace/Light/target/classes$ btrace -cp /home/inter12/workspace/Light/target/classes 13544 /home/inter12/workspace/Light/src/main/java/com/zhaming/trace/btrace/TraceObjectMethodLineCall.java
append in work
toString in work
println in work
sleep in work
分享到:
相关推荐
Dtrace实战运用 A genda Dtrace架构 Dtrace的高级语法 Dtrace实战案例 利用NETBEANS来开发和Dtrace工具 Q/A
BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace for OpenSolaris应用程序)。 BTrace动态地测试目标应用程序的类以注入跟踪代码(“字节代码跟踪”)。
dtrace 用户指南 中文版
dtrace 使用教程
HOW to USE DTrace,讲述怎么使用Dtrace的方法以及实践,sun官方的资源
oracle 的dtrace实现标准
Dtrace 反向工程说明,对unix进行分析,跟踪的必备工具
awesome-dtrace, 出色的DTrace书籍文章视频工具和资源的精选列表 出色的DTrace 出色的DTrace书籍。文章。视频。工具和资源的精选列表。电子邮件内容学习学习。文章视频软件工具插件社区服务 。学习用于学习DTrace的...
SUN Solaris DTrace userguide2.pdf
通过本讲座,听众可以了解到DFrame的框架结构,DFrame和BTrace以及DTrace的关系,本讲座还将通过现场的演示让听众直观的了解到如何利用DFrame来进行Weblogic调优,以及DFrame和其他传统Java调优工具相比较所具有的...
这是SUN dtrace的官方说明稳当。
BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS)。 BTrace动态地检测目标应用程序的类以注入跟踪代码(“字节码跟踪”)。 学分 基于 由提供支持 由提供支持 使用优化 ...
Dtrace用户指南(中文版) DTrace 内置在 Solaris 中,是一个全面的动态跟踪工具。DTrace 可以由管理员和开发者使用,并且可以在实时生产系统上安全使用。使用 DTrace,可以检查用户程序的行为和操作系统的行为。...
Dtrace详细讲解,sun新技术培训。Dtrace入门资料
Linux DTrace路在何方?.pdf
solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace solaris Dtrace ...
BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS)。 BTrace动态地检测目标应用程序的类以注入跟踪代码(“字节码跟踪”)。 建筑BTrace 设置 您将需要安装以下应用程序 ...
dtrace stap book pdf
bay lasa dtrace pdf
linux, 用于linux内核驱动程序和客户端工具的dtrace DTrace的Linux端口Dec,Paul,Fox,Fox,Fox, 。博客- 关于dtrace项目的最新新闻和内容:http://crtags.blogspot.com/ http://www.crispeditor.co.uk