译文《A Systematic Review and an Evaluation of Static Analysis Tools》

image from unsplash

说明,翻译文章为A Systematic Review and an Evaluation of Static Analysis Tools中的Chapter 3 – An Evaluation of Static Analysis Tools for Java Multithreaded Bugs。

正文:

Java多线程错误的静态分析工具的评估

摘要:

静态分析(SA)工具正用于早期检测软件缺陷。随着多核处理器的发展,已经使得从服务器到个人计算机的软件并发成为可能。从本质上讲,并发性错误与顺序程序中的错误不同,它们很难被检测到。可用的SA工具提供对检测并发错误的支持。然而关于SA工具检测Java多线程错误的有效性的实证证据不是那么强。本文介绍了评估四个静态分析工具检测Java并发性错误和错误模式的结果。使用并发基准测试程序和多线程错误模式的集合来评估这些工具。除了工具的评估,我们已经从工具的检测器和文献中识别了87个独特的错误模式。最后,我们对工具的错误模式检测器进行了分类,这将有助于用户更容易地理解和使用它们。

1介绍

写并发软件很困难,然而,检测并发缺陷甚至更困难。在过去几十年中,开发合适的技术和工具来检测并发软件缺陷,已经花费了大量的工作。因此,我们有各种类型的工具,如静态分析器,模型检查器和动态分析器[6,18]。 静态分析(又名自动静态分析)工具能够检测源代码中的缺陷,而不执行它。模型检查器使用调用图,有限状态机等以良好定义的数学公式对源代码进行形式验证[18]。 动态分析器需要执行检测缺陷的代码。

通常,静态分析(SA)工具在检测错误方面比动态工具更抽象。SA工具是可扩展的,其中模型检查工具遭受状态爆炸问题。动态工具不像SA工具那么容易使用; 因为使用动态工具检测错误需要仪器源代码或目标代码[6]。

在软件开发中,早期漏洞检测的重要性是一个公认的事实。静态分析工具有缺陷[ 17,19 ]早期检测和降低软件开发的成本[ 3 ]。实证研究表明,使用SA工具与代码检查并发软件是成本效益的[ 28 ]。通常,SA工具部署在开发人员的工作站上,并与编码一起使用足够快。它也可以用来作为一个批处理器,用于测试大量的代码。然而,重要的是,在任何其他测试工具或技术使用之前,SA工具通常可以用来检查代码。

一些研究评估了在不同的静态分析工具下的java程序[ 2,5,20,21,23-26 ]。然而,很少有研究关注java多线程的缺陷[ 1的静态分析工具的评价,25 ]。大多数这些尝试是局部的多线程的缺陷,因为它们没有涵盖广泛的并发缺陷类型。更多的经验证明,评估不同的缺陷检测工具,专门专注于不同类型的错误和错误模式是必要的。

本研究测评了两种商业版和两种开放源代码版的静态分析工具,主要测试他们java多线程的错误和缺陷模式检测能力。为了评价静态分析工具,我们使用了java程序的基准测试套件,套件包含并发错误[ 7 ]和从一个反模式[ 12 收集的错误模式]和选定的工具库。本研究解决以下研究问题:

问题一:在java多线程的错误检测和错误模式的静态分析工具的有效性如何?

问题二::商业SA工具和开源SA工具在检测java多线程的缺陷时哪一个更好?

我们进行了一个实验来回答这些问题,其中SA工具作为主题,基准套件和错误模式作为对象。除了评估工具之外,我们还对工具使用的规则/检查/错误模式进行了分类,以检测缺陷。这种分类可以帮助用户理解和根据自己的需要选择一套合适的跳棋/错误模式。我们还利用工具研究了bug模式检测器,然后统一了87个独特的java多线程的错误模式。

研究结果表明,商业工具Jtest在检测Java多线程错误方面比其他工具更好,缺点是该工具报告的假阳性率很高。然而,不可能在商业和免费开源工具之间做出明确区分,因为其他商业工具Coverity Prevent检测到工具中缺陷的数量最少。 FindBugs和Coverity Prevent都报告了少量的假阳性警告。

第2节讨论了并发性错误和错误模式。 第3节介绍用于测试工具的选定工具和一组程序。 第4节解释了唯一的bug模式及其分类的识别。 实验详见第5节。第6节讨论分析和结果。 讨论和相关工作分别在第7节和第8节讨论,在第9节结束。

2并发错误以及错误模式

并发软件的最常见的特性是非确定性。 并发程序的非确定性执行使其与顺序程序不同。 因为线程的交织执行,并发程序保持非确定性特性,出现了许多问题,如数据竞争,原子性违反,同步缺陷,死锁,活锁等。

并发问题可以分为两种类型的基本属性,安全性和活性[18]。 安全属性确保在程序执行期间不会发生任何不良。另一方面,活力属性表示好东西最终会发生。这些属性下的最着名的问题是竞争条件(也称为数据竞争,交织问题),死锁,活锁和饥饿[18]。 这些问题必须在程序中不存在,以满足安全性和活性。并发软件的这两个基本属性是抽象的,一些并发问题在它们之间重叠。出于这个原因,基于基本属性对并发性问题进行分类并没有成果。

在软件工程中,模式意味着,一些常见的技术来记录和重用特定的和重要的例子。已经有关于并发错误特征/模式的研究[9,12]。在一般意义上,错误模式描述了在程序中可能发生的常见错误。一个bug模式是一个重复的相关的信号错误和潜在的bug在程序[29]。设计模式是常见问题的解决方案。确定地附加有否定结果的设计模式的解被称为反模式。这是个术语,缺陷模式和反模式是非常相似的,其差别在于缺陷模式与编码缺陷相关,而反模式与设计模式或架构模式中的缺陷相关。在并发软件测试的上下文中,错误模式和反模式可互换使用。例如,FindBugs工具在其bug模式列表中描述了许多设计模式[10]。同样,Hallal et al也描述了。[12]描述了反模式库中的几个错误模式。在这项研究中,我们对bug模式和反模式使用“bug模式”这个术语。

3选择工具和测试程序

3.1选择Java静态分析工具

我们选择了4个Java静态分析工具,如表1所示。在工具中,FindBugs和Jlint是文献中讨论最多的工具。然而,很少有文章[3,20]使用工具Coverity Prevent和Jtest。因此我们最好的知识没有研究评估这两个商业工具的Java多线程错误的有效性。 工具的简要说明如下:

Coverity Prevent [3,4]是一种商业静态分析工具,它结合统计和过程间分析与布尔可满足性(SAT)来检测缺陷。为了推断正确的行为,它使用基于代码中识别的行为模式的统计分析。然后跨方法,文件和模块边界进行跨程序(全程序)分析,以实现100%的路径覆盖。 SAT引擎和SAT求解程序确定路径在运行时是否可行或导致质量,安全性或性能缺陷。除了Java,Coverity Prevent还支持C#和C / C ++。Coverity Prevent检测到多个多线程缺陷,如死锁,线程块,原子性和竞态条件。

Coverity Prevent在多个平台和编译器上工作,如gcc,Microsoft Visual C ++等。它支持Eclipse和Visual Studio IDE。它还在产品设置(如搜索深度)上提供良好的可配置性。可以通过创建自定义检查器来扩展工具。

Jtest [15,20]是由Parasoft开发的商业静态分析工具。它是用于自动化各种最佳实践的集成解决方案。Parasoft Jtest支持各种代码度量计算,编码策略实施,静态分析和Java的单元测试。它还为简化的手动代码审查过程和同行代码审查提供支持。它执行基于模式和流的静态分析,以确保安全性和可靠性。Jtest有一个很好的检查器检测多线程错误的集合。

Jtest在Windows,Solaris,Linux和Mac OS X等多个平台上工作。它具有GUI和命令行(批处理)支持。它适用于Eclipse,IBM RAD和Jbuilder。它允许使用图形设计工具通过修改参数或提供展示示例规则违例的代码来创建自定义规则。

FindBugs [13,14,20,]是在马里兰大学开发的一个基于开源错误模式的缺陷检测器。它可以找到诸如解除引用空指针或未使用的变量的错误。它使用语法和数据流分析来检查Java字节码以检测错误。FindBugs报告超过360种不同的bug模式。将错误模式分组为类别(例如,多线程正确性,正确性,性能等)。

FindBugs提供GUI和命令行界面。 除了它的swing界面,它适用于Eclipse和NetBeans。 FindBugs分析结果可以保存为XML。它需要JRE / JDK 1.5或更高版本。FindBugs是独立于平台的,它已知在Windows,GNU / Linux和MacOS X平台上运行。可以通过定义自定义检测器来扩展FindBugs。

Jlint [1,20]是一个开源静态分析工具,它执行句法检查,流分析,并构建一个锁图,用于检测继承,同步等缺陷。它可以通过使用全局数据流分析来检测数据竞争。它可以通过过程间和文件间分析来检测死锁。Jlint提供了多个检查器来检测多线程Java程序中的死锁。Jlint检测到大约36种不同类型的错误。它有一个名为AntiC的组件,它是一个C系列语言(即C,C ++,Objective C和Java)的语法检查器。

Jlint有一个简单的命令行界面。它运行在Windows,UNIX,Linux上。 Jlint不容易扩展。

3.2测试程序的选择

我们选择了包含并发性错误和错误模式的程序。有必要评估具有错误和错误模式的工具。 测试用于检测错误的工具可以揭示工具的有效性。由于许多原因可能会出现错误。收集具有这么多种原因的现实生活中的Bug程序是相当具有挑战性的,并且它需要大量的时间。 为此,测试工具与bug模式是重要的,因为bug模式可以反映出各种各样的情况,其中bug可能发生[12]。 然而,错误模式并不总是错误,因此使用错误和错误模式测试工具是有意义的。

我们选择了两组程序,其中第一组表示并发错误,第二组表示错误模式。第一组程序取自并发错误基准套件[6,7]。有人批评使用基准来评估验证和验证技术的有效性,因为基准可能不完全涵盖可能导致不正确结果的几个因素[16]。 然而,如果考虑这些限制,可以使用基准[22]。

所选择的基准也用于其他研究。基准的经验故事[8]报告了使用基准的14个研究和研究中心的列表。并行软件测试专家和课程并发软件测试的学生写了大多数基准程序。我们从这个基准套件中选择了19个程序,提供了一个精确的错误文档和一个程序是由我们写的。表2显示了所选的基准程序。有关这些程序的详细信息在附录A中给出,更多详细信息可在基准套件中找到。

第二组是Java多线程错误模式和反模式的集合。我们从3.1节讨论的四个工具中收集了这些模式,Hallal等人[12]记录了一系列反模式。我们已经分类和识别了87个独特的错误模式从141错误模式,在第4节讨论。然后我们收集/写了这些错误模式的程序。这些程序非常小; 通常10到30行代码。

4 Bug模式分类

所选择的工具有超过100个bug模式。为了进行实验,我们需要识别独特的bug模式。 更重要的是,我们需要在常见的词汇表下分类这些错误模式。如果工具在修正的缺陷类别(例如死锁,数据竞争,活锁等)下描述其检查器/规则/模式,则人可以容易地具有关于工具的强度的一般概念。表3示出了并发检查器/错误模式的类别工具。

不幸的是,由工具分类的错误模式是不令人满意的。只有Jlint在精细的类别级别描述其错误模式。在其他工具中,Jtest在工具提供的错误文档中提供了其bug模式的进一步分类。Jtest描述了类别死锁和竞态条件中的19个bug模式,类别并发中的6个bug模式和其他18个bug模式未分类。应该提到的是,Coverity Prevent描述的类别预览下的五个跳格仍在细化,因此不推荐用于常规工业用途。

我们在文献中发现了两个主要作品[9,12],它们与并发的bug模式一起工作。其中,Hallal等人[9]提到了具有良好的bug模式分类的优点,并提出了对6种类型的38个并发反模式的全面分类。他们开发了保持开发者的利益的类别。我们采纳并扩大了这些类别。为了开发一个独特的bug模式集合,我们使用了141个bug模式,其中从模式中收集了103个模式,并从[9]开发的反模式库中选择了38个模式。 反模式库记录了来自FindBugs的8个bug模式和来自Jlint的11个bug模式。由于这个反模式库主要包含并发错误模式,本研究使用术语“错误模式库”来表示它。我们已经从所选的103个错误模式中找到了87个独特的错误模式,并对它们进行了分类,如表4所示。

在统一来自不同工具的错误模式时,我们发现了几种情况,其中一个工具的错误模式检测器被另一个工具部分地描述。例如,图1所示的五个错误模式被标识为相似,因此被组合成单个组。Jtest错误模式描述了wait(),notify()和notifyAll()方法,FindBugs在两个不同的bug模式中描述了wait()和notify()。 另一方面,Jlint只描述了wait()。 FindBugs在单个检查器下描述这两个错误模式。以这种方式,由不同工具实现的错误模式检测器可以在某种程度上从其他不同,尽管它们被列为常见的错误模式。然而,在一些情况下,在单个检查器下描述的FindBugs错误模式分布在不同的组中。

5 实验

我们遵循Wohlin等人提出的实验过程 [27]。实验被定义为:

从“开发源和商业工具测试多线程”的上下文中的“研究人员和从业者”的角度来分析“静态分析工具”以用于“评估”关于它们的“缺陷检测能力” Java程序“。

5.1实验设计

5.1.1上下文选择。

实验离线,因为它不在真实的工业环境中执行。实验的主题是用于测试多线程Java程序的开源和商业静态分析工具。实验的对象是Java多线程程序的集合,这些程序将由测试工具进行分析。由于实验的结果将有助于研究人员和从业者,因此实验可以被表征为真实的。

5.1.2假设制定。

我们考虑了实验的以下假设:

空假设H0:所选的静态分析工具同样能够检测Java多线程程序中的错误和错误模式。

备选假设H1:所选的静态分析工具不能同等地检测Java多线程程序中的错误和错误模式。

需要的措施:Java多线程错误,Java多线程错误模式,错误检测能力。

5.1.3变量选择

实验的独立变量是两个“程序集”,即具有多线程错误的程序集和具有多线程错误模式的程序集。实验的因变量是所选工具的缺陷检测能力。缺陷检测能力的两种测量方法是缺陷检测率和假阳性比率,计算公式如下:

5.1.4选择主题

第2节讨论的静态分析工具是研究的主题。在开源软件领域,所选的开源工具FindBugs [2,5,11-14,18,20,21,23-26,28]和Jlint [1,12,18,20,21,25,26 ,28]是学术界讨论最多的工具。我们坚信它们代表着开源工具。虽然,用商业工具的研究不是很常见,它们的工业应用[4,15]反映它们充分代表了商业静态分析工具。

5.1.5实验设计

在实验中,所有主体(工具)将测试所有对象(程序集)。这里,自变量“程序集”是唯一的实验因素。由于每个受试者将经历该因子的每一种可能的处理,因此实验设计是完整的块设计。表5示出了第一组程序的实验设计。相同的设计应用于第二组程序。

5.1.6仪器

我们将使用Eclipse(版本3.4.2)环境用于工具Coverity Prevent,FindBugs和Jtest,因为它们都为Eclipse提供插件。Jlint将在命令行模式下使用,因为它不提供图形用户界面。

在静态分析工具中,我们将激活所有与多线程相关的检查器/规则,并在完全分析模式下设置工具。 Coverity Prevent将同时应用并发和预览(检查器的集合仍在开发中)检查器。 Jtest结合了一组名为线程安全编程的规则,用于测试程序。在FindBugs中,多线程正确性“bug类别将使用最低优先级报告级别为低,分析工作量为最大。Jlint将与+ all命令行选项一起使用。

实验在Windows环境中执行,在具有Intel®CoreTM2四核CPU和3GB主内存的系统上。 JRE 1.6用作Java虚拟机,而MS Excel用于收集实验数据。

5.1.7有效性评估

结论有效性。针对工具的并发检查器/检测器测试所选择的程序。工具报告的警告记录并仔细检查。因此,结论有效性不被认为是至关重要的。

内部和构造有效性。所有选定的主题都是具有并发性错误检测能力的Java静态分析工具。所选受试者的分类和实验的测量是直接的。在这两个有效性类别中没有观察到显着的威胁。

外部有效性。所选基准程序的平均大小是267行代码,这是小的。在现实世界中,静态分析器处理程序,甚至有数百万行代码。我们可以使用几个中型到大型开源Java项目,而不是使用这些小的基准程序。然而,在我们在基准程序中发现的几个项目中,不可能找到各种多线程错误。此外,对从这样的程序产生的所有警告进行分类将是非常耗时的,因此实际上是不可能的。比较Java错误查找工具的研究[21]使用5个中等大小的开源项目,报告了从4个SA工具生成的9000多个并发警告。这项研究无法确定由于大量警告产生的假阳性和假阴性警告,这在文章的有效性部分的威胁中提到。

虽然基准程序覆盖了各种并发错误,但它们并不是均匀分布在不同的类别中。表6显示死锁和活锁类别中的错误的频率分别为四和二。这些类别中的更大的错误样本将使结果更一般化。每个类别中唯一选择的错误模式的数量在尺寸和分布方面相当令人满意,除了表4中所示的类别活锁。

5.2实验操作

作为实验的准备,我们收集并组织了测试程序。第一组包含错误的程序是从基准中收集的。第二组中的程序(错误模式)是从不同的来源收集的。我们编写/改进了第二套的几个程序,因为它们既不可用也不完整。

实验进行超过450人小时。对于每个程序,首先,我们读取每个基准程序提供的程序描述。然后我们检查代码以识别程序中的错误。在检查期间,我们发现很少有基准程序记录的错误不是一个错误的情况。我们从错误列表中排除这种虚假记录的错误。此外,我们发现了一些在基准文档中没有描述的错误。我们记录了这些新的错误。然后我们用工具测试程序。我们记录了工具生成的警告,并检查每个警告,将其分为真或假警告。我们发现这些工具报告了大量的警告,这些警告就像关于不同编码风格和标准的一般警告。我们将它们归类为一般警告。一个重要的事实是,基准程序中的所有错误都与多线程正确性有关。我们发现了这些工具报告的与软件性能问题相关的几个警告。我们已将这些警告记录为一般警告。由于时间的限制,我们不能确定几个警告为真或假,因此我们将它们标记为未决定。

为了根据bug模式来评估工具,我们针对从第4节中提到的bug模式的统一导出的87个独特的bug模式进行了测试。对于bug模式程序,我们只检查工具是否能够检测它。我们没有进一步分析警告,以确定假阳性警告。这是因为,bug模式程序非常小,大多数情况下,他们缺乏适当的上下文,我们可以说一个已识别的模式是否作为一个bug。 因此,试图识别错误模式的假阳性警告是无意义的。

6.分析和结果

6.1测试并发错误

我们测试了包含32个多线程错误的20个Java程序的SA工具。所有这些32个错误都与软件正确性有关。然而,这些工具能够检测由bug模式测试探究的性能相关缺陷。表6显示了所选SA工具检测到的错误。所选的基准程序包含11种不同类型的错误。这些错误类型的详细描述可在开发基准套件的研究人员所进行的研究[9]中找到。本文提供了一种并发错误的分类法作为一种bug模式。 然而,这些错误模式通常比工具实际实现的错误模式更高级别。 即使基准程序将缺陷描述为错误模式,它们也是多线程错误。

在数据竞争和原子性违规类别中有26个错误,死锁中有4个错误,活锁类别中有2个错误。从表6,显然Jtest是检测数据种族和原子性错误的工具的赢家。在死锁类别中,Jtest和Jlint都会检测到4个缺陷。没有一个工具可以检测到弱现实(两阶段访问),阻止关键段和孤立线程错误。 Coverity Prevent检测到的所有5个错误属于类别数据竞争和原子性违规。 FindBugs还检测到5个错误,其中4个错误在数据竞争和原子性违反类别和死锁类别中的1个错误。Jlint检测到8个错误,这超过了Coverity Prevent和FindBugs。

我们已经记录并检查了工具生成的每个警告。警告的概述如表7所示。一般警告类别包含那些与程序正确性不完全相关的警告。一般警告与软件开发组织可能或可能不遵循的质量和标准相关。这种警告的重要性因组织而异。

与其他工具相比,Jtest报告了大量警告,其中超过75%是一般警告。在136个一般警告中,从名为TRS.NAME的单个Jtest规则生成50个警告,用于检查线程是否初始化其名称。 Jtest规则TRS.SOUF报告23个警告,检查是否使用非最终字段来同步代码块。 规则TRS.CIET生成另外22个警告,说不在一个不扩展Java Thread类的类中捕获InterruptedException。另外22个警告来自规则TRS.STR,它检查'this'引用是否用于同步代码块。这四个Jtest规则报告了117个警告,我们归类为一般警告。

Jlint没有质量和样式相关的并发规则,因此它没有产生任何一般警告。Coverity Prevent有一个名为UNEXPECTED_SYNC的预览检查程序,它与性能问题相关。这个检查器报告了5个警告,我们将其记录为一般警告。有趣的是,FindBugs只报告了两个一般警告,23个检查器和40个错误模式,其中几个错误模式解决质量和样式问题。

表8中显示了唯一假阳性警报的数量以及工具的假阳性比率。 虽然,FindBugs和Coverity Prevent在假阳性比率中几乎相同,FindBugs可以被认为是更好的,因为与Coverity Prevent相比,它检查了大量的错误模式。以同样的方式,Jtest和Jlint的假阳性比率是相同的,但是Jtest可以看作是更强大的,因为它检查比Jlint更多的错误模式。

6.2。测试并发错误模式

我们使用工具测试了87个独特的bug模式,如表3所示。预期每个工具都应该能够检测到它声称检测到的错误模式,反之亦然。工具几乎能够检测到bug模式,如承诺。几乎没有观察到工具不能检测到它声称检测到的错误模式的情况。在很少的情况下观察到的错误模式检测器的强度不同,尽管它们以相似的方式描述。

五个案例中,Coverity Prevent和Jlint未能检测到错误模式,尽管他们有这些错误模式的检测器。Coverity Prevent的跳棋是“违规”,“双重锁定”和“不安全laze初始化”,其中“被违规守卫”是定期生产检查。 Jlint的失败bug模式检测器是“方法名称可以从不同的线程调用并且不同步”,以及“类的字段名称”。与这些情况相反,Jlint错误模式“循环id:调用同步方法名称可能导致死锁”检测Jtest描述的错误模式TRS.CSFS。但是,这两个bug模式并不完全等同。Jlint的bug模式可以检测锁定图的周期,这比Jtest的TRS.CSFS规则强得多。表9显示了工具在不同类别中检测到的错误模式数。

Jtest比其他工具在检测bug方面要好得多。然而,它也比其他工具在生产警告方面处于领先地位。FindBugs和Coverity Prevent在检测错误和报告假阳性警告方面几乎相同。Jlint检测到比FindBugs和Coverity Prevent更多的错误。但是,它还报告了最大数量的假阳性警告,如Jtest。Jtest检测最大错误模式后跟FindBugs,Jlint检测到比Coverity Prevent更多的错误。

总的来说,商业工具比开源工具在检测Java并发错误和错误模式方面更好。然而,如果考虑假阳性警报的数量,则该区别不是非常重要。用户需要在工具的错误检测率和假阳性比率之间进行权衡以选择适当的工具。如果检查假阳性警告的成本小于早期缺陷检测所节省的金额,那么Jtest应该是最好的选择。如果检查更多的假阳性警告成本,则可以选择FindBugs或Coverity Prevent。

用户可以选择从不同的工具选择具体的错误检测器。例如,Jlint提供的死锁检测器相当强。 然而,这并不意味着Jlint足以检测死锁错误。

对结果的有趣观察反映了错误检测的数量与工具报告的假阳性警告的数量之间的关系。 检测更多错误的工具会产生更多的假阳性警告。然而,不进行进一步分析是否这一观察总是真实的,因为它不包括本研究的范围。

7讨论

工具Jtest检测到大约一半的多线程错误,事实是它产生大量的假阳性警告。Coverity Prevent工具从假阳性警告的角度来看是有希望的,但是这个工具在检测故障方面相当弱。一个原因可能是在所选择的工具中由该工具呈现的并发错误检测器的最小数目。我们发现,开源工具FindBugs和Jlint检测到不同的缺陷,因此它们应该组合使用。

虽然Jlint产生大量的假阳性警告,并且Jlint的命令行用户界面不是用户友好的,强烈建议除了任何其他工具之外使用Jlint的死锁检测器。我们发现Jlint的死锁检测器在检测错误方面相当强大,并且它们报告的错误肯定警告少于竞态条件检测器。我们已经确定Jlint多次报告类似的警告。将这样的警告分组为单个警告将减少报告的警告的数量,这将既节省时间并增加该工具的可用性。

FindBugs提供了一个简单灵活的GUI界面,作为eclipse插件和独立的swing界面。 FindBugs有一组丰富的错误模式检测器,它报告很少的假阳性警告。虽然FindBugs发现了很少的并发性错误,但Coverity Prevent用户应该使用它,因为它识别了不同的Bug,而不是Coverity Prevent。

Jtest用户应该在使用它们之前检查探测器,特别是在“一般警告/错误”和“质量和风格问题”类别中的警告,因为一些探测器可能产生大量的一般警告。

FindBugs和Coverity Prevent显示某些检测器的事件列表,这些检测器在检查相应的警告时非常有用。 Jlint重复地为这些检测器生成警告,其中Jtest仅报告关于缺陷的单个警告,而没有进一步的细节。这将是很容易理解它与一个例子。让我们假设在方法的三个位置使用共享字段而不被锁定。 FindBugs和Coverity Prevent都将报告一个警告,其中包含三个事件的详细信息,其中字段被访问而不被锁定。 Jlint将报告3个不同的警告,Jtest将报告一个警告,而不包含三个访问的详细信息。

FindBugs的swing界面提供了一个非常灵活的界面,以自定义的方式查看报告的警告。 Jtest还提供了报告警告的良好视图。它按类别,然后按优先级,然后按规则分组警告。因此,用户只能看到由特定规则生成的所有警告或在特定优先级下警告的所有规则。

我们已经识别了由表7中所示的工具报告的大量一般警告。如果在必要时使用它们,则可以跳过这些一般警告。为此,规则/检查器/错误模式需要在使用前根据某个项目的标准进行审查。

在检查基准程序时花了相当多的时间。所选的基准程序实现某些并发错误。然而,在检查源代码时,我们发现了几个并发缺陷,这些缺陷在可用的基准文档中没有讨论。然而,可用的错误文档并没有提到在程序中可能有额外的并发错误。如果基准测试用户完全依赖于基准测试程序中存在的错误,可能会导致不正确的错误检测率和假阳性比率。我们在从基准套件中选择的程序中发现了11个新的并发性错误,如附录A所示。

我们强烈建议对SA工具的错误模式检测器进行更严格的分类。这将有助于用户更容易地学习和审查错误模式检测器。对工具报告的警告的分析表明,从几个数量的错误模式检测器产生了大量的一般警告。精细的分类法将帮助用户识别对于某个软件项目的标准不是很必要或关键的这种检测器。

虽然静态分析工具报告假阳性警告,但它们可以用于检测并发缺陷。工具的平均缺陷检测率为0.25,这与缺陷的早期检测在软件开发的成本降低中是至关重要的问题的事实不难理解。

8相关工作

C. Artho [1]评估了三个动态(MaC,Rivet,Visualthreads)和两个SA分析工具(Jlint和ESC / Java),用于在Java程序中查找多线程错误。研究结果表明,没有一个工具是明确的赢家。这项研究的一个主要部分是关于扩展Jlint工具。

一项研究[21]使用五个Bug查找工具,即Bandera,ESC / Java 2,FindBugs,Jlint和PMD来交叉检查他们的错误报告和警告。这项研究确定了工具报告的重叠警告。他们将警告分成不同的bug类别,其中并发性被标识为类别之一。最后,提出了一个元工具,它结合了所使用的所有五个工具的警告。

在上面讨论的两个研究中,第一个研究工作检测并发性错误,第二个研究使用并发性作为一个问题。然而,我们发现几个研究从不同的角度评估静态分析工具,而不是检测并发性错误。这些研究在下面讨论。

C. N. Christopher [5]评估了四个具有理想框架的SA框架。 评估结果表明,没有框架是理想的。然而,FindBugs和Soot比PMD和Crystal相对更好。评价的重点是框架的可用性,而不是工具。

一项研究[20]评估了四个商业和七个开源SA工具。本研究还推荐了六个步骤的方法来评估软件的质量。

两个工业案例研究结果在[23]中描述,其中两个SA错误模式工具,FindBugs和PMD应用于评估。然而,这项研究没有讨论任何并发问题。另一个工业案例研究[24]分析了错误发现工具测试和检查的相互关系。研究表明,测试工具检测更多缺陷,但工具不检测通过检查发现的一些缺陷。因此,结合这两种测试是很好的。

另一项研究[25]比较了八个SA工具来检测Java中的安全编码启发式违反。这些工具确定了115种不同的违反安全编码试探法的方法,并开发了一种能使理解更容易应用的分类法。

F. Wedyan et al[26]评估自动化SA工具的Java程序的有用性。他们评估SA工具检测缺陷和识别代码重构修改的有效性。

9结论

我们已经评估了用于检测Java多线程错误和错误模式的静态分析工具。使用一组包含并发性错误和一组错误模式的基准程序来执行实验。我们检查了工具报告的每个警告,测试基准程序,并将其分为真实或假阳性警告。从工具和反模式库中收集了总共141个错误模式。我们确定了87个独特的错误模式,并针对他们测试了工具。此外,我们分类所有的bug模式,这将帮助用户快速学习和审查由工具实现的错误模式检测器。

工具Jtest的缺陷检测率为0.47,其中工具的平均缺陷检测率为0.25。这揭示了单独的静态分析工具不足以检测并发性错误的事实。此外,工具报告了假阳性警告,这与检测到的缺陷数量大致相同。然而,使用这些工具早期检测缺陷是一个好主意。对错误模式的实验表明,所选择的工具能够检测大范围的错误模式。总的来说,商业工具比开源工具更好。然而,这些工具的有效性在检测不同类别中的错误和报告假阳性警告方面有所不同。如果用户利用多个工具来检测不同类别中的错误,这将是更有利的。

记录的bug模式可能在它们之间具有冲突和依赖性。一些工具排列了错误检查器,具有不同的优先级。然而,这项研究没有考虑bug模式的优先级。未来的工作是可能的,以识别冲突,依赖性和bug模式的优先级。

10参考书

[1] C. Artho, “Finding faults in multi-threaded programs,” Master's thesis, Institute of Computer Systems, Federal Institute of Technology, Zurich/Austin, 2001.

[2] N. Ayewah, W. Pugh, J.D. Morgenthaler, J. Penix, and Y. Zhou, “Evaluating static analysis defect warnings on production software,” 7th ACM SIGPLAN-SIGSOFT Workshop on Program Analysis for Software Tools and Engineering, June 13, 2007 - June 14, 2007, San Diego, CA, United states: Association for Computing Machinery, 2007, pp. 1-7.

[3] D. Baca, B. Carlsson, and L. Lundberg, “Evaluating the cost reduction of static code analysis for software security,” 3rd ACM SIGPLAN Workshop on Programming Languages and Analysis for Security 2008, PLAS'08, June 8, 2008 - June 8, 2008, Tucson, AZ, United states: Association for Computing Machinery, 2008, pp. 79-88.

[4] Coverity Prevent. [online]. Viewed 2009 august 13. Available: http://www.coverity.com/products/coverityprevent.html

[5] C.N. Christopher, “Evaluating Static Analysis Frameworks,” Carnegie Mellon University Analysis of Software Artifacts, 2006.

[6] Y. Eytani, K. Havelund, S. Stoller, and S. Ur, “Towards a framework and a benchmark for testing tools for multi-threaded programs,” Concurrency and Computation Practice & Experience, vol. 19, Mar. 2007, pp. 267-79.

[7] Y. Eytani, K. Havelund, S. Stoller, and S. Ur, “Toward a benchmark for multi-threaded testing tools,” Concurrency and Computation: Practice and Experience, 2005.

[8] Y. Eytani, R. Tzoref, and S. Ur, “Experience with a concurrency bugs benchmark,” 2008 IEEE International Conference on Software Testing Verification and Validation Workshop (ICSTW), 9-11 April 2008, Piscataway, NJ, USA: IEEE, 2008, pp. 379-84.

[9] E. Farchi, Y. Nir, and S. Ur, “Concurrent bug patterns and how to test them,” Los Alamitos, CA, USA: IEEE Comput. Soc, 2003, p. 7 pp.

[10] FindBugs Bug Description. [online]. Viewed 2009 august 13. Available: http://findbugs.sourceforge.net/bugDescriptions.html

[11] J.S. Foster, M.W. Hicks, and W. Pugh, “Improving software quality with static analysis,” 7th ACM SIGPLANSIGSOFT Workshop on Program Analysis for Software Tools and Engineering, June 13, 2007 - June 14, 2007, San Diego, CA, United states: Association for Computing Machinery, 2007, pp. 83-84.

[12] H. Hallal, E. Alikacem, W. Tunney, S. Boroday, and A. Petrenko, “Antipattern-based detection of deficiencies in Java multithreaded software,” Proceedings. Fourth International Conference on Quality Software, 8-9 Sept. 2004, Los Alamitos, CA, USA: IEEE Comput. Soc, 2004, pp. 258-67.

[13] D. Hovemeyer and W. Pugh, “Finding concurrency bugs in Java,” Proceedings of the PODC Workshop on Concurrency and Synchronization in Java Programs, St. John's, Newfoundland, Canada, 2004.

[14] D. Hovemeyer and W. Pugh, “Finding bugs is easy,” ACM SIGPLAN Notices, vol. 39, 2004, pp. 92-106.

[15] Java testing tools: Static code analysis, code review, unit testing. [online]. Viewed 2009 august 13. Available: http://www.parasoft.com/jsp/products/home.jsp?product=Jtest

[16] B.A. Kitchenham, “The case against software benchmarking, keynote lecture,” Proceedings of The European Software Measurement Conference (FESMA-DASMA 2001), Heidelberg, May 2001, pp 1–9.

[17] S. Lipner, The Trustworthy Computing Security Development Life Cycle, Proceedings of the 20th Annual Computer Security Applications Conference (ACSAC’o4), p.213, 2004.

[18] B. Long, P. Strooper, and L. Wildman, “A method for verifying concurrent Java components based on an analysis of concurrency failures,” Concurrency and Computation Practice & Experience, vol. 19, Mar. 2007, pp. 281-94.

[19] N. Nagappan and T. Ball, “Static analysis tools as early indicators of pre-release defect density,” 27th International Conference on Software Engineering, ICSE 2005, May 15, 2005 - May 21, 2005, Saint Louis, MO, United states: Institute of Electrical and Electronics Engineers Computer Society, 2005, pp. 580-586.

[20] F. Painchaud and R. Carbone, Java software verification tools: Evaluation and recommended methodology, Technical Memorandum. Defence R&D Canada. Document No. TM 2005226. March 2006. http://cradpdf.drdc.gc.ca/PDFS/unc57/p527369.pdf

[21] N. Rutar, C.B. Almazan, and J.S. Foster, “A comparison of bug finding tools for Java,” ISSRE 2004 Proceedings; 15th International Symposium on Software Reliability Engineering, November 2, 2004 - November 5, 2004, Saint-Malo, France: IEEE Computer Society, 2004, pp. 245-256.

[22] W.F. Tichy, “Should computer scientists experiment more?,” Computer, vol. 31, 1998, pp. 32-40.

[23] S. Wagner, F. Deissenboeck, M. Aichner, J. Wimmer, and M. Schwalb, “An evaluation of two bug pattern tools for Java,” 2008 First IEEE International Conference on Software Testing, Verification and Validation (ICST '08), 9-11 April 2008, Piscataway, NJ, USA: IEEE, 2008, pp. 248-57.

[24] S. Wagner, J. Jurjens, C. Roller, and P. Trischberger, “Comparing Bug finding tools with reviews and tests,” Testing of Communicating Systems. 17th IFIP TC6/WG 6.1 International Conference TestCom 2005. Proceedings, 31 May2 June 2005, Berlin, Germany: Springer-Verlag, 2005, pp. 4055.

[25] M.S. Ware and C.J. Fox, “Securing Java code: heuristics and an evaluation of static analysis tools,” Proceedings of the 2008 workshop on Static analysis, Tucson, Arizona: ACM, 2008, pp. 12-21.

[26] F. Wedyan, D. Alrmuny, and J. Bieman, “The effectiveness of automated static analysis tools for fault detection and refactoring prediction,” 2009 2nd International Conference on Software Testing Verification and Validation (ICST 2009), 1-4 April 2009, Piscataway, NJ, USA: IEEE, 2009, pp. 141-50.

[27] C. Wohlin, P. Runeson, M. Host, M. C. Ohlsson, B. Regnell and A. Wesslen, Experimentation in Software Engineering:An Introduction, Kluwer Academic Publishers, 2000.

[28] M.A. Wojcicki and P. Strooper, “Maximising the information gained from a study of static analysis technologies for concurrent software,” Empirical Software Engineering, vol. 12, 2007, pp. 617-645.

[29] L. Yu, J. Zhou, Y. Yi, P. Li, and Q. Wang, “Ontology Model-Based Static Analysis on Java Programs,” Proceedings of the 32nd Annual IEEE International Computer Software and Applications Conference-Volume 00, IEEE Computer Society Washington, DC, USA, 2008, pp. 92-99.

说明:还有几个附录,中间主要讲述了详细的错误的分类。

你可能感兴趣的:(译文《A Systematic Review and an Evaluation of Static Analysis Tools》)