聚合国内IT技术精华文章,分享IT技术精华,帮助IT从业人士成长

基于编译器自身覆盖的编译器测试技术研究

2021-07-19 16:01 浏览: 3397144 次 我要评论(0 条) 字号:

编译器测试是保证编译器质量的重要手段,现有的编译器测试技术,在测试的过程中都忽略了一个很重要的影响编译器测试效率的因素,那就是执行时间过长的测试程序占用了大量的测试资源,这里将执行时间过长的测试程序称为超时程序。超时程序的执行时间是正常测试程序执行时间的成百上千倍,假设超时程序触发缺陷的概率和正常测试程序触发缺陷的概率相同,给定有限的测试资源,避免执行超时程序会大大提高编译器测试的效率,发现更多的编译器缺陷。同时,在大量的测试程序中,能够触发编译器缺陷的测试程序仅占少数,避免执行无法触发缺陷的测试程序也有利于提高编译器的测试效率,发现更多的编译器缺陷。

背景与问题
编译器测试技术通过生成大量的测试用例来对编译器进行自动地测试,实际上,在编译器的测试过程中,往往需要花费大量的测试时间,通过运行大量的测试程序,才能发现相对较少的编译器缺陷。针对这一问题,现有的解决方法有两种,一种是测试程序优先级排序,其思想主要是优化测试程序的执行顺序,以便尽早地执行那些更有可能触发编译器缺陷的程序,另一种是测试套件约简,通过去除测试套件中的冗余测试程序,从而提高编译器的测试效率。然而,以上方法都忽略了一个很重要的影响编译器测试效率的因素,那就是执行时间过长的测试程序,在编译器测试的过程中,执行这类测试程序会占用大量的测试资源。
为了解决这一问题,我们提出一种基于编译器自身覆盖的测试程序选择方案(CoSS),在测试程序的编译阶段,利用机器学习的方法,结合编译器的源代码覆盖信息,预测测试程序是否执行超时以及是否触发编译器缺陷,根据预测结果,避免超时程序的执行,选择合适的测试程序对编译器进行测试,从而达到提高编译器测试效率的目的。

该成果已在实验室github组织下开源,请访问https://github.com/CGCL-codes/SCVDT/tree/main/CompilerTools获取相关内容。


设计与实现
如图1所示,CoSS方法主要有三个阶段,1)学习阶段,2)测试程序选择阶段,3)测试阶段。

图1  CoSS总体流程

在学习阶段,使用GCC作为待测编译器,每当GCC编译完一个测试程序,测试程序中不同的结构和语义特性可能会引起编译器不同的编译行为,编译器自身的覆盖信息也不尽相同,编译器自身覆盖率信息能在一定程度上反映出测试程序的语言特性、结构特性以及操作特性,这些特性与程序的执行密切相关。
在测试程序编译阶段,通过Gcov工具获取编译器源代码的覆盖率信息,经过特征提取,得到每个测试程序对应的编译器源代码特征向量,作为模型输入的训练集。测试程序完成编译后,对于每一个测试程序,记录其对应的可执行文件执行时间。如果执行时间大于指定阈值Ψ,将其归为超时程序,得到超时测试程序标签。
对于触发编译器缺陷的测试程序,以下简称缺陷程序,我们使用差分优化项(DOL)测试的结果作为缺陷程序的度量,如果测试的结果不一致,则认为该测试程序是缺陷程序。收集每一个测试程序的DOL测试结果,作为缺陷程序的训练标签。分别结合缺陷程序标签和超时程序标签,对训练集中的覆盖率信息向量做特征选择,训练缺陷预测模型和超时预测模型。
在测试程序选择阶段,对新的测试代码,使用缺陷预测模型预测其是否为缺陷程序,使用超时预测模型预测其是否为超时程序,在这两类预测信息的基础上,提出以下四种策略对测试程序进行选择:
  • 超时程序预测(Timeout Predict,TP),按照Csmith生成测试程序的顺序预测每一个测试程序是否超时,丢弃超时的测试程序,选择没有超时的测试程序执行。


  • 缺陷程序预测(Bug Predict,BP),按照Csmith生成测试程序的顺序预测每一个测试程序是否触发缺陷,丢弃未触发缺陷的测试程序,选择触发缺陷的测试程序执行。


  • 超时与缺陷程序预测(Timeout and Bug Predict,TAB),按照Csmith生成测试程序的顺序,首先预测程序是否触发缺陷,然后预测程序是否超时,仅留下既触发缺陷又没有超时的测试程序执行,丢弃其他的测试程序。


  • 超时或缺陷程序预测(Timeout or Bug Predict,TOB),按照Csmith生成测试程序的顺序,同时预测测试程序是否触发缺陷和是否超时,留下触发缺陷或没有超时的测试程序执行,丢弃其他测试程序。


DOL测试阶段是结果验证阶段,验证每种选择策略中,触发编译器缺陷的测试程序的数量。待测编译器对每一个测试程序都执行“O0”、“O1”、“O2”、“O3”以及“Os”优化项,对比每个级别优化项的执行结果,如果不一致,就报告该测试程序触发编译器缺陷。使用Correcting Commits方法度量整个缺陷测试程序集合,检测到的编译器缺陷的个数。
针对超时程序的标签定义,实验收集了29998个由Csmith工具生成的测试程序的执行时间,统计结果如表1,分析表中的数据将时间阈值Ψ设为30秒。

表1  执行时间

为了验证CoSS方法的有效性,实验对比在每一种策略所选择的测试程序中,触发不同缺陷的数量,触发独一无二缺陷的数量,以及检测到每一个不同缺陷所耗费的时间。我们将顺序序列(Queue Order,QO)作为对比实验的基准,QO将Csmith生成的测试程序按照顺序执行,用来展示不使用任何加速方法的编译器测试方法的结果。我们将每一种策略的实验周期设置为2天,检测到的缺陷数量如表2所示:

表2  两天内检测到的缺陷数

BP策略通过2天的时间,对比所有的策略找到了最多的缺陷,缺陷检测效果优于其他策略。
图2中的韦恩图反映出各个策略检测出的缺陷之间的关系,它能够反映出每一个策略检测出的独一无二的缺陷,从图中可以看出,TAB策略检测出了2个独一无二的缺陷,BP策略检测出了3个独一无二的缺陷,这几种方法都检测出了一个共同的缺陷。

图2  独一无二缺陷的个数

详细分析图中信息可以发现,TP策略检测出的3个缺陷完全包含在了TOB策略检测到的4个缺陷中,而TOB策略和QO方法检测到的4个缺陷则是完全一致的,TAB策略检测出的缺陷与TOB策略和BP策略检测出的缺陷有2个是相同的。这表明BP策略将检测的重点放在触发缺陷的测试程序上确实能够找到更多的缺陷,而且绝大部分的缺陷都是其他策略检测不出来的,而TAB策略的检测结果比BP策略稍差一些的原因是对测试程序进行了超时判断,使得一部分触发缺陷的程序被剔除了,这个结论也适用于TP策略的检测结果。
表3中数据反映的是不同策略在找到每一个编译器缺陷时所消耗的时间。

表3  找到每一个缺陷消耗的时间(秒)

表中的“缺陷编号”指的是每一个缺陷,“1”指的是QO找到的第一个缺陷,“2”指的是QO找的第二个缺陷,后面的编号以此类推。“QO”这一列展示的是QO方法找到每一个缺陷耗费的时间,时间单位为秒。列“ΔTP”、“ ΔBP”、“ ΔTAB”、“ ΔTOB”分别指的是不同策略找到缺陷消耗的时间与QO方法找到该缺陷耗时的差值。正值代表的是该策略消耗比QO方法更多的时间找到这个缺陷,负值代表的是该策略消耗比QO方法更少的时间找到这个缺陷。因为不同的策略会找到不同的缺陷,所以用“—”将表格进行对齐,就比如说,只有BP策略找到了编号为7的缺陷,那么就将该缺陷对应的其他策略行标记为“—”。从表中可以看出,BP策略找的所有缺陷的用时都要小于QO方法,而且有3个缺陷是QO方法没有找到的。在TAB策略和QO方法都找到的缺陷中,TAB策略消耗更少的时间就找到了这些缺陷,并且它还能找到QO方法所不能找到的缺陷。TOB策略找到的所有缺陷的时间都要比QO方法找到缺陷的时间要短,由于TOB策略找到的缺陷和QO方法找到的缺陷完全一致,所以更能够直观地反映出加速编译器测试过程的效果。


网友评论已有0条评论, 我也要评论

发表评论

*

* (保密)

Ctrl+Enter 快捷回复