Page 54 - 《软件学报》2021年第9期
P. 54

2678                                 Journal of Software  软件学报 Vol.32, No.9,  September 2021

         具 AVATAR 从静态分析工具报告的缺陷及其对应的修复中学习修复补丁模板,用于生成修复补丁.在 Defects4J
         数据集上的验证表明,该方法可以修复之前方法不能修复的缺陷.
             上述介绍的方法主要依赖于从重复的代码修改中提取可复用补丁模板.而研究表明                              [92] ,实际程序修复中只
         有不到 20%的缺陷存在重复,大部分类型缺陷无法通过聚类提取补丁模板.针对此,2019 年,Jiang 等人                          [93] 提出了
         基于单个历史修复的补丁模板提取技术 GenPat.该技术将代码映射成代码图表示形式,通过分析海量的开源代
         码,为补丁模板的抽象提供指导.具体讲,GenPat 所使用的代码图表示模型中,每个节点包含不同的属性信息,通
         过分析对应属性在代码库中出现的频繁程度,决定其通用性.频繁出现的代码属性具有较强的通用性,在模板抽
         象时被保留,否则被抽象掉.该技术通过将代码属性的抽象过程与代码修改分离,克服了对重复修改的依赖,因
         此可以依据单个修改提取补丁模板.该方法在 Defects4J 数据集上验证有效性,结果表明:GenPat 可以从单个历
         史修复中学习通用的补丁模板,用于修复真实缺陷.但其依然面临补丁的准确率低的难题.
             (3)  端到端补丁生成模型
                            [8]
             2017 年,Gupta 等人 使用序列到序列(sequence-to-sequence)神经网络(neural network)模型自动修复 C 语言
         中的编译错误,并基于此实现了自动修复工具 DeepFix.相比已有的自动修复技术,DeepFix 不依赖外部的缺陷定
         位过程,通过神经网络直接预测程序中的缺陷代码并产生修复补丁推荐.具体讲,DeepFix 采用了一个多层的
         (multi-layered)编解码(encoder-decoder)模型,其编码器和解码器均为基于 GRU 的循环神经网络(RNN)模型.此
         外,DeepFix 在模型的解码器端结合了注意力机制(attention mechanism)来提升预测的准确性.在编码程序阶段,
         DeepFix 将程序转换为符号序列(token sequence)“(l 1 ,s 1 ),…,(l k ,s k ),〈eos〉”作为网络输入,其中,(l i ,s i )表示位置 l i 的字
         符编码是 s i ,而〈eos〉代表输入结束.网络预测输出是“ (, )ls′ ”,表示用编码为 s′ 的符号替换位置 l i 的原有符号.为了
                                                                    i
                                                     i
                                                   i
         使得预测得到的结果可以还原成源代码,模型中只抽象掉了字符串常量和整数常量,分别用 STR 和 NUM 替代.
         DeepFix 依赖编译器验证其修复之后的程序是否编译正确.由于其每次预测的输出仅修复单处错误,对于多处
         位置缺陷,DeepFix 采用迭代式修复策略.最后,实验针对常见的 4 种简单编译错误进行修复,例如缺少分隔符、
         括号错误等.实验结果表明:DeepFix 可以正确定位 78.7%的错误代码位置,正确修复 27.0%的缺陷,且修复时间
         仅需要几十毫秒.该方法模型简单,针对简单缺陷比较有效,对于复杂的缺陷效果如何仍需进一步验证.
             2018 年,Bhatia 等人 [94] 针对学生作业 Python 程序提出了自动修复技术.与 DeepFix 不同的是,该工作不仅修
         复程序的语法错误,同时修复程序的语义错误.其具体方法是:首先,使用神经网络模型修复缺陷代码的语法错
         误得到语法正确程序;然后,借助基于语义约束的程序修复技术,使程序满足语义规约.在语法修复阶段,作者使
         用了 RNN 模型,其输入是语法错误程序的符号序列,输出为修改之后的符号序列,即预测输出为程序而非修改.
         在语义修复阶段,作者通过定义代码重写规则替换程序中的部分变量或者符号,然后将程序的语义转换成逻辑
         约束,通过参考正确代码的语义,使用约束求解器求解代码可能的修复.该方法针对学生作业进行修复,存在大
         量重复的相同功能代码,且程序功能相对简单.实验结果表明,该方法平均可以修复 59.8%的语法错误和 23.8%
         的语义错误.
             2019 年,Vasic 等人 [10] 提出使用联合预测(joint prediction)模型修复程序中的变量使用错误,即应该使用其他
         变量替换程序中的某些变量使用.论文的基本思想是,代码中出错的变量通常应该使用上下文中存在的某个变
         量进行替换.因此,作者提出使用多头指针网络模型(multi-head pointer network)对程序代码是否存在缺陷、缺陷
         的位置以及对应的修复进行联合预测.为此,该方法首先使用 LSTM(long-short term memory)模型对程序进行编
         码,模型的输出作为指针模型的输入.在该方法中,指针模型包含两个指针,其中一个指针指向错误使用的变量 p
         的位置,另一个指针指向期望的正确变量 q 的位置.其对应的修复即使用变量 q 替换变量 p.特殊地,当程序中不
         存在变量错误使用缺陷时,模型的第一个指针将指向一个预定义的特殊位置.当给定一个数据集,首先对程序中
         的所有出错位置以及待替换的变量进行标记.在模型训练阶段,分别根据出错位置预测正确数以及修复变量预
         测正确数建立损失函数(loss function),最后的联合预测则取两者损失函数的求和作为最终的优化目标.最终实
         验在开源网站上的 15 万条 Python 源代码上进行测试,测试结果表明:基于上述预测模型,出错位置预测准确率
         为 71.0%,同时,修复的预测准确率为 65.7%.相比之前介绍的基于神经网络模型的修复技术,本方法被应用到大
   49   50   51   52   53   54   55   56   57   58   59