董 剑 佟双军 左德承 刘宏伟
哈尔滨工业大学,哈尔滨150001
面向S698处理器的软件故障注入工具研究与实现*
董 剑 佟双军 左德承 刘宏伟
哈尔滨工业大学,哈尔滨150001
故障注入技术通过人为引入故障,加速系统失效,能够在短时间内有效地评估容错计算机系统的容错性能。通过对S698芯片以及当前软件故障注入技术的研究,设计实现了一款针对S698处理器的软件故障注入工具S-SFI,能够进行关键寄存器被修改、代码段破坏、进入非法工作区、死循环、软件不喂狗和接口器件工作异常等类型故障的注入。该工具利用串口通信的方式在宿主机端提供了良好的交互界面。通过实验对S-SFI的各项功能进行了验证,并分析了各类型故障对目标系统的影响程度。 关键词 软件故障注入;S698处理器;中断处理
计算机系统的可靠性评估是一项非常复杂的工作[1]。通常采用的模型分析方法随着系统软硬件规模的快速增长而变得越来越困难。对于实际系统,模型分析中涉及到的故障激励和错误的传播过程过于复杂,如果在建模的过程中将实际系统假设成较为简单的模型,分析结果就没有太大的参考意义。通过实验方式来评估系统可靠性已经成为一种非常有吸引力的验证系统容错机制的方法。其中,将物理故障注入目标系统硬件是一种较为常用的方式[2]。诸如引脚级故障注入、重离子辐射和电源干扰都是这种故障注入方式的常用方法[3-4],该方法的优点是能模拟真实的硬件故障,但缺点是需要针对特定的目标系统附加额外的硬件和故障注入设备。另外,目前高复杂度、高速度的硬件系统也使故障注入设备的研制变得非常困难,甚至不可能。通过对系统的仿真模型执行故障注入也是评估可靠性的常用方法,但该方法耗时多,需要花大量时间开发仿真系统。基于软件实现的故障注入技术[5-6]正逐渐受到关注,通过某种途径(插入陷阱指令或者让目标程序在调试模式下执行)中断目标程序的执行,利用软件代码模拟系统软硬件故障。这种方式实现复杂度低、成本小,具有很强的可扩展性。
本文设计并实现一款面向S698处理器芯片的软件故障注入工具S-SFI(Software Fault Injector for S698)。S698是一款商业化的基于SPARC V8标准的32位RISC处理器,其内部集成64位的浮点处理单元(FPU)、PCI控制器等片上外设。该芯片适用于高可靠实时控制,广泛应用于工业控制、工程机械、航天航空、医用电子设备和商用电子设备等领域。所提出的软件故障注入工具能完成关键寄存器修改、代码段破坏、进入非法工作区、死循环和接口器件工作异常等多种类型的故障注入。应用程序开发者能够通过故障注入之后系统的执行效果来检验嵌入式应用的容错性能,有效辅助系统开发人员完成容错应用的研制。
故障注入技术提出于上世纪70年代,主要用于验证容错系统的设计。按照实现方式的不同可以分为基于仿真的实现、基于硬件实现和基于软件实现3大类。基于仿真方式的故障注入需要对目标系统建立仿真模型,对模型的精确性要求较高。基于硬件方式的故障注入需要使用额外的硬件,并且容易对目标系统造成永久性损坏。而软件实现的故障注入通过修改程序执行时内存映像、处理器寄存器或应用程序源代码等方式来模拟故障的发生,其实现成本低、对目标系统依赖性小、对其硬件没有损坏、具有较好的可移植性。目前国内外研究机构已开发了多款软件故障注入工具,如表1所示。
从表1中可以看出,FIAT[7]的故障注入位置是由用户在应用程序这个层面上选择的,而其对内存映像故障注入的具体位置是通过编译器和装载信息获取的,这就决定了它无法注入瞬时故障。FERRARI[8]的运行受限于带有ptrace接口函数的故障注入目标系统,无法对不带有操作系统环境的嵌入式应用执行故障注入。DOCTOR[9]适用于分布式系统。Xception[1]对处理器要求较高,需要用到调试硬件编程接口,而这在很多情况下无法获取。FTAPE[10]的故障注入需要修改驱动程序,并且该方法只能注入比特位翻转类型的故障。GOOFI[11]只是提供了一个通用的框架,它的主要目的是为对不同的故障注入目标系统执行故障注入提供一个通用的操作平台,因为该平台是利用面向对象的思想设计的,所以能方便地扩展故障注入功能。目前的GOOFI版本只提供了对运行前引入故障这种方法的支持,这是其局限性。JACA[12]虽然能够对Java应用程序执行高层次故障注入(例如修改变量值),但其运行依赖于Java语言的反射机制,仅仅适用于对Java程序的故障注入。从上述对这些软件注入工具的分析来看,软件故障注入工具需要针对其依赖的运行环境和编译环境进行设计,同时受到这些因素的影响,其功能也有一定的局限性。而目前国内尚未发现能够运行于S698处理器的故障注入工具。为此,通过对现有工具中针对不同注入方式以及不同故障类型的注入技术的研究,提出了一款支持国产S698处理器的软件注入工具S-SFI。
1.1 SFI的运行环境
S-SFI可分为服务端和控制端两部分,分别运行在宿主机和基于S698处理器的目标系统上。具体运行环境如图1所示。
S-SFI的服务端运行在以S698芯片为处理器的目标硬件系统上,以串口中断处理程序的方式注册到目标系统的中断向量表中。故障注入目标程序连同服务端相关代码在集成开发环境Orion 5.0中编辑、编译、链接生成可执行程序之后,开发环境通过宿主机COM1串口下载可执行程序到目标硬件(对应DSU调试支持接口)之上运行。宿主机COM1口和目标硬件的DSU口共同组成了程序下载运行调试的物理通道。目标系统提供一个串口(UART1)与宿主机机串口2相连,构成故障注入工具控制端与服务端之间的故障注入与结果回收通道。
图1 S-SFI的运行环境
表1 国外经典软件故障注入工具
工具名称实现单位注入特点FIAT美国CMU大学破坏任务内存映像FERRARI美国Texas大学利用UNIXptrace接口函数提供的调试功能注入故障DOCTOR美国Michigan大学能注入处理器、内存、通信故障Xception葡萄牙Coimbra大学对处理器内部调试硬件编程FTAPE美国Illinois大学修改驱动程序模拟磁盘、内存等故障GOOFI瑞典Chalmers大学面向对象的故障注入工具,用通用数据库存储数据JACA巴西Campinas大学利用Java语言的反射机制对Java程序执行故障注入
1.2 S-SFI的功能设计
S-SFI的服务端和控制端的具体功能结构如图2所示。
控制端位于宿主机上,是用户配置故障注入参数、进行故障注入、观察运行结果的交互界面。由于目标程序运行在嵌入式环境下,而这种环境所能提供的人机交互方式非常有限且不直观,为此选择将工具的控制部分实现在能够运行Windows的宿主机上,方便用户操作。S-SFI的控制端主要包含串口通信支撑模块、故障注入参数生成模块和命令发送与结果回收模块。串口通信支撑模块主要包含与目标系统进行串口通信的一些功能。它提供串口选择、发送数据、接收数据和配置串口波特率等串口相关功能给其他模块,供控制端与服务端通信使用。故障注入参数生成模块为用户提供配置界面,并且根据用户的输入合理地组织故障注入命令。命令发送与结果回收模块一方面接收参数生成模块的故障注入命令数据并进行相应的改造以形成控制命令字节流,通过串口发送到工具的服务端。另一方面还需接收解析服务端发来的反馈结果显示给用户。这3个模块统一协作,使得用户能够在PC机上配置故障注入参数、执行故障注入并得到反馈结果。
服务端位于目标系统之上,是工具的核心部分,主要包含了关键寄存器修改、代码段破坏、进入非法工作区、死循环、软件不喂狗和接口器件工作异常这6种故障的实际注入模块和系统状态反馈模块。命令接收与解析模块接收串口上收到的故障注入命令字节流并解析出命令的含义,将相关参数放到相应的数据结构中供后续的故障注入使用。不同的故障类型所对应的参数需求如表2所示。在S-SFI的注入命令格式为‘b’+faultType+parameters+‘e’,命令字长度不固定,用b和e字符指示命令的开头与结尾,它们之间的内容如果与‘b’,‘e’相同则需要用‘’字符进行转义。命令的第1个字节描述故障类型,其余位用来表示注入故障的参数,命令字长度不固定。
图2 S-SFI总体功能结构
1.3 S-SFI的实现
(1) 关键寄存器的修改
S698包含72个普通寄存器以及大量的系统寄存器,普通寄存器能通过汇编指令访问到,系统寄存器可通过C程序访问。目标系统处理器有用户、特权2种工作模式。在中断处理程序中,处理器处于特权模式,能读写所有存储器和寄存器。
表2 每种故障类型注入所需的参数变量
系统寄存器分布于内存地址空间上,中断发生时不会被硬件自动保存,能够在中断处理程序中直接修改。而普通的72个寄存器,在中断发生之时会采用SPARC架构特有的窗口机制保存部分通用寄存器。因此,实现寄存器修改的关键就是找到被寄存器滑动窗口所隐藏的寄存器。图3中给出了寄存器窗口的结构。
图3 具有8组寄存器窗口的寄存器结构
在S698中,当发生函数调用(包含中断调用)时,隐含的save指令使窗口按图中逆时针的方向移动一个格,使得被调函数在新的窗口运行,前一窗口的out寄存器组变成当前窗口的in寄存器组,这种特性常常使得函数调用变得高效,但却使我们无法在中断处理程序中访问被注入的目标程序的寄存器。为此,对中断注册函数catch_interrupt进行了反汇编分析,得到了S698中断的注册过程。在此基础上,设计了窗口寄存器的访问方法。在用于注入的串口中断处理子程序中,先通过restore执行回到进入中断处理程序之前的寄存器窗口B,利用该窗口的sp寄存器的值,可以访问并修改内存中保存的窗口B的寄存器的内容,待中断返回后,注入的故障值就会被恢复到相应的寄存器中。在这里还需要注意,涉及修改寄存器的代码部分不能使用局部变量,因为局部变量存储在内存中的堆栈段,堆栈段通过sp寄存器(窗口中的o6寄存器)访问,而sp寄存器在窗口变换的过程中对应的物理寄存器不同,其值会发生变化,故障注入会因不能正确访问到变量值而失败。
(2)代码段的破坏
代码段的破坏需要起始破坏地址、终止破坏地址和待注入破坏值3个参数。由于控制端发过来的地址可能不是4字节对齐的,所以在进行故障注入时首先需判断起始地址,如果是4字节对齐地址,利用整型指针指向当前待破坏代码段起始位置,以每次四字节的速度执行故障值的写入。如不是4字节对齐地址,需利用字节指针先处理前面若干字节,按照字节依次写入故障值。因为Sparc处理器内存的存储格式是大端模式,其在存储4字节变量的时候,将变量的最高字节存放在内存的最小地址上,举例来说,如果内存地址0x40037280-0x40037283处存储了整型内容0x12574538,那么这个数据中的字节0x12会被存放在地址0x40037280处,字节0x38会被存储到0x40037283处。对于S-SFI来说,因为只接受4字节为单位的代码段破坏故障值,所以如果用户指定的代码段首地址不是4字节对齐,为保持一致性,在对4字节对齐地址之前的内存单元进行破坏时,要仔细选择写入的字节。图左边表示向内存地址0x40037280写入破坏值 0x12574538之后的内存形态,如果用户指定的故障注入地址以0x4003727E开始,如图4中左侧画“??”处,那么,要保证在破坏前2个内存单元之后,内存单元中的数据分布要与图中右侧的形式一致。
图4 多字节代码段破坏值在内存中的分布
(3) 其它注入功能的实现
进入非法工作区主要是对目标程序的PC和nPC寄存器的修改。由于这2个寄存器都会被寄存器滑动窗口保存起来,注入方法与寄存器修改类似。非法工作区的地址采用随机地址,在实验中,进入非法工作区后系统大多数会崩溃。死循环故障使用汇编语言向中断返回地址写入死循环机器代码,将其写入PC寄存器所指向的代码段地址。通过对brach指令机器码的分析获得实现死循环的机器代码。接口器件的工作异常采用了基于定时器的注入方式,定时器中断处理程序中采用循环的方式将故障值数组中的每个故障值注入到指定的接口控制系统寄存器中。
实验所采用的目标系统为欧比特提供的s698开发系统,目标程序为整型和浮点矩阵计算程序。实验中针对6种类型的故障共进行了5110次注入。表3对注入结果进行了统计。
表3 故障注入实验结果统计
在共计5110次的故障注入测试中,有722次导致目标系统崩溃,比例达到了14.13%。有100次导致运行结果不正确,比例为1.96%,故障注入后仍旧得到正确结果的比例为83.91%。首先来看寄存器故障注入部分,对大部分寄存器执行的故障注入对目标系统的运行结果没有影响,这可能是因为目标程序运行中并没有用到这些寄存器,在导致目标系统运行结果不正确的100次故障中,o0,o4,o5,Y,FSR寄存器的故障注入占有的百分比相对多些,说明程序在执行的过程中经常用到它们,这些寄存器对于得到正确的计算结果非常重要。在导致目标系统崩溃的525次故障中,fp,sp,PSR,PC,nPC,WIM和TBR占有的百分比最多,o2次之,这是由于前面几个寄存器都是堆栈指针(程序要通过它来访问变量)或者控制寄存器,它们的故障对系统影响非常大,当其值被改变后,程序可能访问到了错误的内存位置或进入不正确的状态而导致系统运行崩溃。从表中也可以看出,关键寄存器修改、破坏代码段、进入死循环和进入非法工作区这几种类型故障注入后引起系统的崩溃或者错误率都到90%以上,证明它们对于目标程序来说都是非常致命的故障。在系统设计时,要着重研究如何检测与应对这些对系统运行而言非常关键的故障。
经过对S698处理器的深入研究,本文利用基于串口和定时器中断的故障注入手段,开发了一款软件故障注入工具S-SFI,能完成关键寄存器修改、代码段破坏、进入非法工作区、死循环、软件不喂狗、接口器件工作异常这6种类型故障的注入,并通过实验对各项功能进行了验证。S-SFI基于中断控制注入的执行,实现了运行时的故障注入,可在线调整注入参数,能极大提高基于S698的容错系统的调试与验证效率。在下一步工作中,将展开对故障注入数据的分析工作,为用户提供更加直观的系统容错能力参考数据。
[1] Carreira J, Madeira H, Silva J G. Xception: Software Fault Injection and Monitoring in Processor Functional Units[J]. Dependable Computing and Fault Tolerant Systems, 1998, 10: 245-266.
[2] Hsueh M C, Tsai T K, Iyer R K. Fault Injection Techniques and Tools[J]. Computer, 1997, 30(4): 75-82.
[3] Natella R, Cotroneo D, Duraes J A, et al. On Fault Representativeness of Software Fault Injection[J]. IEEE Transactions on Software Engineering, 2013, 39(1): 80-96.
[4] Arlat J, Crouzet Y, Karlsson J, Folkesson P, Fuchs E, Leber G H. Comparison of Physical and Software-implemented Fault Injection Techniques[J]. IEEE Trans. Comput, 2003,52(9) : 1115-1133.
[5] Ziade H, Ayoubi R A, Velazco R. A Survey on Fault Injection Techniques[J]. Int. Arab J. Inf. Technol., 2004, 1(2): 171-186.
[6] Wei J, Thomas A, Li G, et al. Quantifying the Accuracy of High-level Fault Injection Techniques for Hardware Faults[C]. The 44rd Annual IEEE/IFIP International Conference on.Dependable Systems and Networks (DSN), 2014.
[7] Barton J H, Czeck E W, Segall Z Z, et al. Fault Injection Experiments Using FIAT[J]. IEEE Transactions on Computers, 1990, 39(4): 575-582.
[8] Kanawati G A, Kanawati N A, Abraham J A. Ferrari: A Flexible Software-based Fault and Error Injection System[J]. IEEE Transactions on Computers, 1995, 44(2): 248-260.
[9] Han S, Shin K G, Rosenberg H A. Doctor: An Integrated Software Fault Injection Environment for Distributed Real-time Systems[C]. International. IEEE Computer Performance and Dependability Symposium, 1995, 204-213.
[10] Tsai T K, Iyer R K. Ftape: A Fault Injection Tool to Measure Fault Tolerance[R]. NASA STI/Recon Technical Report N, 1994.
[11] Aidemark J, Vinter J, Folkesson P, et al. Goofi: Generic Object-oriented Fault Injection Tool[C]. International Conference on Dependable Systems and Networks, 2001, 83-88.
[12] Martins E, Rubira C M F, Leme N G M. Jaca: A Reflective Fault Injection Tool Based on Patterns[C]. International Conference on Dependable Systems and Networks, 2002, 483-487.
A Software Fault Injector for S698 Processor
Dong Jian, Tong Shuangjun, Zuo Decheng, Liu Hongwei
Harbin Institute of Technology, Harbin 150001, China
Thefaultinjectiontechnologycanacceleratesystemfailurebyinjectingthefault,whichcaneffectivelyevaluatethefaulttoleranceperformanceoffaulttolerantcomputersysteminashortperiodoftime.ByresearchingthesoftwarefaulttechniquesandS698chip,asoftwarefaultinjectorforS698chip(S-SFI)isdesignedandimplemented,whichcaninjectfaults,suchasthekeyregistersmodification,codesegmentwreckage,illegalworkareaentrance,thedeadcycle,errorofwatchdogandabnormalinterface,intothesoftwaresystemrunningonS698.Finally,thefunctionsofS-SFIisevaluatedbyexperiments,andtheinfluenceofeachtypeoffaultonthetargetsystemisanalyzedaccordingtotheexperimentalresults.
Softwarefaultinjection; S698chip;Interruption
*国家自然科学基金(61100029)
2014-10-29
董 剑(1978-),男,山东章丘人,博士,教授,主要研究方向为容错计算技术;佟双军(1990-),男,哈尔滨人,硕士研究生,主要研究方向为容错机制验证;左德承(1971-),男,黑龙江五常人,博士,教授,主要研究方向为容错计算与移动计算;刘宏伟(1971-),男,黑龙江大庆人,博士,教授,主要研究方向为软件可靠性。
TP302.8
A
1006-3242(2016)04-0083-06