UFIAwriting

  编写新的findbugs检测器

Why?

  你也许找到代码里的错误典型

How?

  检查字节码

有很多途径去实现findbugs的检测器

  通常,简单技巧就够了(如:顺序扫描)

  基本途径

1.从一个Bug开始(重要!)

2.编写可以查找到类似问题的最简单的检测器

3.评估:它是否能够找到足够相关的问题而没有太多的误检

4.提炼:提升分析和FP suppression heuristics

5.重复步骤3-4直到你认为可以接受或者放弃这个想法

  字节码框架

所有findbugs的检测器的工作都是基于分析字节码。支撑的框架:

  BCEL(http://jakarta.apache.org/bcel);DOM-like API

  ASM(http://asm.objectweb.org/);SAX-like API

当前,许多配套的findbugs基础架构是基于BCEL的。

基于ASM分析的检测器是实验性的。

  检测器的分类

大多数findbugs的检测器使用下面的一类实现技巧:

  1.检查class/method/field结构

  2.微模型化:简单的字节码模型

  3.基于栈的模型

  4.数据流分析

  5.过程间(函数间 Interprocedural)分析

每一种技术都现成的基类和支撑的基础架构。

  检查class/method/field结构

一些检测器并不要求代码分析.如:

  查找重写了equals方法却没有重写hashCode方法的类

  查找命名错误的方法(如:hashcode()代替hashCode())

  微模型化:简单的字节码模型

如:无条件的等待

源码:

  synchronized(lock){

    lock.wait();

    ...

  }

对应的字节码:

  ALOAD 0

  GETFIELD A.lock

  DUP

  ASTORE 1

  MONITORENTER

  ALOAD 0

  GETFIELD A.lock

  INVOKEVIRTUAL

  Object.wait()V

检测器状态(Detector states):

  基于栈的模型

微模型那些在操作栈上的值是有标志性的:

  如:之前看到的,查找常量字符串类型的值是monitorenter

  典型的实现策略:

    1.调查操作栈上的值

    2.当看到可疑的指令序列或堆栈值时发出警告

  数据流分析

1.使用过程间的数据流分析来推断方法间可能的实情(fact)

  你可能需要温习dragon book(查了下,可能是<Compilers:Principles,Techniques,and Tools>)

2.范例:

  查找空指针

  查找字段访问没有被一个锁一致地保护。

  过程间的分析

概括方法行为,并在每一个调用位置使用这个总结。如:

  1.无条件间接引用的方法参数

  2.返回值总是非空的值

  3.总是抛异常的方法

  更多信息

http://code.google.com/p/findbugs-tutorials

  1. PLDI教程幻灯片,使用findbugs做研究

    关于编写findbugs的检测器的深入讨论

  2. 有两个检测器的插件范例源码  

原文地址:https://www.cnblogs.com/lizzie/p/4754377.html