Java 代码质量 / 静态分析领域又有了一位新成员,它来自 Coverity ——一个在 C/C++ 领域从事了四年软件品质 / 缺陷检测方面工作的公司。Coverity 于本月上旬发布了 Prevent SQS (Software Quality System,软件质量系统),一个商业的品质 / 缺陷检测系统。它通过匹配源码与模板、编译时语法扫描、分析字节码并建立内部所有可能运行路径等多种分析引擎进行模组分析,以发现可能导致运行时异常、安全漏洞、不可预测行为和使性能下降的缺陷。
InfoQ 从 Coverity 的 CTO Ben Chelf 那里得到了一些技术细节:
我们通过分析所有的字节码和与之相应的源码,建立了一个软件特征系统(软件 DNA 图谱)。基于这套系统,我们可以在整个代码库的基础上为所有的方法生成全面的控制流程图和调用关系图,所以在分析代码时,我们能够精确地知道是谁、在什么地方进行了调用。我们建立的代码图表不仅可以用于分析,还可以在发现缺陷时指出所有导致缺陷的关键位置。分析过程是我们的秘密武器,在经过多年的研究后,我们的分析技术已经可以对上百万行代码进行分析并确定极少数缺陷。
根据 Converity 的说明,Prevent SQS 可以集成在桌面开发和持续集成环境中,大概每小时可以扫描数百万行 Java 代码。相应的 Eclipse 插件也提供了行级的问题代码检测。以下是 Prevent SQS 可以检测出的问题:
- 运行时异常
- 对已为 null 的对象的引用;
- 不恰当地将数组当列表来使用;
- 不正确的将一个对象转型为其子类型对象;
- 错误地使用数据库连接函数;
- 不可预测的运行时行为
- 错误的混淆操作和函数;
- 未调用父类的执行代码;
- 错误的 Hibernate 事务;
- 性能下降问题,诸如释放资源(包括文件句柄、连接、信号和流)失败。
按照 Ben 的说法,Coverity 强于其它字节代码扫描工具的能力是:它可以通过代码定义行为,确定可能导致出错的部分:
如果开发人员在重写方法时没有调用父类的实现,而该父类的方法在其它绝大多数被重写的情况下都被调用了的话,依赖于这个概念的检测功能就可以定位问题的所在。这样的约定是通过代码所在类和父类的正常行为来判定的,Prevent SQS 会在检测中获取这些信息,随后用来标识出错误的行为。当然,用户也可将需要检测的约定告诉系统,但是系统可以在大部分情况下自动识别这些约定的功能,对于任何自动检查技术来说都是一个新的领域。在分析中做方法边界检测,可以让我们找出那些没有被引用的块或方法。例如,当你调用一个方法去调用另外一个打开 JDBC 连接的方法,但又忘了关掉这个连接的情况,我们就可以标识出这种由不同类调用造成的关闭失败的情形。当然,并非所有路径上都会出现 Bug 的,通过我们的路径分析,我们可以识别包含缺陷的调用路径,并且不会太多噪音干扰。
当被问到 Coverity 是如何将他们 C/C++ 领域中的专业技术转移在 Java 领域时,Ben 说:
那是因为内在的分析技术是相似的!我们使用了很多与分析 C/C++ 软件时相同的技巧。一个有明显区别对待的地方是解析虚方法。由于在 Java 中所有的方法调用都是“虚的(基于类型的动态查找)”,因此我们确保有合理的算法来计算对象可能的类型,以便于在跨程序分析代码时,对代码在哪里会产生调用分支了如指掌。尽管虚方法毫无疑问也存在于 C++ 应用中,但是实际上在我们所看见的绝大部分现实 C++ 应用中,他们被运用得少得多。正因为如此,我们选择了不同的方法和算法去处理两种语言间的差别。
Ben 建议越早将 Prevent SQS 应用在开发周期中,越能发挥杠杆作用,并举了他们自己作为范例。在 Coverity 的 Java 团队中,Prevent SQS 已被集成到自动构建系统中,同样也是配备了一个又老又大的标志灯,有时,在开发人员提交代码时,SQS 发现了 Bug,标志灯会由绿变红。开发人员可以在提交代码之前运行 SQS,以避免被示红灯。
在静态分析领域,有不少的商业和开源工具,其中包括由Bill Pugh 提供的开源分析工具 FindBugs 。
查看英文原文: Coverity Prevent SQS: Java Static Analysis Defect Detection - - - - - -
译者简介:张海龙,现就职于 Ethos ,注重对项目管理的过程建立和优化、设计模式的理解和实践。与 InfoQ 中文站分享内容,请邮件至 china-editorial[at]infoq.com 。
评论