论文:Jinru Hua, Mengshi Zhang, Kaiyuan Wang, and Sarfraz Khurshid. 2018. SketchFix: A Tool for Automated Program Repair Approach using Lazy Candidate Generation. In Proceedings of the 26th ACM Joint European Software Engineering Conference and Symposium on the Foundations of Software Engineering (ESEC/FSE ’18), November 4–9, 2018, Lake Buena Vista, FL, USA. ACM, New York, NY, USA, 4 pages. https://doi.org/10.1145/3236024.3264600

摘要

人工定位和移除故障程序中的漏洞通常是单调乏味且容易出错的。一种常见的自动程序修复方法称为生成和验证(G&V),它迭代地创建并编译候选修复程序,并针对给定的测试运行这些候选修复。由于大量重新编译和重新执行程序,这种方法成本高昂。为了解决这一局限,最近的工作介绍了SketchFix,它紧密集成了生成和验证阶段,并利用运行时行为来大幅度削减大量的修复候选项。这篇工具论文描述了我们的SketchFix的Java实现,我们已经将他发布到 Github 作为一个开源库。我们使用Defects4J基准进行实验的评估,评估表明:与其他方法相比,SketchFix可以显着减少重新编译和重新执行的次数,并且可以很好地修复AST节点级别粒度的表达式操作。演示视频链接:https://youtu.be/AO-YCH8vGzQ。

1. 介绍

传统的G&V技术需要重新编译和重新执行许多候选程序,直到候选程序通过所有测试,此方法时间成本太高。我们最近的工作介绍了SketchFix[1],它增强了传统的G&V方法。SketchFix的新颖之处在于它通过紧密集成生成和验证阶段以及使用延迟候选生成来减少编译和执行开销。直观地说,SketchFix利用精确的运行时信息来根据需要创建候选项。与产生数千个具体候选项的传统G&V方法不同,SketchFix不会为测试执行未达到的程序部分创建任何具体的候选项。这种延迟的候选生成方法利用运行时行为来大幅削减大部分搜索空间。

另一种常见的修复方法是基于约束求解,它基于由错误程序和测试创建的约束使用现成的求解器来合成修复,这种技术通常会导致布尔或整数类型。

本文描述了SketchFix的Java实现,它在AST节点级别执行细粒度修复。给定一个有故障的Java程序和一个测试套件作为输入,SketchFix首先使用基于频谱的故障定位技术Ochiai[2]来根据可疑值对可疑语句进行排名。对于每个可疑语句,SketchFix在此位置根据AST节点级别转换模式引入“孔”[3]。SketchFix提供API以使用Java语法指定“孔”,可以直接针对测试套件编译和执行。SketchFix使用一个名为EdSketch[4]的草图引擎来填充带有回溯搜索的孔。当测试因运行期间异常或断言失败而失败时,执行的候选程序部分将确定未来候选项的生成。SketchFix在遇到异常或测试失败时回溯,并选择下一个候选项,直到找到满足所有测试的修复候选项。

SketchFix以精细的粒度定义了转换模式,并优先考虑对原始程序引入较小扰动模式。最近的研究 [5,6]提出了见解:在语义上更接近原始程序的补丁更可能是正确的。我们的排名策略与此见解一致,旨在缓解过拟合问题[6]。SketchFix可从https://github.com/sketchFix网站中获得。

2. 例子

我们通过Apache Math项目的缺陷来描述SketchFix。

图1:SketchFix的输入和输出

图1显示了SketchFix的输入和输出,图里包含一个人工编写的补丁以及 SketchFix生成的可以实现正确修复的草图。SketchFix使用Ochiai故障定位方法来识别可疑语句列表,对每个可疑语句应用AST节点级别转换来生成草图,对于每个草图,SketchFix将原始源文件替换为草图并编译,针对给定的测试执行草图,该过程是自动化的。在图1中,SketchFix基于两个AST节点级别转换模式将故障程序转换为草图:引入新的if条件的条件模式和插入return语句的返回模式。与其他修复技术不同,SketchFix会生成一个具体候选列表并迭代编译它们,SketchFix使用带孔的草图来编码if-return修复模板的所有候选项。因此,草图只编译一次,但它代表了数百个具体的候选项。SketchFix针对编译的草图执行给定的测试套件,当测试执行到达SketchFix.COND(...)孔时,不考虑数百个具体候选项,如v2D != null和line1 != line2,SketchFix只考虑两个布尔值(true和false)并选择true或者false填充条件孔。如果SketchFix为if条件选择false,则它不会初始化返回表达式中的任何候选项,因为测试执行没有到达if条件体内的孔SketchFix.EXP(...)。因此,它们必须编译执行未达到的if条件主体的所有候选项的测试。在此示例中,选择false会导致测试失败。SketchFix回溯并选择下一个候选项,将if条件设置为true。当测试执行到达SketchFix.EXP(...)孔时,SketchFix会延迟地生成此孔的候选项并选择一个候选项来填充表达式孔。在此示例中,SketchFix选择可见变量v2D以填充孔,此候选项通过所有测试。

3. 实现

图2:SketchFix的工作流程

图2显示了SketchFix的工作流程。鉴于程序错误和测试套件,SketchFix首先根据Ochiai故障定位技术识别可疑值排序列表。对于每个可疑位置,SketchFix应用预定义的AST节点级别转换模式来创建草图。这些草图直接针对测试套件进行编译和执行。一旦执行触发测试失败或运行时异常,SketchFix就会回溯,选择下一个填充漏孔的候选项,并针对测试执行新的候选项。

3.1 AST节点级别转换

SketchFix通过将错误的程序转换为精细粒度的草图,将程序修复系统地简化为程序合成。SketchFix提供的API主要采用三个参数:包含所有可见变量和默认值(null或0)的对象列表,用于区分相同类型的不同孔的孔ID,以及生成的候选的目标类型。例如,图1中的表达式孔被指定为SketchFix.EXP(new Object[]{v2D,line1,...,null},0,Vector2D.class)。孔的目标类型派生自基于Java语法的方法的返回类型。如果目标类型的孔未知,SketchFix将获取前两个参数,并将目标型视为另一个要合成的孔。我们使用JavaParser自动将错误程序转换为草图。

转换模式:定义了六个AST节点级别转换模式,将可疑位置作为输入并生成带孔的草图。

表达式转换器(EXP):如果错误语句包含变量、常量值或字段引用的AST节点,则该节点将转换为一个返回对象的孔SketchFix.EXP(...)。

操作符转换器(AOP):如果故障行包含带算术运算符的二进制表达式,则此二进制表达式将转换为一个孔SketchFix.AOP(...)。

重载转换器(PAR):如果错误语句包含具有重载方法的方法调用,则SketchFix会映射参数类型并生成表达式孔以表示不同类型的参数。

条件转换器(COND):此模式将新子句附加到故障条件,例如if(cond && SketchFix.COND(...))。新子句表示为左侧和右侧表达式与关系运算符的组合。

If条件变换器(IF):SketchFix在带有条件孔的故障语句之前引入if条件。

Return语句转换器(RTN):SketchFix在错误语句之前插入一个return语句。

排序策略:草图中引入更多的孔会使合成成本增加。我们将转换模式的成本定义为模式引入的原子孔(表达式孔和操作符孔)的数量。我们以较低的合成成本确定模式的优先级。修复候选项在语义上更接近原始程序,开发人员相对容易理解。使用更接近孔的变量是相对容易的,根据它们与孔位置的接近程度(即孔与变量声明之间的语句数)对变量进行排序。对于目标类型未知的条件孔,根据变量声明的类型按照它们与孔位置的接近程度的降序来探索目标类型。例如,SketchFix为图1中的条件孔优先考虑目标类型Vector2D,因为最接近的定义变量(v2D)属于这种类型。

3.2 延迟候选项

当测试执行首次到达一个孔时,SketchFix会根据给定的可见变量和默认值初始化孔的候选项。为每个候选项分配一个唯一标识符,该标识符是列表中的索引。每个孔的候选标识符初始化为-1,表示该孔尚未初始化。当执行首先到达标识符为-1的孔时,SketchFix选择从0开始的标识符来表示用于填充孔的候选项。在图1中,标识符0映射到条件孔的值false。继续执行此选择,直到执行遇到运行时异常或测试失败,导致带有候选标识符增量的回溯(如下图3中incrementCounter()),动态选择下一个候选。在图1中,标识符1映射到条件孔的值true。如果存在多个孔,方法incrementCounter将一次增加一个孔标识符。当找到通过所有测试的修复或候选程序的空间耗尽时,即所有候选标识符已达到其最大值——候选列表的大小时,该过程终止。在这种情况下,方法incrementCounter返回false,程序退出while循环。

图3:SketchFix使用的测试驱动程序

4. 实验

我们在Defects4J基准测试上评估SketchFix,它由来自5个开源Java项目的357个缺陷组成。

为了识别缺陷的可疑语句,我们使用ASM字节码分析框架来捕获失败和传递测试执行的覆盖范围。SketchFix使用现有的基于频谱的故障定位技术Ochiai对可疑语句进行排名。现有的实证研究表明,Ochiai可以有效地定位面向对象程序中的缺陷。它已应用于在比较中使用的所有四种修复技术。如果多个语句具有相同的可疑性分数,我们会随机排序。

图4:SketchFix和其他修复方法生成的补丁的人工评估结果。

(SF代表SketchFix,A代表Astor,N代表Nopol,C代表ACS,H代表HDRepair。✓表示正确的修复,?表示合理的修复,×表示不生成修复)

我们首先将SketchFix的修复效果与其他修复技术Astor、Nopol、ACS和HDRepair进行比较,这些修复技术已针对缺陷4J基准进行了评估。由于空间限制,图4仅通过人工检查显示部分修复结果,其中包含SketchFix修复的缺陷。我们检查三个条件以确定修复是否在语义上等同于人工补丁:1)维修在同一地点;2)相同类型的修复,即表达式操作或操作符操作;3)候选孔的运行时的值与用于修复缺陷的表达式的值相同。例如在图1中,我们将return v2D视为在语义上等效于在null指针检查中返回null。SketchFix生成19个正确的修复和7个合理的修复,合理的修复指的是通过了所有测试但在人工检查中失败。

图5:SketchFix和Nopol生成的补丁

与其他修复技术相比,SketchFix在处理表达式和变量类型方面特别有效。例如,图5显示了一个人工编写的补丁,它使用不同类型的参数(int和double)。SketchFix使用重载转换模式正确修复了此错误。相比之下,基于约束求解的修复技术通常仅仅修改具有布尔或整数类型的赋值的条件或右侧的表达式。这些技术很难修复需要操作表达式和变量类型的缺陷。如图5所示,基于约束的工具Nopol通过插入新的if语句生成合理的修复。此示例还说明与Nopol相比,SketchFix对原始程序引入了较小的AST节点级别更改,并且此修复更可能被用户接受。

对于延迟的候选生成,每个草图将被编译一次,这可能代表数千个候选项。当Sketch-Fix找到第一次修复时,它会编译1.6%。即使SketchFix彻底搜索修复候选项的整个空间,它也只编译所有候选项的7%(而没有延迟的候选生成,100%的候选项都必须编译),这些候选项必须在没有延迟候选生成的情况下编译。实验表明,当SketchFix找到第一个通过所有测试的补丁时,它只执行3%的候选项。平均而言,SketchFix花费9分钟来定位故障并生成草图,并且花费23分钟来生成满足所有测试断言的第一次修复。

结论

本文描述了一种具有延迟候选生成的自动程序修复工具SketchFix。SketchFix的主要见解是利用运行时信息来大幅削减候选项的空间,它将错误的程序转换为细粒度的带孔草图。SketchFix可以应用于存在库的各种代码结构的各种程序中。通过生成和验证阶段的紧密集成,SketchFix基于我们的实验大幅度削减了大量的候选修复。我们的结果还表明,SketchFix在AST节点级别使用非原始类型表达式操作修复缺陷时效果很好。

参考文献

[1] Jinru Hua, Mengshi Zhang, Kaiyuan Wang, and Sarfraz Khurshid. 2018. Towards Practical Program Repair with On-Demand Candidate Generation. In ICSE.

[2] Rui Abreu, Peter Zoeteweij, and Arjan J. C. van Gemund. [n. d.]. On the accuracy of spectrum-based fault localization. In TAIC PART.

[3] Armando Solar-Lezama. 2013. Program sketching. STTT (2013).

[4] Jinru Hua and Sarfraz Khurshid. 2017. EdSketch: execution-driven sketching for Java. In SPIN.

[5] Xuan-Bach D. Le, Duc-Hiep Chu, David Lo, Claire Le Goues, and Willem Visser. 2017. S3: syntax- and semantic-guided repair synthesis via programming by examples. In FSE.

[6] Edward K. Smith, Earl T. Barr, Claire Le Goues, and Yuriy Brun. 2015. Is the cure worse than the disease? Overfitting in automated program repair. In FSE.

致谢

此文由南京大学软件学院2019级硕士郭超翻译转述。

c2665 “initgraph”: 2 个重载中没有一个可以转换所有参数类型_一个使用延迟候选项生成的用于自动化程序修复方法的工具...相关推荐

  1. MFC:2个重载中没有一个可以转换所有参数类型

    MFC:2个重载中没有一个可以转换所有参数类型 用VS2008,在使用AfxMessageBox函数的时候出现以上错误,代码如下: AfxMessageBox("Here is the in ...

  2. c2665 “initgraph”: 2 个重载中没有一个可以转换所有参数类型_Python 命令行之旅:深入 click 之参数篇...

    作者:HelloGitHub-Prodesire 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 一.前言 在上一篇文章中,我们初步掌握了 click 的简单用法,并了解到它 ...

  3. 【Problem solved】 error C2665: “loadimage”: 2 个重载中没有一个可以转换所有参数类型...

    选择"项目"菜单->项目属性->配置属性->常规->字符集,改为"未设置"即可. 转载于:https://www.cnblogs.com ...

  4. 一个进程仅存在给定类型的一个挂起信号,同一进程同样类型的其他信号不被排队

    任何时候,一个进程仅存在给定类型的一个挂起信号,同一进程同样类型的其他信号不被排队,只被简单的丢弃:理解--即使连续发送SIGQUIT信号,进程也只有处理一个SIGQUIT信号. Please rea ...

  5. 两种参数类型_深入理解Java中方法的参数传递机制

    形参和实参 我们知道,在Java中定义方法时,是可以定义参数的,比如: public static void main(String[] args){ } 这里的args就是一个字符串数组类型的参数. ...

  6. html 中一个格子拆分成两个_一个效果惊人的数字游戏

    安爸曾多次讲过数学推理能力对孩子成长的重要性,听到有位家长说自己用扔骰子的方法教孩子数学等式.步骤大致是扔骰子时,如果骰子是3,就在棋盘上从0出发走3步,并且写出0+3=3的加法等式.扔到负数就后退, ...

  7. C语言中把小写字符串转换成大写用函数,一个容易的将小写字符串转换成大写的函数...

    一个简单的将小写字符串转换成大写的函数 我用的是VC++6.0,恳请大家帮忙看看到底哪里出错了. #include void uppers(char *Dest,char *Sour) { while ...

  8. mysql中如何把字符串转换成日期类型

    select date_format('2013-03-09','%Y-%m-%d'); select date_format('2013-03-09','%y-%m-%d');select STR_ ...

  9. android checkbox监听另一个checkbox选中和不选中_一个真正0基础小白学习前端开发的心路历程...

    摘要:真正的0基础小白学习前端开发的心路历程. 距离第一阶段的结束敲响了末尾的声音,抱着初心从开始8号的学习到第一阶段的结束这期间要应付期末考试应付自己的各种事情学习时间总是挤出来的这次学习让我受益匪 ...

最新文章

  1. 如何在Eclipse中添加新建包,java文件,工程工具栏按钮
  2. 【转】Linux面试题集锦
  3. oracle 提示存在lob,案例:Oracle数据库临时文件特别大 commit后lob字段使用临时表空...
  4. 整合apache和JBoss,配置虚拟主机
  5. 图像处理-RGB彩色图像均衡化处理
  6. 计算机win10分区软件,分区工具哪个好? win10系统分区助手值得拥有
  7. 小米android怎么刷机教程,安卓刷机教程_小米刷机教程_手机刷机教程-IT资讯(PC6.com)...
  8. CSR8675烧录工具-全系列CSR8675/86xx一拖多量产工具csr烧录软件(支持FLASH版本和ROM版本)
  9. 强网杯 2018 core ROP做法
  10. oracle的sql硬解析和软解析,[ORACLE]oracle SQL执行过程 软解析(soft prase)硬解析(hard prase)以及 Soft Soft Parse...
  11. makefile中常用函数
  12. mysql计算1000天后的日期_Mysql中常用的日期函数
  13. 《那些年啊,那些事——一个程序员的奋斗史》——24
  14. yolo和以往算法的区别/yolo为什么叫yolo
  15. 实时控制软件开发第二次作业总结
  16. oracle 的 rank()函数
  17. 智能硬件产品经理需要哪些技术基础?
  18. 吊死人小游戏 2.0版本
  19. 使用Django1.7开发熙鱿记官网
  20. 正式迁入深圳户籍-用爱发电

热门文章

  1. 敲黑板划重点!「PV,UV流量预测算法大赛」明日结果提交最后1天!
  2. 你了解京东云区块链吗?点开有详情!
  3. 出于安全考虑,千万不要绕开 CORS!
  4. 知乎披露会员业务未来布局,融合社区内容深耕垂直领域
  5. 开源正在蚕食 500 亿美元的数据库行业!
  6. 开源的全面胜利背后,那些被遗忘的人性问题
  7. 30 秒?!Chrome 插件带你速成编程学习 | 程序员硬核评测
  8. 遇上浏览器跨域问题怎么办?
  9. 腾讯用微信、QQ 把微视送上了 App Store 第一 | 畅言
  10. 程序员渴望的“无代码世界”要来了!