静态代码检测工具对比

心情很down,一年没更博了,陆续整理…此篇没啥含量,纯调研,搬运别人成果

什么是静态代码分析

静态代码分析是指无需运行被测代码,仅通过分析或检查源程序的语法、结构、过程、接口等来检查程序的正确性,找出代码隐藏的错误和缺陷,如参数不匹配,有歧义的嵌套语句,错误的递归,非法计算,可能出现的空指针引用等等。

在软件开发过程中,静态代码分析往往先于动态测试之前进行,同时也可以作为制定动态测试用例的参考。统计证明,在整个软件开发生命周期中,30% 至 70% 的代码逻辑设计和编码缺陷是可以通过静态代码分析来发现和修复的。

但是,由于静态代码分析往往要求大量的时间消耗和相关知识的积累,因此对于软件开发团队来说,使用静态代码分析工具自动化执行代码检查和分析,能够极大地提高软件可靠性并节省软件开发和测试成本。

Java 静态代码分析主要技术

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

类型推断:类型推断技术是指通过对代码中运算对象类型进行推理,从而保证代码中每条语句都针对正确的类型执行。这种技术首先将预定义一套类型机制,包括类型等价、类型包含等推理规则,而后基于这一规则进行推理计算。类型推断可以检查代码中的类型错误,简单,高效,适合代码缺陷的快速检测。

模型检查:模型检验建立于有限状态自动机的概念基础之上,这一理论将被分析代码抽象为一个自动机系统,并且假设该系统是有限状态的、或者是可以通过抽象归结为有限状态。模型检验过程中,首先将被分析代码中的每条语句产生的影响抽象为一个有限状态自动机的一个状态,而后通过分析有限状态机从而达到代码分析的目的。模型检验主要适合检验程序并发等时序特性,但是对于数据值域数据类型等方面作用较弱。

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

主流静态代码分析工具

FindBugs 是由马里兰大学提供的一款开源 Java 静态代码分析工具。FindBugs 通过检查类文件或 JAR 文件,将字节码与一组缺陷模式进行对比从而发现代码缺陷,完成静态代码分析。

PMD 是由 DARPA 在 SourceForge 上发布的开源 Java 代码静态分析工具。PMD 通过其内置的编码规则对 Java 代码进行静态检查,主要包括对潜在的 bug,未使用的代码,重复的代码,循环体创建新对象等问题的检验。

Android Lint是Google提供给Android开发者的静态代码检查工具。Lint 工具可检查 Android 项目源文件是否包含潜在错误,以及在正确性、安全性、性能、易用性、便利性和国际化方面是否需要优化改进。

Infer是 Facebook 旗下开源的静态分析工具,至今已在Github上获得6700+ Star。Infer可以扫描JAVA、Objective-C和 C/C++ 代码,擅长资源泄漏以及空指针的检测。

360火线(Fireline)是360公司技术委员会牵头,Web平台部Qtest团队开发的一款免费静态代码分析工具。主要针对移动端Android产品进行静态代码分析。其最为突出的优点就是资源泄漏问题的全面检测。

Screenshot

1、使用配置

PMD FindBugs Jenkins配置

360火线(FireLine)jenkins配置

2、检测项对比

FindBugs(更名为spotbugs):

FindBugs BugDescriptions

SpotBugs BugDescriptions

  • Bad practice 不佳实践:常见代码错误,用于静态代码检查时进行缺陷模式匹配(如重写equals但没重写 hashCode,或相反情况等)
  • Correctness 可能导致错误的代码(如空指针引用、无限循环等)
  • Internationalization 国际化相关问题(如错误的字符串转换等)
  • Malicious code vulnerability 可能受到的恶意攻击(如访问权限修饰符的定义等)
  • Multithreaded correctness 多线程的正确性(如多线程编程时常见的同步,线程调度问题等)
  • Performance 运行时性能问题(如由变量定义,方法调用导致的代码低效问题等)
  • Security 安全问题(如HTTP,SQL,DB等)
  • Dodgy code 导致自身错误的代码(如未确认的强制转换、冗余的空值检查等)

PMD:

  • 可能的 Bugs:检查潜在代码错误(如空 try/catch/finally/switch 语句)
  • 未使用代码(Dead code):检查未使用的变量,参数,方法
  • 复杂的表达式:检查不必要的 if 语句,可被 while 替代的 for 循环
  • 重复的代码:检查重复的代码
  • 循环体创建新对象:检查在循环体内实例化新对象
  • 资源关闭:检查 Connect,Result,Statement 等资源使用之后是否被关闭掉

Android Lint:

  • Correctness 潜在的bug
  • 可优化的代码
  • Security 安全性
  • Performance 性能
  • Usability 可用性
  • Accessibility 可访问性
  • I18n 国际化

360火线(FireLine):

  • 安全类:根据360信息安全部门最权威的SDL专门定制,每一条SDL都有真实的攻击案例
  • 内存类:各种资源关闭类问题检测(本次评测的重点)
  • 日志类:检测日志输出敏感信息内容的规则
  • 基础类:规范类、代码风格类、复杂度检查规则
3、检测结果对比

Screenshot

Screenshot

参考

[1] 常用 Java 静态代码分析工具的分析与比较

[2] 360火线(FireLine)