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

姜佳君  等:软件缺陷自动修复技术综述                                                              2671


         STMT”应该是“METH_DECL”的子节点.因此,根据该规则,CapGen 不能在循环语句“FOR_STMT”中插入
         “EXPR_STMT”.类似的代码修改操作限定了特定修改操作的应用范围.除此之外,CapGen 在复用项目中已有代
         码生成补丁时,会统计不同代码表达式在项目中出现的频繁程度并进行排序,被频繁使用的表达式具有更高的
         优先级.上述的补丁空间约束方法和代码复用策略有效地提升了补丁的质量.在 Defects4J 数据集上的实验表明,
         该方法可以达到 84%的补丁准确率.但由于其对补丁空间的约束,导致其修复的数量并不多.
             HistoricalFix 和 CapGen 方法应用历史修改为补丁搜索提供指导.2019 年,Kim 等人           [47] 提出直接应用历史中
         人工修复的模板,并开发了自动修复工具 ConFix.该工具从人工修复中直接提取代码修改操作.ConFix 在代码
         的抽象语法树(abstract syntax  tree)上,根据修改代码的位置提取相关的上下文信息作为应用对应人工修复的条
         件,即仅当出错代码正确匹配上下文才可以应用对应的代码修改.ConFix 根据语法树的结构提取语法树中被修
         改节点的相邻节点作为上下文,例如父节点、左右邻节点等.实验结果表明,使用上下文信息平均可以减少 48%
         的不必要代码修改.
             (3)  利用相似代码
             上述技术主要针对补丁的搜索策略和代码的修改进行优化,还有一部分最新研究关注于优化补丁生成过
         程中所使用的代码元素.上述介绍的方法在复用项目中已有的代码时,仅考虑代码出现的频繁程度(例如
         CapGen),甚至完全不考虑代码的特征,并且均没有考虑缺陷代码与复用代码之间的联系.针对于此,2016 年,Ji 等
         人 [48] 提出通过复用项目中与缺陷位置相似的代码片段生成补丁,并实现了缺陷修复工具 SCRepair.作者认为,与
         缺陷代码过于相似的代码可能存在同样的错误.因此,SCRepair 在复用相似代码作为修复参考时考虑了代码之
         间需要具有差异性.SCRepair 通过对比缺陷代码与参考代码之间的语法树结构的一致性衡量代码相似性,使用
         ChangeDistiller [49] 提取缺陷代码到参考代码的修改操作衡量代码之前的差异性.根据预设的相似性和差异性阈
         值对复用的参考代码进行过滤.SCRepair 与 RSRepair 相似,差别在于 SCRepair 在复用代码时考虑上述过滤条
         件,而 RSRepair 采用无过滤的随机搜索.
             2017 年,Wang 等人 [50] 同样基于复用相似代码的基本思想,提出了修复工具 CRSearcher.与 SCRepair 不同的
         是,CRSearcher 将代码的搜索范围扩展到了其他的项目,应用基于标识(token-based)的代码相似度衡量方法,并
         且不要求相似代码与缺陷代码一定具有差异性.CRSearcher 并不算一个完整的自动修复工具,它不包含补丁验
         证模块,而是针对 FindBugs 检测出的缺陷为开发者推荐修复,需要人工确认补丁的正确性.
             与上述方法类似,Xin 等人      [51] 在 2017 年提出的修复方法 ssFix 同样从代码库中搜索与缺陷代码相似的代码
         作为修复补丁的原材料.ssFix 采用阿帕奇公司(Apache)的 Lucene 作为代码搜索引擎.在生成补丁阶段,ssFix 并
         不是直接复用相似代码,而是通过 ChangeDistiller 提取缺陷代码与相似代码之间的差异,根据其中的不同点逐
         一应用修改操作.相比上述复用技术,ssFix 的代码复用粒度更细,有效地提升了其补丁生成能力.在 Defects4J 数
         据集上的实验表明,ssFix 可以正确修复 20 个缺陷.但是由于其细粒度的代码修改、补丁空间增大导致补丁的准
         确率比较低,产生了两倍数量的似真补丁.
             Jiang 等人 [29] 认为,同一个项目中的代码具有更好的参考价值.同一个项目中的代码通常由同一个开发者或
         同一开发团队所编写,对于相似功能的代码模块,代码风格(例如程序结构和变量名等)具有较高的相似性.基于
         该思想,在 2018 年,他们提出了自动修复工具 SimFix,通过代码结构特征以及代码语义特征(变量和函数命名)搜
         索项目中的相似代码.在应用相似代码阶段,SimFix 同样采用基于差异的代码修改策略,即通过对比缺陷代码与
         相似代码之间的差异提取细粒度的代码修改操作.在复用代码阶段,会替换相似代码中的变量使其在缺陷代码
         位置语法正确.与 ssFix 不同,SimFix 所提取出的代码修改操作可以进行组合应用,并且同时使用历史修复中的
         常用修改操作对候选补丁进行过滤优化.相似代码和历史修改对 SimFix 的补丁空间提供了很好的约束,使其在
         最终的实验验证中不仅正确修复了更多数量的缺陷,其修复的准确率相比 ssFix 也提升了将近一倍.
             基于类似的思想,2019 年,Hu 等人       [52] 提出了根据正确的代码为学生提交的作业代码推荐修复补丁,并实现
         了修复工具 Refactory.该方法首先将学生提交的正确代码作为代码库,通过预定义变换规则对其进行重构使代
         码结构一致.当学生提交的代码不能通过测试验证时,Refactory 通过将其与代码库中的正确代码进行匹配定位
   42   43   44   45   46   47   48   49   50   51   52