通过关联缺陷描述和代码更改来评估补丁

互联不一般哥 2024-06-16 19:04:55

Is this Change the Answer to that Problem?

Correlating Descriptions of Bug and Code Changes for Evaluating Patch

Haoye Tian1, Xunzhu Tang1, Andrew Habib1, Shangwen Wang2, Kui Liu3, Xin Xia3

1University of Luxembourg Luxembourg

2National University of Defense Technology China

3Huawei China

引用

Tian H, Tang X, Habib A, et al. Is this change the answer to that problem? correlating descriptions of bug and code changes for evaluating patch correctness[C]//Proceedings of the 37th IEEE/ACM International Conference on Automated Software Engineering. 2022: 1-13.

论文:https://dl.acm.org/doi/abs/10.1145/3551349.3556914

仓库:https://github.com/Trustworthy-Software/Quatrain.

摘要

我们提出了一个评估补丁正确性的全新视角:一个正确的补丁实现了对由缺陷行为提出的问题的“回答”。为了解决这个问题,我们的直觉是自然语言处理可以提供评估缺陷(问题)和补丁(答案)之间语义相关性所需的表示和模型。具体来说,我们将缺陷报告和生成补丁的自然语言描述作为输入。本文提出方法Quatrain,首先考虑最先进的提交消息生成模型,以生成与每个生成补丁相关的输入。然后,我们利用神经网络架构来学习缺陷报告和提交消息之间的语义相关性。在对三个缺陷数据集(Defects4j、Bugs.jar和Bears)生成的9,135个补丁的大型数据集上的实验表明,Quatrain在预测补丁正确性方面达到了0.886的AUC,能够在过滤掉62%不正确补丁的同时召回93%的正确补丁。

1 引言

生成和验证技术在自动程序修复(APR)中取得了成功,为多个基准测试中的大量缺陷生成了有效的修补程序。虽然这种技术很常见,但在工业界的应用面临一个关键问题,即其实用性:最先进的方法往往会生成过度适应弱预言(例如,测试套件)的补丁。实际上,由测试用例验证的补丁只是合理的。大多数情况下,实践者会手动发现它们是错误的。近年来,关于自动评估补丁正确性的研究非常多。我们主要识别出两类方法,利用静态或动态信息。在第一类中,只利用静态信息来决定补丁的正确性。例如,Ye等人手工制作了代码更改的静态特征,可以用于训练基于机器学习(ML)的补丁正确性分类器。类似的方法基于深度表示学习已经被提出。最近,Tian等人提出了一种系统,通过检查失败测试用例的静态相似性与代码更改的相似性来决定正确性。在第二类中,利用测试套件动态执行的轨迹进行正确性评估。为了预测补丁的正确性,Xiong等人检查了失败测试用例执行的行为变化。Shariffdeen等人依赖于符号执行来遍历测试输入和补丁空间,以减少补丁候选的数量。

尽管上述方法在补丁正确性评估方面取得了可喜的成果,但我们识别出一个根本问题和一个机会,这为本研究中探讨的新研究方向开辟了道路。作为一个根本问题,我们注意到最先进的方法通常通过主要推理代码更改,有时也推理测试用例来评估补丁的正确性。然而,很少有明确调查生成补丁所针对的错误。然而,补丁是为了解决特定的错误行为而编写的。作为一个机会,我们注意到错误报告虽然非正式,但可能提供了错误的明确描述,可以利用它来评估补丁的正确性。

图1 来自Defects4J的Closure-96错误报告及开发者补丁的相应提交信息。

据我们所知,之前没有研究将补丁正确性问题作为问答问题进行调查。我们遵循这样的直觉:当代码库维护者收到补丁时,建议的更改是根据报告的错误进行评估的。因此,该错误是一个问题。错误报告及其自然语言描述(参见图1a示例)通常提出问题。实现补丁的代码更改提供了问题的答案。描述这些更改的提交信息(参见图1b示例)通常向维护者呈现解决方案。然后,维护者可以立即判断解决方案(补丁)是否与问题(错误)相关。由人类维护者进行的补丁验证场景可能显得天真,因为开发人员还会考虑其他方面,包括错误是否真实,更改是否更具风险等。然而,这构成了我们旨在通过利用自然语言处理(NLP)和机器学习(ML)方面的最新进展来自动化的初步筛选过程。

我们探索了利用深度自然语言处理(NLP)模型来评估错误描述和补丁描述之间语义关联的可行性,以预测自动程序修复中的补丁正确性。我们的主要贡献如下:

我们进行了一项初步验证研究,证明在开发者提交的补丁数据集中,错误描述和补丁描述是相关的。这一假设验证构成了第一个发现,开启了使用错误工件进行补丁正确性研究的新方向。我们将补丁正确性评估问题表述为一个问答问题,并提出了Quatrain(补丁正确性评估的问答),这是一种利用深度NLP模型来分类错误报告与补丁描述相关性的监督学习方法。我们对Quatrain在识别正确补丁以及从9,135个合理补丁(由开发者编写或由APR工具生成)中筛选出错误补丁的有效性进行了广泛评估。我们的评估进一步将Quatrain与最先进的动态方法和静态方法进行了比较,结果表明在AUC、F1、+Recall和-Recall方面,Quatrain达到了相当或更好的性能。我们分析了输入质量对预测性能的影响。特别是,我们展示了软件工程委员会可以从对补丁摘要(又称提交信息生成)方向的扩展研究中受益。

2 技术介绍

概述:我们所基于的直觉是,修补错误的补丁的自然语言描述与描述该特定错误的错误报告在语义上是相关的:错误报告描述了问题(错误),而补丁描述描述了解决问题的方案。错误报告及其相关补丁之间的这种语义关系类似于自然语言处理(NLP)中的问题和答案之间的问答关系。我们的定义如下:

定义3.1(将补丁正确性预测视为问答问题):给定自然语言中的错误报告 brnl,为报告的错误生成的补丁 patchc 以及补丁的自然语言描述 patchnl,预测问答式对 (brnl, patchnl) 是否匹配。即,预测补丁 patchnl 是否与错误报告 brnl(问题)相关(回答)。

为了解决这个问题,我们提出了一种方法,Quatrain。它以一个程序为输入,该程序的错误行为在错误报告中进行了描述,并提供了由APR工具生成的相关补丁,然后输出正确性的预测。图3提供了该方法的概述,包含两个阶段:训练(离线)和预测(在线)。

在训练阶段,给定一批有缺陷的程序,Quatrain首先从程序存储库中自动提取错误NL描述(错误报告);然后,对于与错误相关的每个候选补丁,它通过利用代码更改总结工具生成补丁NL描述。随后,Quatrain需要大量的正(即正确)和负(即不正确)样本来训练一个分类器,该分类器预测错误报告和补丁描述之间的关联性。

在预测阶段,Quatrain通过应用图3中的第一、第二和第四步来预处理一个新的有缺陷程序及其相关的候选补丁。然后,它使用训练好的QA分类器来预测候选补丁是否确实回答了错误报告中的问题。答案相当于对可行补丁的正确性的陈述(是:正确;否:不正确)。

图3:方法概述。

2.1 提取错误报告

我们方法的第一步是获取错误的描述。寻找这样的描述的一个自然选择是利用错误报告。它们在各个项目中数量众多,并提供了程序错误行为的自然语言描述,至少描述了错误的症状。错误报告是通过不同平台提交的,例如,问题跟踪器(如Jira)和GitHub中的问题。为了我们的目的,我们使用脚本自动挖掘我们使用的错误数据集的错误报告。

一个官方的错误报告通常包括三个部分:标题、描述和评论。在我们构建的基准测试中,一些错误报告包含评论,其中发布了正确的解决方案甚至整个补丁。然而,请注意,在我们的实验评估中,我们必须假设错误尚未被修复。因此,为了保持实用性并减少偏见,我们丢弃所有评论,只利用错误报告的标题和描述正文。

2.2 生成补丁描述

我们方法的第二步是总结由APR生成的补丁,以自然语言的方式获取对补丁中应用的更改的语义解释。这里的想法是获得一个补丁的表示,尽可能接近错误报告如何用自然语言描述错误的方式。如果补丁是由开发者编写的(例如,我们训练集中的正样本补丁),其关联的提交消息可以用作补丁的这种自然语言描述的代理。我们使用脚本从开发者存储库(如GitHub)中挖掘提交消息,并收集与我们数据集中的补丁相关联的描述。

然而,请注意,对于APR生成的补丁,显然不会有提交消息可用。因此,我们使用最先进的提交消息生成技术自动生成补丁描述。具体来说,我们考虑了CodeTrans [9],这是一种基于编码器-解码器变换器的模型,已经被开发用于解决多个软件工程任务。Quatrain使用了CodeTrans-TF-Large,这是迄今在提交消息生成任务上获得的最高BLEU分数44.41的最大模型。

在训练期间,我们从以下来源获取补丁描述:(i)由开发者提供的手动编写的修复错误补丁的提交消息,或(ii)使用CodeTrans为APR生成的补丁自动生成描述。

2.3 构建训练样本

根据定义3.1,我们正在处理一个二分类问题。为了训练一个二分类器,需要收集正(即正确)和负(即不正确)样本。因此,Quatrain的第三步是构建一个包含正负训练样本的数据集。

总体而言,一个正(或负)训练(或测试)样本由一个错误报告及其相关的补丁组成。

2.3.1 正样本

我们收集了两种类型的正(正确)训练样本。第一类正确样本是由开发者编写的补丁及其相关的错误报告。第二类正确样本是APR生成的补丁及其相关的错误报告,这些APR补丁在之前的研究中已被手动标记为正确。

2.3.2 负样本

我们需要创建负样本来训练Quatrain识别不正确的补丁。为此,我们构建了两种不正确的样本。

第一种负样本是随机将开发者编写的补丁分配给不相关的错误报告。例如,我们通过将bug-x的补丁与bug-y的错误报告配对来创建一个训练样本。创建这种负样本的基本原理是让模型学习错误报告及其相关补丁描述之间的隐含关系。一个处理完全不相关错误的补丁与被检查的错误几乎没有关系。

第二种负样本是通过选择在之前的研究中被标记为不正确的APR生成的补丁及其相关的错误报告来创建。这些APR生成的补丁本意是解决特定的错误,但手动验证显示它们是不正确的。相应地,为这些不正确补丁生成的补丁描述没有正确回答错误报告,因此可以被视为负样本。

2.4 错误报告和补丁的Embedding

为了有效学习错误报告和补丁描述之间的关系,我们首先需要将文本转换为数值表示。尽管存在各种将文本转换为数值向量的技术,选择合适的嵌入技术至关重要,因为它会影响向量表示文本的精确度。与流行的嵌入模型如Word2Vec相比,Word2Vec对每个单词使用固定表示,无论单词出现的上下文如何,而BERT在表示文本方面具有更多优势:它生成的单词表示会根据周围的单词动态调整。因此,我们采用BERT作为错误报告和补丁标记化文本的初始嵌入模型。所使用的模型是一个预训练的大型模型,具有24层和1024维嵌入,训练于大小写敏感的英语文本上。在将文本表示为向量空间后,我们可以对其进行数值计算,例如计算文本相似度或相关性指标。

2.5 神经QA模型的训练

QA模型广泛应用于自然语言处理(NLP)和软件工程(SE)社区。QA模型需要两个输入:错误报告和补丁描述,以其向量化格式。然后,BiLSTM层接受输入以学习错误报告和补丁描述之间的相关性。

为了根据错误报告更好地区分正确补丁与其他补丁,我们在补丁描述上采用注意力机制,以结合最相关的信息,类似于Tan等人的方法。

2.6 错误报告和补丁对的分类

对于给定的有缺陷程序及其APR生成的补丁,Quatrain首先提取错误描述,生成补丁的文本描述,将文本对进行向量化,然后查询训练好的QA模型,以此来对该对是否相关进行分类。预测概率的值在0(错误)和1(正确)之间。Quatrain根据预测输出的阈值来判断补丁是否正确。

3 实验评估

3.1 实验设置

研究问题:

RQ-1: Quatrain在基于错误和补丁描述关联的补丁正确性识别中的有效性如何?我们在一个包含真实正确和错误补丁的大型数据集上评估Quatrain。

RQ-2: 错误报告和补丁描述的质量在多大程度上影响Quatrain的有效性?我们进行两个独立的实验:第一个实验中,我们将文本的大小(即单词数量)作为质量的代表,并研究在正确和错误预测中质量测量是否存在差异。在第二个实验中,给定原始错误报告和开发者补丁描述对,我们分别用随机的错误报告或工具生成的补丁描述替换,并观察性能测量的变化。

RQ-3: Quatrain在补丁正确性识别方面与最先进的技术相比表现如何?我们提出将我们的方法与文献中提出的用于APR补丁评估的静态和动态方法进行比较。

表1 标记补丁的数据集

我们的目标是在补丁正确性识别中尽可能多地召回正确补丁,同时过滤掉尽可能多的错误补丁。因此,我们遵循Tian等人对其BATS [47]评估提出的召回率定义:

+Recall 测量正确补丁被识别的程度,即从所有正确补丁中识别出的正确补丁的百分比。

-Recall 测量错误补丁被过滤掉的程度,即从所有错误补丁中过滤出的错误补丁的百分比。

Area Under Curve (AUC) and F1. 我们构建了一个基于深度学习的NLP分类器来识别补丁的正确性。因此,我们使用两个最常见的指标,AUC和F1得分(用于识别正确补丁的精度和召回率的调和平均值),来评估我们方法的整体性能。

3.2 RQ1 Quatrain 有效性

实验目标:我们通过调查Quatrain方法的有效性来回答RQ-1,该方法通过相关联的错误和补丁描述来预测补丁的正确性。

实验结果:使用所提供的10组交叉验证,我们在表2中提供了Quatrain预测的总体混淆矩阵,以及Quatrain的平均+Recall(正确补丁的召回率)和-Recall(错误补丁的召回率)。Quatrain在AUC方面表现出较高的值为0.886,显示了QA模型在补丁正确性预测方面的总体有效性。然而,我们注意到F1分数(0.628)相对较低。这个指标在测试数据不平衡时通常会产生较低的值[18]:在我们的设置中,错误补丁集和正确补丁集之间的比例约为5:1。我们确认通过重新平衡测试数据可以获得更好的F1:在每轮比赛中,当比例为1:1(1,591:1,591)时,相同的训练分类器达到了0.793的F1分数。稍后,在我们的实验中,我们通过在相同的实验设置上与最先进的方法进行比较(参见第5.3节)来减轻潜在的不平衡偏差。我们发现+Recall和-Recall对阈值的选择很敏感。当将阈值设置为较低值(例如,0.1)时,我们能够识别出所有正确的补丁(+Recall=100%),但相反地,没有任何错误的补丁可以被过滤掉(-Recall=0%)。同样,在阈值为0.9时,我们可以过滤掉所有的错误补丁,但无法回忆起任何正确的补丁。然而,我们看到当选择了一个合适的阈值时,Quatrain在+Recall和-Recall之间取得了平衡的有希望的结果。例如,在阈值为0.4时,Quatrain可以回忆起92.7%的正确补丁,同时过滤掉61.7%的错误补丁;或者在阈值为0.5时,+Recall为73.9%,-Recall为87.0%。结果表明我们的方法在识别正确和错误的补丁方面是有效的。

3.2 RQ2输入质量对Quatrain的影响

实验目标:Quatrain在生成补丁候选项并应用于有错误的程序时,依赖于特定步骤来提取错误和补丁描述。这些描述的质量可能影响我们方法的性能。我们通过尝试回答三个子问题来调查这种影响:

• RQ-2.1 错误报告和补丁描述的长度在多大程度上影响预测性能?我们假设良好的描述应该有更多不同的词语,并探讨是否可以在更大的补丁/错误报告描述上进行正确的预测。

图6展示了每轮预测中补丁描述长度的分布。我们观察到,总体而言,在大多数组中,正确预测的补丁描述长度大于错误预测的补丁描述长度:当补丁描述长度较大时,模型更有效。曼-惠特尼-Wilcoxon检验(p值:4.1e-16)进一步确认了长度差异在统计上具有显著性。相比之下,对于错误报告的情况,其长度差异未发现具有统计显著性。

• RQ-2.2 基于自然语言处理的QA分类器实际上是否将错误报告和补丁描述相关联起来?我们在测试数据中引入噪声,并评估分类器是否实际上正在查看我们希望用QA检查的相关性。

图7展示了在应用分类器于真实匹配对(即原始对)和应用分类器于补丁与随机错误报告匹配的对(即随机对)时,Quatrain对1,073个正确补丁的预测概率分布。从箱线图可以看出,原始对(白色箱子)的分布最低值约为0.5。这是构造上的正常现象:我们设定0.5作为决定正确性的阈值概率,并且我们的数据集中在预测正确的情况下。在破坏了错误报告和补丁描述对的相关性之后,我们发现尽管补丁是正确的,但Quatrain在某些情况下的预测概率值小于0.5(即这些补丁将被错误分类为不正确)。曼-惠特尼-Wilcoxon检验(p值:4.0e-35)确认了两个分布中位数概率值差异在统计上具有显著性。具体来说,22%(241/1,073)的开发者补丁在被关联到随机错误报告后,不再被Quatrain正确识别为正确。这些结果表明,Quatrain确实在评估错误报告与补丁描述之间的相关性以预测正确性。

• RQ-2.3 生成的补丁描述是否提供与开发者撰写的提交消息相同的学习价值?我们进行实验,其中训练集中的地面真实补丁描述交替在开发者编写的(假定质量较高)和自动生成的(假定质量较低)提交消息之间切换。

实验结果表明,当测试数据的输入使用开发者编写的补丁描述时,如RQ-2.2所示,Quatrain达到了82%的+召回率(1,073/1,301)。然而,当开发者编写的描述被CodeTrans生成的描述替换时,该指标(+召回率)下降了37个百分点至45%。这表明补丁描述的质量对Quatrain的预测性能有很大影响。图8展示了在正确和错误预测中,开发者描述与生成描述之间的Levenshtein距离的箱线图分布。在大多数组中,白色箱子(正确预测)显示了较短的Levenshtein距离值,即更高的相似性。这个结果表明,如果生成的描述具有与开发者描述同等高的质量,Quatrain的预测能力将从中受益。最后,注意到在第5.1节中,我们评估了Quatrain在所有开发者提交消息被生成描述替换的设置下的表现:AUC指标下降了11个百分点至0.774。

转述:伊高磊

0 阅读:1

互联不一般哥

简介:感谢大家的关注