Automatic Patch Generation Learned from Human-Written Patches文章记录

本文介绍了一种新的自动补丁生成技术PAR,该技术从人工编写的补丁中学习修复模式。通过对大量开源补丁的分析,作者们识别出常见的修复模式并创建了修复模板。在对119个真实bug的评估中,PAR成功生成了27个补丁,比GenProg的16个更成功。用户研究也表明,PAR生成的补丁比GenProg的更容易被接受。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Automatic Patch Generation Learned from
Human-Written Patches
从手写的补丁中学习自动生成补丁

作者:Dongsun Kim, Jaechang Nam, Jaewoo Song, and Sunghun Kim
The Hong Kong University of Science and Technology, China

摘要

补丁生成是一项必不可少的软件维护任务,因为大多数软件系统都不可避免地存在需要修复的bug。不幸的是,人力资源通常不足以修复所有报告的和已知的错误。为了解决这个问题,**提出了几种自动生成补丁的技术。**特别是,Weimer等人提出的基于遗传规划的patch生成技术GenProg已经显示出了很好的结果。然而,由于突变操作的随机性,这些技术可能会产生无意义的补丁。
为了解决这一限制,我们提出了一种新的补丁生成方法,基于模式的自动程序修复(PAR),使用从现有人工编写的补丁中学习的修复模式。
我们手动检查了超过60,000个人工编写的补丁,发现有几个常见的修复模式。我们的方法利用这些修复模式自动生成程序补丁。我们对119个真实的bug进行了实验评估。此外,一项涉及89名学生和164名开发人员的用户研究证实,由我们的方法生成的补丁比由GenProg生成的补丁更容易接受。PAR在119个错误中成功生成了27个,而GenProg只成功生成了16个错误。

1介绍

为了减少人工的工作量,人们提出了几种自动生成补丁的技术。Arcuri和Yao提出了将进化算法应用于自动生成补丁的思想。Dallmeier等人提出了一种利用对象行为模型的方法,并将该方法应用于来自开源项目的实际bug。Weimer等人提出了一种基于群体的技术,利用遗传编程。Wei等人提供了一种基于契约的技术来自动生成补丁,并通过将其应用于Eiffel类中的bug显示了它的有效性。

其中,**获奖的补丁生成技术GenProg[7]及其扩展[8]显示了最有前景的结果。为了修复给定程序中的错误,这种技术通过使用交叉操作符和变异操作符(如语句添加、替换和删除[9])来生成程序的变体。然后,它运行测试用例来评估每个变量。GenProg迭代这些步骤,直到其中一个变体通过所有测试用例。任何程序变体通过所有测试用例被认为是一个成功的补丁。**他们实验表明,这种技术可以成功地为105个真正的bug中的55个创建补丁。

然而,GenProg有一个固有的局限性:由于这种技术基本上依赖于随机的程序突变,如语句的添加、替换和删除,因此可能生成无意义的补丁。图1(b)显示了一个由GenProg为图1(a)所示的bug生成的无意义补丁的示例。与图1©中人工编写的补丁相比,GenProg的补丁完全从程序中删除了“strings[]”变量。注意,只要给定的索引是有效的,程序就会给lhs分配一个字符串元素,而GenProg生成的补丁不会这样做。尽管GenProg的补丁实际上可以通过所有给定的测试用例,但开发人员不会接受这个补丁,如Section IV-C所示。

为了解决这个问题,我们提出了一种新的补丁生成技术:基于模式的自动程序修复(PAR)这种方法利用了人类编写补丁的知识。我们首先仔细检查了62,656个人工编写的开源项目补丁。有趣的是,我们发现有几个常见的固定模式。根据我们的观察,**我们创建了10个修复模板,它们是基于确定的修复模式的自动程序编辑脚本。****解析这些修复模板以生成程序补丁。**尽管创建修复模板需要手工工作,但这只是一次性的成本,而且这些模板创建后在不同的上下文中具有高度可重用性。图1(d)显示了由我们的方法生成的补丁,它类似于人工编写的补丁(图1©)。

为了评估PAR,我们将其应用于从Apache log4j、Rhino和AspectJ等开源项目收集的119个实际bug。

我们询问了253名人类受试者(89名学生和164名开发人员),如果他们是PAR和GenProg生成的匿名补丁的代码审查者,他们会接受哪些补丁。本研究的结果清楚地表明,**PAR生成的补丁比GenProg生成的补丁更容易接受。**此外,我们的方法生成了比GenProg更成功的补丁:PAR在119个错误中成功生成了27个补丁,而GenProg成功生成了16个错误。

本文的主要贡献如下:
人工观察人类写的补丁:我们对人类写的补丁的调查显示,补丁中有共同的修复模式。
PAR,一种利用修复模式的自动修补程序生成技术:我们提出了一种新的自动修补程序生成技术,它使用来自公共修复模式的修复模板。
**实证评价:**我们将PAR应用于119个真实bug,给出了实证评价结果。

本文的其余部分组织如下。在第二节介绍了从人类编写的补丁中识别出的常见修复模式之后,我们在第三节中提出了我们的方法,PAR。第四节实证地评价了我们的方法,第五节讨论了它的局限性。在第六节对相关工作进行了调研之后,第七节对未来的研究方向进行了总结。

2. 常见的固定模式

本节介绍从我们对人工编写补丁的手工调查中确定的常见修复模式。我们首先描述了我们是如何收集和检查大量人类书写的补丁的。然后,我们报告一列常见的修复模式。

补丁收集

为了我们的调查,我们从Eclipse JDT中收集了62,656个人类编写的补丁。我们使用Eclipse JDT,因为它有很长的修订历史(超过10年),并且在文献中得到了广泛的应用。我们使用Kenyon框架检索漏洞补丁。

常见补丁

由于我们的目标是探索人类在补丁生成中的知识,所以我们关注的是语义而不是句法变化。首先,我们检查了补丁中是否添加或删除了任何语义。其次,我们确定了每个错误的根本原因和相应补丁的解决方案。最后,将相似的斑块分组成共同的模式。

为了减少人工检查时间,我们首先使用分组收集类似的补丁。组是表示对象使用的基于图的模型。虽然不是为补丁分析而设计的,但分组可以帮助检测语义而不是语法差异。对于每个补丁,我们从两个连续的程序版本中构建了两个组:应用补丁之前和之后。然后,自动计算两组节点和边的差值。我们可以将具有相同差异的补丁收集到一个组中。尽管补丁组不一定是固定模式,但这样做可以大大减少手工检查时间。

为了识别修复模式,我们首先将补丁分为加补丁、减补丁和改变补丁。附加补丁插入新的语义特性,如新的控制流,而减法补丁删除语义特性。更改补丁只是通过替换语义特性来更改控制流。

然后我们检查了bug的根本原因,以及相应的补丁是如何专门解决这些bug的。例如,图2所示的补丁会插入一个新的if语句,以避免在fTextHoverManager为空时发生崩溃。在本例中,根本原因是“空值”,补丁通过添加新的控制流来解决它。

一些补丁处理多个原因,这些被称为复合补丁。我们将一个复合斑块划分为多个独立的斑块,并对它们进行单独分析。

修复模式

在检查这些补丁之后,我们发现了许多重复出现的类似补丁,即修复模式。表一显示了我们的调查确定的常见模式。以上8种模式几乎覆盖了我们观察到的所有斑块的30%。下面的段落描述了每个模式的细节:
在这里插入图片描述
模式:更改方法参数。
Example:obj.method(v1,v2)→obj.method(v1,v3)
描述:该模式可以修复一个bug,因为它使调用者给方法提供适当的参数。

模式:使用相同的参数调用另一个方法。
Example:obj.method1(param)→obj.method2(param)
描述:此模式更改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值