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

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


                 回率的有效手段;
             (6)  依赖未通过测试.目前,软件缺陷自动修复方法主要集中于基于测试的修复方法,即,根据程序中未通
                 过的测试定位程序中的错误.然而在真实的开发场景中,未通过的测试并不总是存在的.在缺陷修复
                 领域中常用的验证数据集 Defects4J(v1.2.0)中,96%(=381/395)的程序缺陷在被修复之前无对应的未
                 通过测试    [48] .该问题会严重影响目前的自动修复技术在真实工业开发场景中的实用性.最新的一些自
                 动修复方法尝试分析缺陷报告           [53] 、应用软件静态分析    [57,59] 等技术定位程序中的缺陷或验证补丁正确
                 性,从而不依赖于未通过测试.但其修复效果相比基于测试的修复技术依然存在较大的差距.而且该
                 类方法主要针对一些特定类型的缺陷,如空指针错误                   [59] 、内存溢出 [57] 等.因此,非基于测试的自动修复
                 技术在未来的研究中依然需要更多的探索;
             (7)  不完整规约.测试为缺陷修复工具提供规约,测试不完备是导致似真补丁的一个重要原因.已有研究
                 的实验   [105] 表明,测试的覆盖率与补丁的质量成正相关.因此,提升测试的覆盖率是提升补丁质量和修
                 复准确率的重要手段.最新的一些研究             [22,23,106] 通过生成新的测试对候选补丁进行过滤,可以在一定程
                 度上提升补丁质量.然而,由于测试生成依赖测试断言(oracle),导致自动生成的测试对补丁过滤有限.
                 挖掘程序的其他特征对程序规约进行补全,是提升补丁质量的有效途径.已有工作尝试使用类似特征
                 指导补丁生成(例如 ACS),但目前挖掘到的程序规约信息依然比较有限.可以考虑结合更多的数据源,
                 比如项目的演化历史和缺陷报告等,对程序规约进行补全;
             (8)  语义理解.程序自动修复技术实际上涉及程序理解的过程.然而,自动修复方法通过启发式搜索或代
                 码复用的方式虽然在一定程度上可以修复程序中的部分代码,但实际上针对其修复结果并不能给出
                 合理的解释,即并没有真正理解程序的语义.因此,补丁的生成过程在一定程度上具有随机性和盲目
                 性.这也是导致对于开发者非常容易修复的一些缺陷,自动修复工具却难以修复的一个重要原因.但
                 程序理解本身就是一件具有重大挑战的研究.随着近年来人工智能的发展,使用智能化的算法(例如
                 深度神经网络)实现程序语义的部分理解,是可探索的方向.
             自动修复技术的上述挑战是目前研究被广泛关注的重点问题,也是在未来的研究中亟待解决的难点.部分
         挑战在之前的综述论文中          [1,3] 也有被提出过,比如不完整规约导致的补丁过拟合等,此处结合最新研究对其进一
         步归纳和总结.除此之外,已有综述论文中同时提出了自动修复技术所面临的关于实用性的重要挑战,接下来本
         文对其进一步总结.
             •   修复效率问题
             目前,研究比较广泛的基于测试的自动修复方法大部分遵循“生成-验证”的模型                           [25−28,93] ,即首先生成修复补
         丁,然后通过运行测试验证补丁的正确性.该模型由于依赖测试的反复执行,会导致修复效率比较低,一般需要
         几十分钟到几个小时去修复一个程序缺陷,使得已有的自动修复方法只能离线使用,不能为开发者提供实时的
         反馈.已有研究从不同角度提升修复效率,如早期的自动修复方法 AE                       [107] ,通过分析补丁的等价性来避免重复补
         丁的验证过程.此外,Prophet     [24] 通过补丁排序方法使得正确的修复补丁尽可能得到提前验证,在一定程度上可
         以提升修复的效率.但上述方法依然不能避免验证大量候选补丁所带来的巨大时间开销.最新的研究中,通过补
         丁隔离   [44] 和字节码修复  [31] 避免了补丁验证过程中的代码反复编译开销,大幅度提升了修复的效率.然而,尽管
         如此,自动修复方法依然难以满足在线与开发者交互的实效要求.因此,修复效率依然是目前自动修复方法所面
         临的实用性挑战之一.
             •   代码可维护性问题
             由于自动生成的补丁一般通过组合复用已有的代码片段产生,在缺少领域知识进行有效指导的情况下,补
         丁代码具有一定的随机性,比如产生类似“if (a!=a)”和“if (1<3)”等死代码(dead code),甚至会产生重复代码                   [29] 以
         及晦涩难懂的补丁代码         [69] 等,严重影响代码的可读性和可维护性.最新的研究通过启发式方法或统计分析尝试
         从已有代码或补丁数据中学习类似的领域知识,在一定程度上降低了补丁的随机性,但补丁质量依然难以保证.
         目前,依然缺少关于该问题的针对性研究.
   52   53   54   55   56   57   58   59   60   61   62