`

Btrace、DTrace实战之Btrace

阅读更多

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
 

分享到:
评论

相关推荐

    sun solaris Dtrace实战运用

    ### Dtrace实战运用 #### Dtrace架构概览 Dtrace是一种动态跟踪技术,它为操作系统提供了深入了解其行为的能力。在Sun Solaris系统中,Dtrace被广泛应用以解决各种性能问题和诊断难题。Dtrace的核心优势在于它能够...

    BTrace-一个用于Java平台的安全动态的跟踪工具

    在描述中提到,BTrace与OpenSolaris上的DTrace类似,DTrace是一款强大的系统诊断工具,能够深入到操作系统内部进行性能分析。BTrace将这种能力引入到了Java世界,使得开发者可以对Java应用程序进行细粒度的性能分析...

    dtrace 用户指南.zip

    6. **性能分析实战**:DTrace在实际问题解决中具有广泛的应用,比如查找内存泄漏、优化SQL查询、调试内核问题等。学习如何将DTrace与实际工作结合,能有效提升问题诊断效率。 7. **DTrace工具集**:除了D语言之外,...

    Dtrace

    - **实战项目**:通过实际项目的实践来加深理解,是掌握 Dtrace 技能的关键步骤。 总之,Dtrace 作为一种先进的动态追踪工具,为开发者和系统管理员提供了一种强有力的手段来解决复杂的问题。通过学习和掌握 Dtrace...

    HOW to USE DTrace

    ### 使用DTrace的基础知识 #### 引言:DTrace概览 DTrace是一种全面的动态追踪工具,集成在Solaris操作系统中。它为系统管理员和开发者提供了深入探索用户程序及操作系统内部行为的能力。通过DTrace,可以理解系统...

    Dtrace_Oracle.pdf

    - **低侵入性**:DTrace的设计目标之一是尽可能减少对被监控系统的干扰,确保在收集数据的同时不会显著影响系统的正常运行。 - **灵活性**:用户可以根据需要定制追踪点(probe),追踪点可以放置在内核或应用程序中...

    Sun Dtrace手册

    ### Sun DTrace手册知识点概述 #### 一、DTrace简介 DTrace(Dynamic Tracing)是一种先进的系统性能分析工具,最初由Sun Microsystems开发并应用于Solaris操作系统中。它能够帮助开发者和系统管理员深入理解应用...

    BTrace@javaone

    TraceClass是BTrace的核心组件之一,用于组织和定义探针及相关的动作。 - **注解**:BTrace使用了一组特定的注解来标识和配置TraceClass及其成员。这些注解位于`com.sun.btrace.annotations`包中。 - `@BTrace`:...

    DTrace userguide2.pdf

    ### DTrace用户指南知识点概述 #### 一、引言 - **DTrace简介**:DTrace(Dynamic Tracing)是Sun Microsystems为...无论是在开发过程中定位问题还是在生产环境中监控系统行为,DTrace都将是不可或缺的工具之一。

    Dtrace用户指南(中文版)

    ### Dtrace用户指南知识点解析 #### 一、DTrace简介 **DTrace** 是一个集成在 **Solaris** 操作系统中的强大动态跟踪工具。它不仅适用于管理员也适用于开发者,并且能够在实时生产环境中安全地使用。DTrace 主要...

    Dtrace 高级用法文档

    Dtrace 反向工程说明,对unix进行分析,跟踪的必备工具

    awesome-dtrace, 出色的DTrace书籍文章视频工具和资源的精选列表.zip

    awesome-dtrace, 出色的DTrace书籍文章视频工具和资源的精选列表 出色的DTrace 出色的DTrace书籍。文章。视频。工具和资源的精选列表。电子邮件内容学习学习。文章视频软件工具插件社区服务 。学习用于学习DTrace的...

    sun公司新技术培训Dtrace详细讲解2

    ### Dtrace 技术详解与应用 #### 一、Dtrace 的出现背景及意义 在 Dtrace 出现之前,传统的调试方式存在着诸多不足。为了定位问题,开发人员往往需要直接修改源代码并添加调试语句,这不仅耗时耗力,而且可能导致...

    bay lasa dtrace pdf

    Bay LASA DTrace PDF 本资源总结了关于 DTrace 的知识点,包括动态追踪、性能introspection、云计算等方面。 1. 动态追踪(Dynamic Tracing) 动态追踪是指在运行时对软件的追踪和分析,以了解软件的行为和性能。...

    Linux DTrace路在何方?.pdf

    Linux DTrace是一款强大的性能诊断工具,最初由Sun Microsystems公司开发,是系统开发和运维中的关键技术。DTrace允许系统管理员深入洞察系统的运行情况,包括内核行为、应用性能等,为故障排查和性能优化提供了有力...

    btrace:BTrace-用于Java平台的安全,动态跟踪工具

    BTrace可用于动态跟踪正在运行的Java程序(类似于DTrace,适用于OpenSolaris应用程序和OS)。 BTrace动态地检测目标应用程序的类以注入跟踪代码(“字节码跟踪”)。 学分 基于 由提供支持 由提供支持 使用优化 ...

    dtrace stap book pdf

    dtrace stap book pdf dtrace 是一种动态追踪技术,主要应用于 Unix 和 Linux 操作系统中,以便更好地了解系统的行为和性能。SystemTap 是一种动态追踪工具,主要应用于 Linux 操作系统中。DTrace 书籍 pdf 版本...

    dtrace 技术使用说明指南

    dtrace 技术使用说明指南 dtrace 是一种动态跟踪技术,用于实时观察和分析操作系统和应用程序的运行状态。它可以对系统的各个组件进行跟踪、分析和优化,帮助开发者和管理员更好地了解系统的行为和性能。 dtrace ...

    Dtrace_Ch09

    5. **性能分析与调试**:Dtrace的强大之处在于其在性能分析和问题调试上的应用。这一章可能会涵盖如何使用Dtrace来定位系统瓶颈,如CPU使用率过高、内存泄漏或I/O问题,并提供相应的调试策略。 6. **安全与最佳实践...

    sun公司新技术培训Dtrace详细讲解

    Dtrace的核心设计之一是将追踪功能分为内核态和用户态两部分。内核态主要用于捕获低级别的系统活动,如系统调用、进程调度等;而用户态则关注应用程序的行为,例如函数调用、异常情况等。这种分层设计确保了Dtrace的...

Global site tag (gtag.js) - Google Analytics