java串口编程程序_ARJA:基于多目标遗传编程的 Java 程序自动修复

c54a8335c39f78e9359a1766ebb3ba93.png
img

引用

Yuan Y , Banzhaf W . ARJA: Automated Repair of Java Programs via Multi-Objective Genetic Programming[J]. IEEE Transactions on Software Engineering, 2018:1-1.

摘要

自动程序修复是指自动修复程序中的错误,以显著降低调试成本和提高软件质量的问题。为了解决这个问题,基于测试套件的修复技术将给定的测试套件视为预言,并修改输入错误程序以使整个测试套件通过。GenProg 被公认为这类修复方法中的佼佼者,它使用遗传编程(GP)来重新排列已经存在于错误程序中的语句。然而,最近的实证研究表明,GenProg 的性能并不完全令人满意,特别是对于 Java。本文提出了一种新的基于 GP 的 Java 程序自动修复方法 ARJA。具体地说,我们提出了一种新的低粒度补丁表示方法,它将可能出现错误的位置、操作类型和潜在修复成分的搜索子空间解耦,使 GP 能够更有效地探索搜索空间。在此基础上,我们将自动程序修复描述为一个多目标搜索问题,并使用 NSGA-II 寻找更简单的修复。为了减少计算量和搜索空间,我们引入了一个测试过滤过程来加速 GP 的适应度评估,并引入了三种规则来避免不必要的代码操作。此外,我们还提出了一种类型匹配策略,利用现有语句的语法模式来创建新的潜在修复成分。我们对 ARJA 及其变种进行了大规模的经验评估,并与几种最先进的修复方法进行了比较。我们的结果验证了 ARJA 中所使用的搜索机制的有效性和效率,并显示了它相对于其他方法的优越性。ARJA 还能够正确地修复一些现有修复方法难以修复的实际多位置 bug。

1 简介

自动程序修复旨在自动修复软件中的 bug。这一研究领域最近在软件工程界引起了极大的兴趣,因为它试图解决一个非常实际和重要的问题。自动修复技术通常依赖于预言,它可以由测试套件、前后条件或抽象行为模型组成。

我们的研究重点是基于测试套件的程序修复,它将给定的测试套件视为预言。测试套件应该至少包含一个最初失败的测试用例,这些测试用例暴露了要修复的 bug,以及一些最初通过的测试用例,它们定义了程序的预期行为。就基于测试套件的修复而言,如果修复方法生成的修补程序使整个测试套件通过,则该 bug 被称为已修复或已修复。获得的补丁可以称为测试套件适配补丁。

GenProg 是基于测试套件的程序修复中最著名的修复方法之一。这种通用方法基于冗余假设,这意味着可以用于生成修复的代码(称为修复成分)已经存在于错误程序的其他地方;它使用遗传编程搜索可以满足测试套件的潜在补丁。尽管 GenProg 作为一种最先进的修复方法得到了广泛的认可,但它在一些研究者中引起了一定的学术争议。

首先,Qi 等人对 GenProg 基准测试的结果表明,用随机搜索代替 GenProg 中的 GP 可以提高修复效率和修复效率,从而质疑 GP 在自动化程序修复中的必要性和有效性。第二,最近进行的一项实证研究指出,GenProg 报告的绝大多数补丁是不正确的,相当于一个单一的功能缺失。这里我们不关注补丁的潜在错误,这主要是由于测试套件的脆弱,而不是修复方法。我们主要关注的是 GenProg 通常会生成无意义的补丁,这对 GP 生成有意义或语义复杂的修复表达能力提出了挑战。最后,最近的一个大规模实验表明,GenProg 针对 Java 的一个实现(称为 jGenProg)只能为 224 个真实的 Java 错误中的 27 个找到合适的补丁,并且只有 5 个被确认为正确的。显然,jGenProg 的性能目前还远远不能令人满意。

考虑到有关 GenProg 的这些负面报道,有必要重新审视该系统最显著的特征,使其成为一个完善的维修系统。我们认为至少有两个重要特征。一是 GenProg 可以扩展到大型程序,这主要是因为它的补丁表示法。另一个是 GenProg 可以潜在地解决各种类型的 bug,因为 GP 的表达能力允许对代码进行不同的转换。特别是 GP 可以同时更改程序的多个位置,因此 GenProg 可能会修复大多数其他修复方法无法处理的多位置错误。GenProg 的可伸缩性是显而易见的,因为它已被广泛应用于大型现实世界软件,这使得它区别于那些主要局限于小型程序的方法(例如 SemFix 和 SearchRepair)。然而,如前所述,继承了 GP 的 GenProg 的表达能力并没有被文献中最近的实验研究所证实。我们认为说明并解决这个问题是非常重要的,这将使 GP 真正能够强有力地应用于自动化程序修复。

一般来说,一个成功的修复系统包括两个关键元素:1)包含正确补丁的搜索空间;2)能够有效和高效地导航搜索空间的搜索算法。对于搜索空间,GenProg 使用冗余假设,这一假设已经被两个独立的实证研究所证实。这使得搜索算法成为一个瓶颈,可能会 GenProg 导致无法发挥其生成非平凡补丁的潜力。原因可能是 GenProg 中底层 GP 算法的搜索能力不足以真正维持其表达能力。

基于此分析,我们的主要目标是提高通过 GP 搜索程序修复的有效性。为此,我们提出了一个新的基于 GP 的 Java 程序自动修复修复系统 ARJA。ARJA 主要特点是:一种新颖的 GP 补丁表示,多目标搜索,以及几种缩小搜索空间的策略。我们的结果表明,完全遵循冗余假设的 ARJA 版本可以为 Defects4J 的四个项目中的 59 个实际 bug 的测试套件生成充足的补丁,而 jGenProg 只报告了 27 个。通过手工分析,我们发现这个 ARJA 版本可以为 Defects4J 中的至少 18 个 bug 生成一个正确的补丁,而 jGenProg 只有 5 个。据我们所知,18 个正确修复的 bug 中有一些从未通过其他修复方法得到正确修复。此外,ARJA 能够正确地修复一些现有修复方法难以解决的多位置错误。本文的主要贡献如下:

1)解的表示是关系到 GP 性能的一个关键因素。灵感来自 Oliveira 等人的作品提出了一种新的基于 GP 的程序修复补丁表示方法,该方法将可能出现错误的位置、操作类型和替换/插入代码的搜索子空间解耦。

2)我们建议将自动程序修复作为一个多目标优化问题来制定,并使用 NSGA-II 来搜索潜在的修复。

3)在 ARJA 搜索的三个不同阶段(操作初始化阶段、成分筛选阶段和解解码阶段)引入了三种规则,以有效地减少搜索空间。

4)虽然我们的研究主要集中在对搜索算法的改进上,但是我们也努力在重用程序中已经存在的代码的基础上合理地丰富搜索空间。为此,我们提出了一种类型匹配策略,该策略可以利用现有代码的语法模式来创建有前途的新代码来修复错误。

5)我们对 18 个种子 bug 和 224 个真实 bug 进行了大规模的实验研究,从中获得了一些新的发现和见解。

6)我们为 Java 开发了一个公共可用的程序修复库,目前包括我们提出的方法(即 ARJA)的实现,以及最初为 C 设计的三种修复方法(GenProg、RSRepair 和 Kali)。希望该库能够促进 Java 软件自动修复的进一步研究。

2 目标和动机

本研究的总体目标是开发一个更强大的基于 GP 的 Java 程序自动修复系统。为此,我们对 GenProg 的潜在局限性进行了分析,以指导我们新系统的设计。GenProg 中有几个不足之处促使我们追求这个目标,下面将讨论这些缺陷。

2.1 高粒度补丁表示

在 GenProg 中,补丁表示中的每个基因(参见图 2(a))是一个高粒度的编辑操作,其中操作类型、可能的错误位置(即目的语句)和替换/插入代码对于交叉(参见图 2(b))和突变(参见图 2(c))运算符是不可见的。通过 GP 操作这样的高级单元会阻碍解之间遗传信息的有效重组。这主要是因为编辑的良好部分信息(例如,有希望的操作类型、准确的故障位置和有用的替换/插入代码)不能从一个解传播到其他解。

ab6df56dbf6dc029ac10aa897a9b3ced.png
img

图 2 GenProg 中的补丁表示、交叉和变异说明

2.2 Oliveira 等人的补丁表示法

最近,Oliveira 等人提出了一种较低粒度的补丁表示方法,在编辑操作中,将三种局部信息对应的三个子空间解耦。使用该表示法,图 2(a)中表示的补丁可以被重新格式化为如图 3(a)所示的那样,其中表示被分为三个不同的部分:第一部分是操作类型的列表,第二部分是可能的错误位置的列表,第三部分是替换/插入代码的列表。

0c912357b949bf7b5d46bcb40e4fdf62.png
img

图 3 Oliveira 等人介绍的补丁表示和交叉说明

基于这种表示,Oliveira 等人进一步提出了三种交叉算子。图 3(b)示出了其中一个称为 OP1SPACE 的例子。该交叉首先随机选择表示中的一个部分,然后在保持其他两个部分不变的情况下仅对该部分进行单点交叉。然而,由于杂交后三个部分的基因数目不同,存在一些无效基因需要剔除才能得到最终的后代解。去除无效基因可能导致信息丢失。为了缓解这个问题,他们引入了一种记忆方案来重用无效基因。

Oliveira 等人的补丁表示法虽然在一定程度上克服了 GenProg 对搜索能力限制过大的缺点,但也可能带来新的问题。一个问题是无效的基因会导致好的部分信息的丢失。记忆方案可能有帮助,但它似乎没有增加修复的成功率。另一个问题是,这种表示上的交叉在不同的可能有错误的位置之间交换操作类型和替换/插入代码的信息。然而,这种情况可能并不理想,因为每个可能的位置都有其自己的语法/语义上下文,并且它们更可取的操作类型和替换/插入代码可以有很大的变化。此外,由于作用域问题,仅可用的替换/插入代码在不同的可能有错误的位置可能会有很大不同,因此在这些位置之间交换替换/插入代码可能很容易导致不可编译的程序变体。

我们的研究旨在提出一种新的低粒度补丁表示方法,该方法能够解决 GenProg 表示的局限性,同时避免了文中引入的表示方法所带来的上述两个问题。

2.3 关于多编辑修补程序的限制

一个 bug 修复通常需要对 bug 程序进行多次编辑。例如,在 Defects4J 中的四个项目的 224 个真实 bug 中,超过三分之二的人工编写的补丁包含至少两个语句级的编辑。然而,现有的大多数修复方法在创建多编辑修补程序方面都很差。基于 GP 的方法(如 GenProg)可以同时处理多个错误语句,因此它们有可能找到多个编辑补丁。然而,Qi 等人的一项实证研究表明 GenProg 生成的大部分补丁实际上相当于一个单一功能的删除。最近关于 Defects4J 的实验结果也表明 GenProg 没有成功地修复任何可能需要多次编辑的 bug。据我们所知,对于 GenProg 在生成多编辑补丁方面的弱点,文献中还没有达成共识。我们认为 GenProg 中底层 GP 的搜索能力非常重要。

我们的研究旨在通过一个新的具有更强搜索能力的多目标 GP 来解决 Gen

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值