其神若何,月射寒江。

白盒测试之静态检查--Findbugs自定义检测器API

上一篇 / 下一篇  2010-04-01 19:46:19 / 个人分类:白盒测试研究

网上介绍Findbugs的自定义检测器的资料太少了。只是很少的一些网友发的文章。特别是对于里面的API的介绍几乎没有。还好了,有源代码,只有自己研究下了。刚好最近开发插件,稍稍研究了下里面的源代码,实现了单例的线程安全检测插件。

 

1      检测器

1.1   BytecodeScanningDetector

对于扫描字节码的需求,一般是扩展这个类。

1.1.1  Visit

Visit有很多不同参数的方法。表示访问类、或者代码、方法等时候会调用该方法。

一般用该方法进行访问前的初始化工作

l        public void visit(Code obj)

分析方法内容时调用visit(Code)方法,往往用于分析方法代码前进行初始化工作

l        public void visit(JavaClass obj)

 分析该类之前,调用该方法。往往用于取得类的信息

 

l        public void visitField(Field obj)

分析类的属性前,调用该方法,往往用于取得类的属性信息。

 

 

例如:

public void visit(JavaClass obj) {

             isHasField = false;

             isPublicStaticMethord = false;

             super.visit(obj);

      }

 

      public void visitField(Field obj) {

             if (isHasField) {

                    return;

             }

             //如果存在非基本类型非最终属性非静态的

             //那么肯能就是类的属性了

             if (!obj.isFinal() && !obj.isStatic()) {

                    isHasField = true;

             }

      

      }

1.1.2  VisitAfter

 

public void visitAfter(JavaClass obj)

 

类分析只后调用该方法

1.1.3  sawXXX

sawXXX这类方法都会在分析XXX的时候调用该方法。

 

1.1.3.1            sawOpcode

public void sawOpcode(int seen)

 

分析字节码

>>在分析方法正文中的每一个操作码时调用sawOpcode(int)方法。

>> seen就是每条的操作码,操作码在反编译后都能看到

 指令码都是该类的常量,可以找到。

汇编指令码如下:

public void show();

 Code:

  0:  getstatic      #29; //Field java/lang/System.out:Ljava/io/PrintStream;

  3:  ldc    #48; //String ssssssssssssss00s

  5:  invokevirtual  #35; //Method java/io/PrintStream.println:(Ljava/lang/St

ring;)V

  8:  return

>>取得该指令对于的类

getClassConstantOperand()

对于5:可以取到java/io/PrintStream

>>取得该指令对应的类执行的方法的名字

getNameConstantOperand()

 对于5:可以取到println

>>例如

汇编代码:

public void doBadStuff();

 Code:

  0:    invokestatic    #2; //Method java/lang/System.gc:()V

  3:   return

 

查找调用了System.gc的代码

public void sawOpcode(int seen) {

       if (seen == INVOKESTATIC) {

           if (getClassConstantOperand().equals("java/lang/System")

                   && getNameConstantOperand().equals("gc")) {

 

               bugReporter.reportBug(new BugInstance("SYSTEM_GC", NORMAL_PRIORITY)

                       .addClassAndMethod(this)

                       .addSourceLine(this));

           }

       }

   }

}

 

1.1.3.2            sawMethod

public void sawMethod()

 

>>每分析一个方法前,都会调用该方法

>>取得类的名字

String className = super.getClassName().replaceAll("/", ".");

>>取得方法的名字

this.getMethod().getName()

>>取得方法的返回类型

String returnType = this.getMethod().getReturnType().toString();

>>取得方法是否为静态

             boolean isStatic = this.getMethod().isStatic();

>>取得方法是否为公开的

             boolean isPublic = this.getMethod().isPublic();

 

>>例如:

public void sawMethod() {

             if (isPublicStaticMethord) {

                    return;

             }

//class name:   demo/First|| methord name :show|| ReturnType() name :  //demo.Second  //accce flag=   1  

             String className = super.getClassName().replaceAll("/", ".");

             String returnType = this.getMethod().getReturnType().toString();

             boolean isStatic = this.getMethod().isStatic();

             boolean isPublic = this.getMethod().isPublic();

             //单例判断

             if (isPublic && isStatic) {//如果为公有的静态的

                    if (className != null && className.equals(returnType)) {//如果返回值就是本类

                           isPublicStaticMethord = true;

                    }

             }

 

      }

 

1.1.4  生成报表

 

要生成报表,需要几步操作

 

1、构造函数里面会传递报表参数

publicSingletonDector(BugReporter bugReporter) {

      this.bugReporter= bugReporter;

   }

 

2.在恰当的地方调用报表

一般是在visitXXX sawXXX地方检查的时候调用

bugReporter.reportBug(newBugInstance("MULTITHREAD_SINGLETON",NORMAL_PRIORITY)

                 .addClass(this))

                 ;

>>MULTITHREAD_SINGLETON

  就是配置的报表的名字

>>addXXX

 就是传递给报表的属性,在报表里面是可以取到的

 

 

--------------------------2010-4-1 river.liu 转载请保证完整

 


TAG:

 

评分:0

我来说两句

xiaohanjiang

xiaohanjiang

River.liu又名小寒江。曾经从事多年JAVA软件开发工作,这几年一直从事软件测试工作。多年来,一直致力于软件工程、软件开发、软件测试方面的研究。不喜欢自称高手,不愿意自封资深;科学研究讲究的是务实、实践。真理、真知才是硬道理。茫茫海洋,我只希望我的每个理念能游弋于业界之间。我的思想能在你的脑海中徜徉。

日历

« 2024-04-12  
 123456
78910111213
14151617181920
21222324252627
282930    

数据统计

  • 访问量: 39591
  • 日志数: 52
  • 建立时间: 2009-12-15
  • 更新时间: 2011-03-14

RSS订阅

Open Toolbar