博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
btrace
阅读量:5804 次
发布时间:2019-06-18

本文共 4206 字,大约阅读时间需要 14 分钟。

hot3.png

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

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

1、下载地址:

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

 

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

转载于:https://my.oschina.net/u/1389155/blog/172968

你可能感兴趣的文章
复利计算总结-软件工程
查看>>
http url转义字符,特殊字符
查看>>
数据结构之shell排序
查看>>
jQuery源代码学习:经常使用正則表達式
查看>>
T-SQL 根据年月日创建DateTime
查看>>
【Joomla】修改点汇总
查看>>
魔王与西蒙•弗拉格
查看>>
Linux文件系统的进化
查看>>
pku3041 Asteroids
查看>>
【转】查找——图文翔解RadixTree(基数树)
查看>>
一本通 1267:【例9.11】01背包问题
查看>>
Git 工作区和暂存区
查看>>
Truncated incorrect DOUBLE value: 'NO_REFUND'
查看>>
Mysql 忘密码 + Phpadmin 修改密码无法登陆
查看>>
【思想空间·毁灭人类的十件事】
查看>>
Firebug入门指南(转)
查看>>
db4o数据库存放的class含有相同的字段名且字段的类型也相同。现在想把这个库中数据读出来,但总是报 java.lang.ClassCastException错误...
查看>>
iOS开发那些事儿(七)Http状态码汇总
查看>>
Java实现链式存储的二叉查找树(递归方法)
查看>>
Dexter 6.0+ 运行权限
查看>>