zoukankan      html  css  js  c++  java
  • 调试工具BTrace 的使用例子

    BTrace 是一款利用hotSpot虚拟机可以动态替换class的特点而完成的,可以对online的程序动态的改变类的行为(一般为加些打印日志),进而进行线上调试的一个工具。

    一篇淘宝技术团队的博客:http://rdc.taobao.com/team/jm/archives/509

    主要步骤如下(本次测试只针对BTrace和测试的程序在同一台机器上,remote的还待实验):

    1、下载地址:http://kenai.com/projects/btrace/downloads/download/releases/release-1.2.2/btrace-bin.zip

    2、解压到linux相应的目录下。

    3、编写普通运行的程序如下:

    package com.ddc.mem;
    
    public     class CaseObject{
         
           private static int sleepTotalTime=0; 
         
           public boolean execute(int sleepTime) throws Exception{
               System.out.println("sleep: "+sleepTime);
               sleepTotalTime+=sleepTime;
               Thread.sleep(sleepTime);
               if(sleepTime%2==0)
                   return true;
               else 
                   return false;
           }
         
        }

    Main函数运行:

    package com.ddc.mem;
    
    import java.util.Random;
    
    public class CaseObjectMain {
    
           public static void main(String[] args) throws Exception{
                  Random random=new Random();
                  CaseObject object=new CaseObject();
                  while(true){
                      boolean result=object.execute(random.nextInt(1000));
                     Thread.sleep(1000);
                  }
               }
    }

    4、将以上两个类编译并运行 。

    5、编写BTrace 文件,按照java规范,java文件名称为TracingScript.java

    /* BTrace Script Template */
    import com.sun.btrace.annotations.*;
    import static com.sun.btrace.BTraceUtils.*;
    
    @BTrace
    public class TracingScript {
        /* put your code here */
    /*指明要查看的方法,类*/
      @OnMethod(
         clazz="com.ddc.mem.CaseObject",
         method="execute",
         location=@Location(Kind.RETURN)
      )
    /*主要两个参数是对象自己的引用 和 返回值,其它参数都是方法调用时传入的参数*/
       public static void traceExecute(@Self com.ddc.mem.CaseObject object,int sleepTime, @Return boolean result){
          println("调用堆栈!!");
           println(strcat("返回结果是:",str(result)));
          jstack();
          println(strcat("时间是:",str(sleepTime)));
       }
    
    }

    6、对于btrace文件夹加运行时路径(java_home 和 classpath)

    修改{btrace_home}/bin/btrace 文件

    #! /bin/sh
    
    #需要设置jdk的路径,因为需要动态编译,所以需要设置这个路径
    JAVA_HOME=/usr/lib/jvm/java-6-sun-1.6.0.22
    #因为需要动态编译,所以需要设置原类库的classpath,主要是要编译BTRACE文件,它里面肯定有依赖原类
    CLASS_PATH=/data/testxiao/
    #BTRACE_HOME路径,编译以及运行时都需要BTRACE自己的jar包
    BTRACE_HOME=/data/btrace
    if [ -z "$BTRACE_HOME" -o ! -d "$BTRACE_HOME" ] ; then
      # resolve links - $0 could be a link to btrace's home
      PRG="$0"
      progname=`basename "$0"`
      BTRACE_HOME=`dirname "$PRG"`/..
      BTRACE_HOME=`cd "$BTRACE_HOME" && pwd`
    fi
    
    if [ -f "${BTRACE_HOME}/build/btrace-client.jar" ] ; then
        if [ "${JAVA_HOME}" != "" ]; then
           case "`uname`" in
              Darwin*)
                  # In Mac OS X, tools.jar is classes.jar and is kept in a 
                  # different location. Check if we can locate classes.jar
                  # based on ${JAVA_VERSION}
                  TOOLS_JAR="/System/Library/Frameworks/JavaVM.framework/Versions/${JAVA_VERSION}/Classes/classes.jar"
    
                  # if we can't find, try relative path from ${JAVA_HOME}. Usually,
                  # /System/Library/Frameworks/JavaVM.framework/Versions/1.6.0/Home
                  # is JAVA_HOME. (or whatever version beyond 1.6.0!)
                  if [ ! -f ${TOOLS_JAR} ] ; then
                      TOOLS_JAR="${JAVA_HOME}/../Classes/classes.jar" 
                  fi
    
                  # If we still can't find, tell the user to set JAVA_VERSION.
                  # This way, we can avoid zip file errors from the agent side
                  # and "connection refused" message from client.
                  if [ ! -f ${TOOLS_JAR} ] ; then
                      echo "Please set JAVA_VERSION to the target java version"
                      exit 1
                  fi
              ;;
              *)
                  TOOLS_JAR="${JAVA_HOME}/lib/tools.jar"
              ;;
           esac
           ${JAVA_HOME}/bin/java -Dcom.sun.btrace.probeDescPath=. -Dcom.sun.btrace.dumpClasses=false -Dcom.sun.btrace.debug=false -Dcom.sun.btrace.unsafe=false -cp ${BTRACE_HOME}/build/btrace-client.jar:${TOOLS_JAR}:/usr/share/lib/java/dtrace.jar:${CLASS_PATH} com.sun.btrace.client.Main $*
        else
           echo "Please set JAVA_HOME before running this script"
           exit 1
        fi
    else
        echo "Please set BTRACE_HOME before running this script"
        exit 1
    fi

    7、jps   CaseObjectMain进程的pid,假设pid为1478 ,刚才的btrace  为TracingScript.java

        则运行命令为 :bin/btrace   1478 TracingScript.java

    8、一切ok  

    输出如下:

    调用堆栈!!
    返回结果是:false
    com.ddc.mem.CaseObject.execute(CaseObject.java:14)
    com.ddc.mem.CaseObjectMain.main(CaseObjectMain.java:11)
    时间是:483
    调用堆栈!!
    返回结果是:true
    com.ddc.mem.CaseObject.execute(CaseObject.java:12)
    com.ddc.mem.CaseObjectMain.main(CaseObjectMain.java:11)
    时间是:998
    调用堆栈!!
    返回结果是:false
    com.ddc.mem.CaseObject.execute(CaseObject.java:14)
    com.ddc.mem.CaseObjectMain.main(CaseObjectMain.java:11)
    时间是:611
    调用堆栈!!
    返回结果是:true
    com.ddc.mem.CaseObject.execute(CaseObject.java:12)
    com.ddc.mem.CaseObjectMain.main(CaseObjectMain.java:11)
    时间是:524

    表明其实已经改变了原有的输出并加上了打印日志 。

  • 相关阅读:
    洛谷 P1653 猴子 解题报告
    洛谷 P2024 [NOI2001]食物链 解题报告
    洛谷 P1966 火柴排队 解题报告
    洛谷 P1311 选择客栈 解题报告
    洛谷 P3959 宝藏 解题报告
    二进制枚举子集技巧
    洛谷 P1841 [JSOI2007]重要的城市 解题报告
    洛谷 P2324 [SCOI2005]骑士精神 解题报告
    vector-size
    ubuntu 更换软件源
  • 原文地址:https://www.cnblogs.com/serendipity/p/2499840.html
Copyright © 2011-2022 走看看