面向对象方法的有效性(有效的面向对象程序修复)
1、引用
Saha, Ripon & Lyu, Yingjun & Yoshida, Hiroaki & Prasad, Mukul. (2017). Elixir: Effective object-oriented program repair. Automated Software Engineering, 648-659. 10.1109/ASE.2017.8115675.
2、摘要本文提出了一项出于在面向对象(OO)程序中普遍使用方法调用,以及它们在 OO 程序错误补丁中的流行的工作。我们提出了一种生成和验证修复技术,称为 ELIXIR。ELIXIR 积极地使用方法调用(与局部变量、字段或常量一样)来构建更具表达性的修复表达式,用于合成补丁。
我们实现 ELIXIR 并在两个数据集上进行评估,即流行的 Defects4J 数据集和我们创建的一个新数据集 Bugs.jar,并对比技术中的两个基线版本,以及代表程序修复技术最新水平的 5 个其他技术。最终的评估显示,ELIXIR 能够将 Defects4J 中正确修复的 bug 数量增加 85%(从 14 个增加到 26 个),将 Bugs.jar 中正确修复的 bug 数量增加 57%(从 14 个增加到 22 个),同时显著优于其他最新的修复技术,包括 ACS、HD-Repair、NOPOL、PAR 和 jGenProg。
3、背景介绍软件应用程序在规模和复杂性方面不断增长,并推动新应用程序域的开发,诸如云计算、大数据分析、移动计算和软件定义网络,他们不可避免地导致相应的软件 Bug 数量的增加,最终解决这些错误的成本增加。
TIOBE 索引中排名前五,其中 Java、C 、C#和 python 四种都是面向对象语言,决定了面向对象在当今编程中的地位。 面向对象中的封装导致对象上的方法调用(MI)的构造(在本文中与术语方法调用互换使用)构成了面向对象程序中数据访问和计算的基本单元。根据同一项研究,在每个项目的生命周期中,77%的单行错误修复涉及到对方法调用的更改或插入。这些数据点表明,在修复面向对象程序中的 Bug 时,需要以一种全面的方式合并方法调用的修复和合成。
ELIXIR 开发用于修复面向对象程序,一个关键创新是大胆地使用方法调用(与局部变量、字段和常量一样)来构建更具表现力的修复表达式用于合成补丁。并通过排序选择,解决后续扩大的修复空间。我们在两个数据集(流行的 Defects4J 数据集和我们创建的新数据集 Bugs.jar 上实现和评估 ELIXIR,并对比我们技术中的两个基线版本,以及代表程序修复技术最新水平的五个其他工具/技术。主要贡献如下:
实证研究:一项强调 Java 程序补丁中方法调用盛行的实证研究,作为我们提出的技术的动机。
技术:一种新的技术,ELIXIR 在构造 Java 程序和面向对象程序的修复时积极地使用方法调用。
实现:我们内部 Java 修复框架中 ELIXIR 的实现,以及 ELIXIR 的两个基线版本。
数据集:一个包含 1,158 个 Bug 和补丁新的大型数据集,Bugs.jar,提供给某个研究社区,以补充像 Defects4J 这样的现有数据集。
评估:对 ELIXIR 在两个数据集上的综合评估,即 Defects4J 和 Bugs.jar 和七个竞争技术,包括 ELIXIR 的两个基线版本和五个外部工具/技术,ACS、HDRepair、NOPOL、PAR 和 jGenProg。
4、 ELIXIR 框架
图 1
ELIXIR 的总体结构如图 1 所示。对于给定的缺陷,ELIXIR 将一个缺陷程序、一个测试套件(至少有一个缺陷重现测试用例)和一个可选的缺陷报告作为输入,并生成一个通过所有测试用例的补丁,即修复缺陷。ELIXIR 有四个步骤。
4.1 Bug 定位。这个步骤在有问题的程序中识别出一个可疑的语句列表。然后,对于每个潜在的 bug 语句(修复位置),ELIXIR 执行以下步骤,直到找到一个可信的补丁(可信的补丁是简单地通过测试套件中的所有测试用例(包括失败的测试),但仍然可能是不正确的,因为测试套件可能提供了不完整的规范)。
4.2 生成候选补丁。ELIXIR 包含一组程序转换模式。对于每个模式,ELIXIR 通过向模式中插入各种修复表达式来生成一个候选补丁列表,并执行以下步骤,直到找到一个可行的补丁。
1)程序变换模式:ELIXIR 按照给出的顺序应用下列程序转换模式,为给定的语句生成候选补丁。
- 扩大类型(变量类型扩大,float 替换为 double)
- 更改返回语句表达式
- 检查空指针,确保不访问空对象
- 检查数组范围和集合大小,防止出现异常
- 改变中缀布尔运算符,包括变异测试研究中常见的变异运算符减弱和加强布尔表达式
- 改变方法调用(MI),比如替换对象表达式、替换方法名、替换参数、用合成的 MI 替换完整的 MI
- 方法调用的插入:合成错误,并插入他们作为一个表达式的一部分或作为一个完整的声明。
2)合成修复表达式
图 2
ELIXIR 的关键特性之一是它使用了一组丰富的修复表达式,这些表达式可以有效地修复面向对象程序中的实际 bug。这需要大量使用 MIs 和对象访问。图 2 显示了 ELIXIR 中使用的修复表达式的语法。
3)合成候选补丁
4.3 候选补丁的排序和选择。对候选补丁进行排序是一个具有挑战性的问题,因为任何有效的(即可编译的)补丁都可能是正确的补丁。我们认为程序上下文和错误报告可能提供有价值的线索,以识别真正相关的补丁。因此,我们提出了一种机器学习技术来排序和选择候选补丁,并选择前 N 个补丁进行验证。
图 3
图 3 给出了对候选补丁进行排序的总体方法。给定一组候选补丁,ELIXIR 首先使用修复表达式提取每个候选补丁的四个特征评分。特征计算评分主要与距离,上下文相似性、上下文中的频率以及错误报告相似度密切相关。修复表达式由与修复位置越接近的元素组成,它就越相关,用公式
计算距离;修复表达式在文本上与上下文越相似,就越与修复位置相关;我们还认为修复表达式由频繁使用的元素组成的越多,它在该上下文中就越相关。
然后使用逻辑回归进行排名,ELIXIR 特根据距离、上下文相关性等计算加权征得分。然后,这些特征分数被传递给一个已经训练好的 logistic 回归模型,该模型为每个候选 patch 计算一个表示其相关性的概率分数,从而选出排名前 N 的补丁。
4.4 验证选定的候选补丁。ELIXIR 从排序列表的顶部开始,一次应用一个选定的补丁到有缺陷的程序上,并运行测试用例。如果所有的测试用例都通过了,ELIXIR 终止并返回一个貌似合理的补丁。
5、实验与评估ELIXIR 是在一个我们开发的叫做 FLAiR 自动程序修复框架之上实现的,FLAiR 有自己的 bug 定位系统、各种程序转换模式、一个内存编译系统、JUnit 测试用例执行系统和一个运行时数据监控系统。在 FLAiR 框架上,我们实现了 ELIXIR 的另外两个变体。
- ELIXIR- baseline:使用与 ELIXIR 完全相同的程序转换模式。使用遵循 ACS、PAR 和 HD-Repair 等现有工具的修复表达式,这个基线帮助我们演示修复表达式集的贡献。
- ELIXIR- noml:同时使用 ELIXIR 的模式和修复表达式,不使用任何机器学习技术,随机选择 N 个 patch,这个基线展示了我们提出的排名模型。
为了严格评估 ELIXIR,选用流行的 Defects4J 和大规模成熟的现实世界数据集 Bugs.jar。为平衡正负修复表达式的数量,我们对 ELIXIR 进行训练得到数量对等的修复表达式。然后解决一下四个问题,通过实验一一验证。
RQ1:与先进方法比较
为了与 ELIXIR 作对比,我们选择了五种最先进的 G&V 修复工具,统计每种工具获取正确补丁和非正确补丁的数量,总体结果显示 ELIXIR 产生了 26 个正确的补丁,这是在 Defects4J 上最高的,次之的是最近引入的 ACS 的 18 个补丁,实验结果如表 1:
表 1
此外还研究了 ELIXIR 的各种模式下生成可信的(正确的和不正确的)补丁方面贡献,结果显示 MI 是最有效的模式。它生成了 12 个正确的补丁,接着是布尔表达式中广泛变化较为有效。
RQ2:ELIXIR 修复表达式、排序和选择的贡献
运行两个基线:ELIXIR-Baseline 和 ELIXIR-NoML,发现有着与 ELIXIR 相同的转换模式集的 ELIXIR- baseline 也可以修复 14 个 bug。通过与 RQ1 的实验表格进行比较,我们可以看到 ELIXIR-baseline 几乎和 ACS 一样好,并且优于其他工具。因此,这个结果清楚地展示了我们丰富的修复表达式的贡献。ELIXIR-noml 的结果表明,仅仅扩展修复表达式集,而不进行任何有效的选择和修剪,实际上会减少正确补丁的数量(14 对 13)。在我们的实验中,我们观察到扩展后的修复表达式的中位数是基本修复表达式的 30 倍。
RQ3:各特征在排序和选择中的作用
为了调查是否所有的特征都参与了候选补丁的排序和选择,我们在 ELIXIR 的训练和测试阶段一次关闭四个特征中的一个。结果表明,每个特征都对正确 patch 在搜索空间中的排名有所贡献,如表 2 所示。关闭任何功能都会减少正确补丁的数量。其中,距离是影响最小的特性,而 bug 报告和频率是影响最大的特性。
表 2
RQ4:ELIXIR 在 Bugs. jar 的有效性
我们从 bugs.jar 中的 7 个主题中随机选择 127 个 bug 来创建样本集,观察实验结果,ELIXIR 为 22 个 bug 生成了正确的补丁,ELIXIR-baseline 为 14 个 bug 生成了正确的补丁,在 RQ1 中,我们证明了 ELIXIRBaseline 比除 ACS 之外的最先进的技术更好。因此,下表实验结果表明,与最先进的相比,ELIXIR 在 Bugs.jar 上同样有效。
表 3
6、总结通过扩大和有效地搜索更大的修复空间,ELIXIR 能够显著增加正确修复的 bug 数量,同时也优于其他先进的工具,如 ACS、HD-Repair、NOPOL、PAR 和 jGenProg。我们相信,这项工作是一个很有前途的示范如何 AI/ML 技术可以用于扩大范围的自动程序修复技术。但是 ELIXIR 也存在一定的缺陷,我们仅在两个数据集上进行研究,可能不能推广到这些数据集之外的 bug 上。此外实验 ELIXIR 的任何实现错误都可能影响其内部有效性。对补丁正确或不正确的分类标准是基于人工分析,这在科学上并不严格,效率不高。
7、致谢本文由南京大学软件学院 2021 级硕士石孟雨翻译转述。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com