`
jejoker
  • 浏览: 25097 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类

Btrace的javaagent参数之script的坑

    博客分类:
  • JAVA
阅读更多

简单来说,这篇文章只是个笔记,纪念我与btrace参数拼搏的青春……(好吧……,我似乎不年轻了)

 

先写结论:windows环境下,javaagent方式的instrument不支持win的全路径方式,这里指script参数,因为他会按 : 进行分隔,带了盘符就会有问题。可以使用scriptdir替代,他会扫描这个文件夹下的所有classes文件,认为都是你的btrace脚本

 

==== 分割线,想看过程及其他一些说明,可以继续读下面 =========

 

btrace的场景,大部分情况下可能是运行时attach,一般来说都ok,但是也有极个别的场景下需要启动时就instrument(一直不知道这词怎么翻译……)。

什么样的场景呢?比如说:项目引入了大量jar包,某个jar里面启动了线程池而没有进行关闭……,还是个未命名线程池,这茫茫人海,让我去哪里找……

 

一般一种可行方案是,可以扫描自己项目所有能加载的类,并在加载的类中(如字节码)扫描是否有线程池类使用。bingo,出来了,可问题是……,他可能是十几个,或者几十个类引用了。然后一个一个翻代码,恐怕效率奇低。就算你排除了一些,剩下十来个,问题是,这些class你自己并没有引用,意味着可能是间接引用,于是乎……,又是一份费时费力的苦差。

 

这里,我想到了几种方案,这里不一一说了,大体是,可替换jdk的线程池类,使用自己的,打jstack,或者织入到线程池类中,等等等……

 

这里,我实际采用的方式是btrace,因为btrace非侵入性的debug代码能力非常之强,而且除了runtime阶段instrument以外,他提供了javaagent方式instrument。(javaagent就不展开说了)

于是,我尝试在代码启动时加入javaagent,大概是这样的:

-javaagent:D:/Dev/btrace-bin-1.3.9/build/btrace-agent.jar=noServer=true,debug=true,stdout=true,script=d:/script/Pool.class

 结果,brache很愉快的告诉你,d不是预编译的class,然后报xxx/Pool.class file not found。

 

初步怀疑是btrace代码做了分隔,为了支持多脚本,于是查看btrace源码。果然他做了这个事情,源码如下:

        if (script != null) {
            StringTokenizer tokenizer = new StringTokenizer(script, ":");
            if (isDebug()) {
                debugPrint(((tokenizer.countTokens() == 1) ? "initial script is " : "initial scripts are ") + script);
            }
            while (tokenizer.hasMoreTokens()) {
                loadBTraceScript(tokenizer.nextToken(), traceToStdOut);
            }
        }

 于是乎……,无解……

于是,看到有另一个参数 scriptdir,然后就指定这个文件夹,把classes文件放到下面就解决了

当然了,使用了这个参数,他会扫描下面的所有文件,并且都认为是btrace脚本,如果不符合规范(如没有@Btrace注解),都会报错,OVER!

 

另:补充一下,实际上,btrach默认直接 new File(scriptFilePath),如果找不到,会尝试 META-INF/btrace/scriptFilePath 找一次,还不行才会FileNotFound

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics