FindBugs,一个不错的静态分析工具

最近在做软件质量保证与测试的助教,第一个实验就需要讲解FindBugs,因此,将整个过程梳理了一下,望各位大神分享你们的观点,共同进步。

一,基本原理

1. Findbugs是一个静态分析工具,它检查类或者JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。现在有许多工具可以进行静态代码分析,比如:Parasoft JTest、Software Analyzer、pclint等,不同的工具一般针对不同的语言,而FindBugs针对的就是Java语言。Findbugs可以在ANT/GUI/ECLIPSE三个环境中运行,同时也可以编写自己的检测器,功能比较完善。

它主要用到的技术是缺陷模式匹配数据流分析

1)缺陷模式匹配:事先从代码分析经验中收集足够多的共性缺陷模式,将待分析代码与已有的共性缺陷模式进行模式匹配,从而完成软件的安全分析。这种方式的优点是简单方便,但是要求内置足够多缺陷模式,且容易产生误报。

2)数据流分析:数据流分析也是一种软件验证技术,这种技术通过收集代码中引用到的变量信息,从而分析变量在程序中的赋值、引用以及传递等情况。对数据流进行 分析可以确定变量的定义以及在代码中被引用的情况,同时还能够检查代码数据流异常,如引用在前赋值在后、只赋值无引用等。数据流分析主要适合检验程序中的 数据域特性。

2. FindBugs检查.class文件,基于Bug Patterns概念,查找javabytecode(.class文件)中的潜在bug。主要检查bytecode中的bug patterns,如NullPoint空指针检查、没有合理关闭资源、字符串相同判断错(==,而不是equals)等。

3. Findbugs自带检测器,其中有60余种Bad practice,80余种Correctness,1种 Internationalization,12种Malicious code vulnerability,27种Multithreaded correctness,23种Performance,43种Dodgy。

4. FindBugs有两种使用形式,一是作为插件,放在Eclipse中使用,二是提供软件运行。而作为插件的形式比较方便简单,个人觉得使用起来比较合适。

5.FindBugs内置的编程规范包括:

1)Bad practice 坏的实践:常见代码错误,用于静态代码检查时进行缺陷模式匹配

2)Correctness 可能导致错误的代码,如空指针引用等

3)国际化相关问题:如错误的字符串转换

4)可能受到的恶意攻击,如访问权限修饰符的定义等

5)多线程的正确性:如多线程编程时常见的同步,线程调度问题。

6)运行时性能问题:如由变量定义,方法调用导致的代码低效问题。

二,bug类型

1.当数据类型不对,进行equals比较时会检查出bug;

FindBugs,一个不错的静态分析工具_第1张图片

2.当使用String类型字符串进行循环相加时,不会提示使用StringBuffer。

3.当检查条件重复时会提示bug,比如:


FindBugs,一个不错的静态分析工具_第2张图片

4. 类静态变量未初始化,调用会检查到bug:

5. 会检查到字符串方法调用bug:

FindBugs,一个不错的静态分析工具_第3张图片

6.不会检查到多余的toString():

7.会检查到多次重复调用随机函数bug:

8.数组越界发现不了:

FindBugs,一个不错的静态分析工具_第4张图片

我猜想是因为这个编译都不能通过的原因。

以上这些简单的Test case只是我讲解实验时提出的一部分,FindBugs还能发现更多的bug,在此不做过多的介绍。

参考链接

三,深入理解Findbugs

1. Findbugs不是通过分析类文件的形式或结构来确定程序的意图,而是通常使用 观察者模式,检查类或者 JAR 文件,将字节码与一组缺陷模式进行对比以发现可能的问题。PMD也是一款静态代码分析工具,它是分析Java源文件。

2.可以下载到源代码,对源代码进行分析。源代码目录如下(版本号3.0.1)

FindBugs,一个不错的静态分析工具_第5张图片

1)src/jui包是Findbugs开发UI界面使用到的包,src/junit是单元测试包,里面包含有对很多类的测试用例。etc文件下是包含的一些配置文件。

2)src/tools包下面有四个子文件夹,里面包含的是一些公用的工具类,比如打印bug描述,生成xml文件等。

3)src/antTask包下面是针对Ant的一些类。

4)最主要的就是src/java包下面的将近50个子文件夹,如下(未截完):

FindBugs,一个不错的静态分析工具_第6张图片

该工具自带了一些检测器,于此同时,开发者可以根据自己的需求设计编写特定于应用程序的缺陷检测器。

5)有一个专门的文件夹edu.umd.cs.findbugs.detect,里面包含该工具提供的所有检测器,FindBugs 利用了 Byte Code Engineering Library,或称为 BCEL,以实现其检测器。所有字节码扫描检测器都基于 visitor 模式,FindBugs 实现了这个模式。它提供了这些方法的默认实现,在实现自定义检测器时要覆盖这些方法。我们将侧重于两个方法——visit(Code)和sawOpcode(int)。在 FindBugs 分析类时,它会在分析方法内容时调用visit(Code)方法。与此类似,FindBugs 在分析方法正文中的每一个操作码时调用sawOpcode(int)方法。

我们以一个最简单的检测器findRunInvocations为例简单说明一下:

FindBugs,一个不错的静态分析工具_第7张图片

该检测器继承了BytecodeScanningDetector类,实现了StatelessDetector接口,而BytecodeScanningDetector继承了DismantleBytecode,实现了顶级父类Detector。

FindBugs,一个不错的静态分析工具_第8张图片

分析多个检测器之后可以发现主要的结构层次:

顶级接口Detector是所有检测器的父类,在此接口下,有实现该接口的多个子类,每个检测器又根据自己的检测目的去实现不同的子类。查看API可以获取更加清晰的结构层次。

6)在eclipse中,可以自选需要的检测器:

FindBugs,一个不错的静态分析工具_第9张图片

7)每一个检测器都有要在findbugs.xml里注册,如果自实现了检测器,同样需要在该文件里注册进去。

FindBugs,一个不错的静态分析工具_第10张图片

你可能感兴趣的:(FindBugs,一个不错的静态分析工具)