文摘

软错误造成的单一事件打乱aerospace-based计算一直是一个严重的挑战。沉默的数据损坏署是结果发生软错误之一。署发生在程序产生错误的输出没有迹象。署是最阴险的一种结果,很难检测到。为了解决这个问题,我们设计和实现一个invariant-based系统称为萝卜。不变量描述程序的某些属性;例如,一个变量的值等于一个常数。萝卜首先提取关键程序点不变量和不变量转换成断言。然后它变硬的程序断言插入源代码。当发生软错误时,断言将在运行时被发现是假的软错误和警告用户。 To increase the coverage of SDC, we further propose an extension of Radish, named Radish_D, which applies software-based instruction duplication mechanism to protect the uncovered code sections. Experiments using architectural fault injections show that Radish achieves high SDC coverage with very low overhead. Furthermore, Radish_D provides higher SDC coverage than that of either Radish or pure instruction duplication.

1。介绍

单个事件打乱(SEU)是一个改变的状态由一个电离粒子(离子、电子、光子等)中引人注目的一个敏感节点微电子设备(1,2]。设备输出的误差或操作引起的SEU叫做软错误。因为这种类型的错误并不能反映一个永久的失败,它称为软3]。第一个失败归因于宇宙射线的报道出现在1975年太空电子发生故障(4]。1993年,中子诱发软错误甚至观察到机载计算机在商用飞机的飞行高度5]。软错误已成为一个关键的挑战在aerospace-based计算(6,7]。

原始的错误率/设备(例如,门闩,SRAM单元)在大部分CMOS工艺预计将保持不变或略有降低;因此软错误率每个处理器与摩尔定律将增长成正比的数量设备添加到一个处理器在下一代8]。除非我们开发和应用更有效的软错误减排技术,这种趋势是不可避免的。

软错误的结果是分为四种类型9),良性的,崩溃、挂起和沉默的数据损坏署图所示1。良性意味着错误掩盖和程序得到正确的输出;崩溃意味着错误导致程序停止执行;挂意味着资源耗尽,但项目仍不能完成执行;沉默的腐败意味着程序产生错误的输出数据。当发生崩溃或挂起时,系统知道程序执行异常。与别人相比,发展更阴险的,因为它没有任何迹象出现。应用错误的输出发生署甚至可能导致财产损失和人员伤亡。错误输出绝对是比没有更危险,因为用户无法意识到错误,直到出现严重的后果。本文主要着重于消除署。

基于症状的故障检测机制来提供低成本解决方案(10,11]。这些机制对软件行为症状的硬件故障和异常检测到它们将非常低成本症状监测的硬件或软件。然而,错误导致署逃避检测,因为他们不会引起症状。为了解决这个限制,基于软件的指令重复是一个可能的选择。使用这种方法,说明复制及其结果进行验证的单个线程内执行(12- - - - - -15]。这个解决方案的优势是纯粹的软件,不需要专门的硬件,可以实现高覆盖率。然而,开销的性能和功率相当高,因为大部分的程序复制。未来的任务将需要更大的计算能力比可用在今天的处理器(4];因此低成本预期未来aerospace-based计算故障检测解决方案。

解决检测发展的问题,本文提出了一种assertion-based检测机制。断言是一个声明,谓词(boolean-valued函数,对错题表达式)。如果找到一个断言是错误在运行时,断言失败上升,这通常会导致程序异常抛出一个断言。本文基于断言程序不变量(16),这是真正的在一个特定的项目属性点或点。例如, 是一个不变的变量呢 代表他们满足线性关系。这通常不变的满意当程序执行但很少满意如果软错误影响的价值 。基于这一原则,我们设计和实现系统萝卜可以加强程序对软错误。萝卜可以提取不变量从一个C程序和插入invariant-based断言回源代码。一旦发现虚假断言,它表明软错误检测。然后停止执行并给出一个警告。

萝卜仅仅将几行代码添加到原始源代码,因此它很容易实现。此外,它不需要修改底层硬件和几乎增加了系统的复杂性。此外,萝卜的开销是非常低的自一个断言的开销很低,断言在一个程序的数量很小。

为进一步增加署报道,我们扩展萝卜,通过融合软件指令复制的机制。部分的代码覆盖不到的萝卜被部署保护指令重复。实验结果表明,萝卜达到低成本、高覆盖率和Radish_D甚至达到覆盖率高于萝卜或纯指令重复。萝卜的技术和软错误缓解Radish_D提供新的解决方案。

2。定义和模型

本节描述重要的定义和模型用于本文。

定义1。一个程序被定义为 表示程序中的函数。 边的集合表示函数之间的依赖性,酸处理 。在表示输入和输出。软计算(17]本文不考虑;因此,如果 , ,在确定,可唯一地确定。

定义2。一个函数 由一组基本块吗 和变量 ;因此 。基本块是一个单一的入口,单一退出的指令序列。一个指令 , ,在那里 表示动态的序列号在执行指令。 表示程序点,等于从一开始偏移量大会文件的位置。 表示源操作数和目标操作数。

定义3。 ,如果 , ,也 , ,然后 被定义为连接器指令。确实,连接器指令传输数据从一个到另一个函数。连接器指令写的变量被定义为连接器变量 。连接器变量包括函数参数变量,函数返回变量和全局变量。根据定义,连接器指令是最后写一个连接器变量的函数。

定义4。执行概要文件用 ,这是作为一个元组 。执行概要文件定义了变量的值在给定程序点。 表示给定的程序。 是收购价值的变量出现在

定义5。不变的 被定义为 ,在那里 代表了程序, 是变量的有序集合, 代表的关系中出现的变量 ,在那里 设置的关系被认为是,见表1 可分为一元、二元和三元。
例如,假设一个不变 ,在那里 = 0 x10, , 代表在程序点0 x10命令集 ,也就是说, , ,满足的条件

故障模型假设是一个单一的寄存器文件内翻转。最错误的其他部分处理器最终表现为破坏状态寄存器文件(18]。此外,我们假设一个故障发生在程序的执行。

3所示。萝卜

本文实现了萝卜,一个系统可以强化程序对软错误。萝卜增强了程序的弹性软错误插入断言源代码。断言是基于程序不变量。如果断言语句的执行期间不满意,则停止执行并警告报告软错误的发生。

萝卜是C源文件的输入和输出是一个新的C源文件。新源文件可以编译和执行就像原始的源文件。他们是相同的功能,但不同的可靠性。

本节介绍了工作流的萝卜,可分为三个阶段,即预处理、检测和选择。图2显示了每个阶段的细节。在预处理阶段,我们提取执行概要文件 关键项目的点。然后 用于提取潜在的不变量在检测阶段。在那之后,不变量 得到了其中一小部分转换为断言在选择阶段。最后,硬化源代码是输出。下面我们将介绍每个阶段。

3.1。预处理阶段

在预处理阶段,我们发现关键的程序分和提取它们的执行概要。概要文件是用来提取不变量在未来的阶段。最后,断言将被放置在这些程序点以防止错误传播。署保险由于不同程序的断言,因此我们分析署的传播并找到传播的关键程序点。错误可以通过数据流和控制流传播招致署。由于两类传播的区别,我们分析和寻找他们的关键项目单独点。

当通过数据流错误传播时,相同的静态指令执行的无故障的执行,但指令读取或写入的数据损坏。招致署,破损的数据需要传输到其他功能,尤其是输出函数。只有连接器指令可以执行此操作;因此他们必须执行和数据传输是损坏的。这使得连接器指令有效的故障检测,因此他们选择的关键程序点对数据流传播。

接下来,我们讨论在控制流错误传播。比较指令执行两个值之间的比较,比较的结果影响的标志寄存器,这决定了随之而来的由一个分支指令。通过控制流传播意味着一个错误的分支指令执行跳转。假设在无故障的执行 分支指令,下一条指令是什么 ,这意味着 选择 作为下一个基本块。当标记寄存器损坏的软错误, ,这意味着 选择了错误的分支 而不是 。为了避免这种情况,我们应该检查是否正确的分支被执行之后 。因此选择分支指令作为关键程序控制流的传播。

根据上面的分析中,数据流和控制流的关键程序点传播指连接器指令和分支指令。需要两个步骤提取关键程序的执行概要文件点。

步骤1。我们编译源代码,把它翻译成汇编文件,然后找到连接器组装文件中的指令和分支指令。他们的程序点记录和点集添加到项目

步骤2。执行概要文件被使用Kvasir[收购16]。Kvasir执行C和c++程序并创建数据跟踪文件的变量及其值在运行时通过检查的操作二进制。使用Kvasir可以中断程序的执行和读取所有变量的值清单项目的兴趣点。一旦执行完毕,我们得到的资料 点在目标程序

3.2。检测阶段

在检测阶段,变量的有序集和相应的命令设置的值是根据执行生成的配置文件 。我们检查值是否满足任何的关系 表中列出1。检测阶段总共有4个步骤。

步骤1。为每个程序点 ,我们得到的集合访问变量 从执行概要 。然后一元、二元和三元命令集 , , 创建。上标数字引用变量的有序集的数量。例如, 两个变量的安排吗 ;也就是说,

步骤2。找到相应的值的变量出现在 , , 并生成值的命令集 , , 。例如, 是命令值组吗

步骤3。对于有待定参数的关系,我们使用一个值的有序集的一部分来计算这些参数。从而确定整个表达式。

步骤4。测试值的有序集合的每个元素满足条件的关系。如果是这样,那么创建一个新的不变量并把它放到潜在不变集
把一个二元关系 为例。我们将显示每一步的检测阶段。因为它是一个二进制的关系,只有二进制命令组 被认为是在这个例子。

在第一步中,我们得到了 通过搜索执行概要 。然后 通过创建每两变量的安排吗

在第二步中, 通过获得的值 在执行概要 。可能有很多值对 因为某些代码部分可以调用多次调用会产生一个值在一个单一的执行和每个实例。

在第三步中,我们计算的参数 , 。为此,我们需要使用至少2的元素 。假设这两个元素 ,它可以很容易地获得

在最后一步中,所有元素 检查是否满足 。如果所有人都通过验证,不变的 持有并将其添加到潜在的不变集

3.3。选择阶段

经常观察到的潜在的元素数量不变集 是非常大的。如果它们都转换成断言和插入源文件,它将产生很高的性能开销。在选择阶段,选择适当的不变量根据其检测能力的发展。启发式的选择标准制定的基础上传播的发展。这些启发式是通用的,可以应用于任何不变量。我们首先列出启发式,然后描述选择的步骤。

启发式1。有某些类型的变量应该在每个目标监控程序。
一小部分变量能够告诉如果顺利执行,从而监控这些变量能够检测署。目标程序的点集 可以分为项目连接器指令和分支指令。连接器项目分的指令,它是连接器的变量应该特别关注,因为他们反映函数的结果是否正确。在程序的分支指令,branch-controlling变量,它出现在声明中如果,,或结构,反映了这些结构的状态,因此应注意。因此,所有目标程序点我们发现某些变量监控。

启发式2。检测发展的可能性增加如果有效值由断言定义的数量减少。
无效值不能通过考试的断言软错误的存在。因此有更多的无效值(有效值)意味着检测发展的可能性增加。数量的不变量的有效值是根据其关系。平等的关系,使用“ “作为操作员,只有一个有效的值,然后来包容 范围( , ),和不平等的关系 为了提升数量的有效值。

启发式3。检测发展的可能性增加如果更多的变量都包含一个断言。
出现在一个断言的变量越多,更多的变量,它可以监控。如果任何变量被损坏由于软错误,能够捕捉错误的断言。因此有更多的变量在断言导致更高质素的报道。到目前为止,变量的最大的数是3,指三元关系。

利用这些启发式,我们能够减少不变量的数量和获得更有效的断言。选择阶段有三个步骤。

步骤1。的不变量包含连接器变量在程序点连接器指令或branch-controlling变量在程序的分支指令基于启发式的选择1

步骤2。不变量的关系,更少的有效值是根据启发式捡起2

步骤3。的不变量包含最多的变量选择启发式3
选择过程停止,直到只剩下一个不变的或已执行的所有步骤。然后我们选择不变量转换为断言,这基本上是一个字符串转换问题。为了简洁起见,我们不谈论它。最后我们包括断言头文件的开始新的源文件以确保断言可以工作。

4所示。Radish_D

生成的断言萝卜不能完全监控所有的变量和程序点;因此某些缺点可能传播通过无保护的代码部分。为了进一步提高质素的报道,我们引入基于软件的指令复制机制来保护不受萝卜的代码部分。

本文利用指令迅速复制机制(15)进行比较,在Radish_D也为我们自己的重复。快速复制路径上所有计算指令复制和复制指令使用不同的寄存器和内存位置。在特定的同步点,比较指令插入检查如果原始指令及其复制品有相同的值。

而不是部署完整的指令迅速复制机制,Radish_D应用选择性指令复制机制。因为指令的一部分被保护的断言,我们只需要复制他人。

部署复制之前,我们需要确定哪些变量是安全的保护下断言。断言可以保护变量出现在其声明中。然而,保护并不持续这些变量的整个生命周期。只有分数从本地函数的开始到变量的主机断言被认为是安全的,因为变量的值检查期间的执行断言。

我们分区每个变量的生命周期的断言和确定安全期。然后复制部署在教学水平。复制的目标是不包含一个变量的指令操作数的安全期。创建一个副本指令通过复制原始指令的操作码和操作数。目的操作数是变成了一个未使用的寄存器,复制的原始目的操作数。接下来我们决定如果有需要改变复制源操作数的指令。如果已经有一个复制源操作数的,这意味着这个源操作数是一些指令的目标操作数,从而得到了一个副本,我们代替与它的拷贝复制指令的源操作数。复制指令插入前的原始指令在同一基本块。

此外,商店,选择分支,并调用指令同步点。如果任何源操作数的指令的副本,我们比较它的价值和它的复制插入比较指令。根据操作数的类型(int或浮动),比较指令可以是icmp指令或fcmp指令。比较指令后,一个分支指令使用的谓词neq插入代码。如果这两个值显示差异,将会跳转到一个名为faultDetected的函数;如果不然,它将继续执行之前的商店,分支机构,或调用指令。faultDetected输出错误消息并返回函数的退出代码,它将通知系统的软错误和结束执行。

我们用一个例子来显示我们的方法之间的区别和完整的指令复制机制图3。为了一致性,我们使用LLVM (19汇编语言,汇编代码。图3(一个)显示原来的汇编代码和图3(b)显示了完整的指令后的汇编代码重复。它可以在图中找到3(b), 的副本 复制是通过指令来实现的 。同样的, 的副本 通过重复 是同步点和源操作数的 , ,都需要进行检查。 比较 分别与他们的副本。如果值的 是不平等的, 将调用faultDetected软错误报告。

生成的汇编代码Radish_D图所示3(c),假设我们已经获得一个断言 利用萝卜,这是“维护行代码所示 ”。由于断言, 在执行这个例子被认为是安全的。 不再是必要和指令用于他们的重复了。变量除外 仍然需要被复制和检查;因此 是重复的 在同步点和检查 。Radish_D和完整的指令复制机制的效率将在下一节中被利用。

5。实验

本文应用故障注入实验来验证萝卜和Radish_D的有效性。故障注入实验进行最初的执行。硬化高管使用萝卜,Radish_D,完整的指令复制目标随后。我们比较故障注入实验和计算的结果提交覆盖和性能开销。确保这些机制中一个公平的比较,我们使用一个叫做质素的指标检测效率,这是定义在之前的工作9]署覆盖率和开销之间的比率检测机制。

平台验证是Ubuntu 14.04 (AMD64架构)。LLFI [20.应用于执行故障注入。LLFI LLVM-based故障注入工具。源代码翻译成一个中间表示(IR)和红外代码注入。错误可以注入特定程序点,效果可以很容易地追踪回源代码。LLFI注入目的寄存器配置。在一个单一的故障注入,LLFI随机拿起一条指令和注入1软错误的目标操作数。一个故障注入试验一直持续到故障注入已经重复了1000次。注入的故障可能会影响数据流和控制流。我们采取以下LLVM IR代码来解释对控制流的影响:(1)% judge1 = icmp等% 1,% 2(2)br i1 % judge1,标签% BB1组,标签% BB2组。

% judge1决定分支的结果。如果% judege1注入,分支指令可能会选择错误的分支,从而影响控制流。完整的指令复制机制由开发一种新的实现通过在LLVM的基础设施。使用的传递也是Radish_D的操作指令重复通过修改某些条件重复。

计划用于评估来自MiBench基准套件(21]。这些项目是qsort(执行快速排序的算法),isqrt(这是基地的两个模拟平方根算法),立方(解决了一个三次多项式),rad2deg(弧度和角度之间的转换),crc(32位crc计算检测意外更改原始数据),和bitstrng(打印格式化字符串的字节位模式)。这些都是C程序组成的几百行C代码。我们使用25输入提取不变量和随机选择一个输入的注入。

5.1。对比萝卜和全指令重复

4显示的性能开销萝卜和完整的指令重复。我们使用原始程序的执行时间作为比较的基准。与基线相比,平均开销萝卜是30.4%,和完整的指令复制52.8%的开销。完整的指令复制机制的开销是22.4%高于萝卜的开销为研究项目。

5显示了区议会保险。萝卜的平均署覆盖率是77.1%,全指令重复是84.3%。完整的指令的平均署报道重复是萝卜的高出7.2%。在大多数基准测试,提交完整的指令重复保险和萝卜很近。

完整的指令重复不达到近100%的覆盖率,因为它不检查存储和分支指令的结果。例如,在图3(b)表示完整的指令重复,如果 注入, 影响和可能选择错误的分支。迅速(15)提高了覆盖率接近100%,因为它假定硬件应用ECC和它增加了控制流检查机制。可以观察到图提交检测效率6。萝卜具有更高质素探测效率,完整的指令重复的1.6倍。这是因为全指令复制机制保护所有指令执行,这开销高质素覆盖率很高。然而,萝卜获得相对较高的署覆盖率低得多的开销。萝卜达到这样的目标,控制程序点生成断言的数量。进一步断言的执行成本相对较低和断言有良好署报道,因为他们很少满意当软错误发生。

5.2。Radish_D的实验结果

Radish_D的平均署覆盖率为92.5%,高于8.2%的全部指令复制和萝卜的高出15.5%。可以验证,指令重复Radish_D保护不安全的代码部分覆盖不到的断言。Radish_D可能产生断言检查后的变量存储在内存存储指令(见启发式1)。此外,在程序的分支指令,branch-controlling变量检查。因此Radish_D抓住一些错误的断言,逃避重复的检测机制和覆盖面Radish_D高于全指令重复。

Radish_D的平均开销是76.3%,低于之和的开销全部指令重复和萝卜,因为我们消除了重复部署到指令已经被保护的断言。

Radish_D的平均区议会探测效率低于指令重复或萝卜。Radish_D,有重叠的软错误都能被探测到的指令重复和断言。这些软错误,开销增加部署指令重复但署报道并不增加。署检测效率之间的比率是署覆盖率和开销,从而降低了。

5.3。假阳性的不变量

输入时可能出现的假阳性这个断言点的输入值不满足条件的断言从训练的输入。我们使用25输入训练和100年输入进行测试。在这些运行没有错误注入。我们测试的所有项目被用来评估署覆盖率故障注入实验。结果表明,平均误判率的研究项目是4.8%。

我们也进行实验考试训练集规模的影响。qsort图所示的结果7。训练集由25、50、75输入和假阳性计算在100个输入。

假阳性率从5%降低到3%,该训练集规模从25到50到75年的2%增加投入。署覆盖率也随着训练集的增加从25到75年减少输入。影响署覆盖率和假阳性率增加训练集大小是重要的。因此我们应该根据用户选择训练集规模的目标。如果用户指定的绑定署覆盖率和开销通过把假阳性率变成开销,我们可以选择一个训练集规模来实现目标。

此外,重新可以通过断层积极减少开销。当断言将发出警报,我们可以确定它是重新制作的假阳性。如果断言再次提出了一个警告,这是一个假阳性。在这种情况下,警报可以忽略,程序可以继续。

从上面的讨论,可以得出的结论是,Radish_D署覆盖率高于萝卜或完整的指令重复。但其开销也高,这表明Radish_D应该使用的情况下署报道被认为有更多的优先级比开销。此外,萝卜的署检测效率远高于Radish_D或全部指令重复,这意味着它更划算。但是萝卜可能由于误报产生开销。用户可以选择萝卜或Radish_D根据他们之间的权衡考虑署覆盖率和性能开销。

先前的研究[8,22,23)适用与单个变量和不变量的大部分不变量是基于有界区间。我们应用不变量与更多的变量,它可以取得更好的覆盖在许多场合。例如,我们可以提取一个不变的 从一个典型的循环结构如下所示: } 它是发现, 通常比bounded-range-based不变 在检测错误自 检查这两个 只检查

一个典型的标准选择探测器中定义的22、闷、探测器检测到一个错误的概率是考虑到有一个错误检查变量的值。紧张的概念是基于一个变量的值。本文中的不变量可能包括2或3变量和紧张的概念不能被用来描述一个不变量与多个变量。例如,如果 是不变了 ,因为有多个可能的值 不能决定是否不变仍然是满意,因此紧张不能计算。由于紧张不能被使用,我们应用某些启发式选择不变量和被证明是有效的。

7所示。结论

解决检测发展的问题,我们提出一个方法,适用于invariant-based断言和实现一个系统叫萝卜。萝卜不需要任何硬件修改错误检测功能添加到原来的系统,也不需要承认程序的语义,因此具有良好的可扩展性。实验表明,萝卜达到高质素覆盖率非常低的开销。

此外,我们建议Radish_D通过添加指令重复的不安全的代码部分不受断言。Radish_D署覆盖率达到高于萝卜或完整的指令复制机制。萝卜和Radish_D为软错误减灾提供可行的替代方案。

相互竞争的利益

作者宣称没有利益冲突有关的出版。

确认

这项工作得到了中国国家基础研究计划(“973”项目)。