基于程序变异的故障注入及故障规则库的设计
2010-11-07徐丽中国矿业大学计算机科学与技术学院221008
徐丽 中国矿业大学计算机科学与技术学院 221008
基于程序变异的故障注入及故障规则库的设计
徐丽 中国矿业大学计算机科学与技术学院 221008
1. 基于程序变异的软件故障注入方法
软件故障注入的方法有很多种,本节着重介绍利用插入的故障代码违反程序中函数的满足条件(前置条件、后置条件或其它),改变其状态,迫使软件出现故障,使程序偏移正常的控制流,从而达到引发异常,执行异常处理代码的软件故障注入方法。
1.1 基于断言违背的软件故障注入方法
对于违背语言规则或违背系统规则的隐式引发的异常,根据异常处理结构的抽取信息,对try块中的每个语句可以采用基于断言违背的软件故障注入法进行故障注入。假设程序中有下列的语句:
int [ , ]a=new int [2][3]
该语句执行的前置条件是数组的下标的满足条件,由于C#中默认的下标起始值为0,所以下标的范围定义为0到下标值减去1,即我们对于上述定义的数组,可以取到的范围为 int [0][0]-int [1][2]我们所采用的断言违背的故障注入则有以下几种可能来进行注入,从而引发所对应的异常。
在测试时只需改变数组下标的值,就可以改变注入的错误,从而引发不可达的异常,注入故障后即可进行异常机制的测试。
对于用户自定义异常,根据抽取的异常处理结构信息,针对引发异常的条件则可以进行故障注入。分为两种情况:一种是基于断言违背的软件故障注入方法,假设在程序的源代码中有如下的一个语句:
if (0<=i && i throw ArrayIndexOutOfBoundsException; 则可以采用与上面类似的故障注入程序来进行。另一种是普通的故障注入方法,假设在程序的源代码中有如下的一个语句: if ( currValue == 0 ) throw new ZeroValueException(); 则在进行故障注入时,可以直接对currValue赋值为0,即可引发ZeroValueException(),测试源程序不可达的异常代码,增大测试的覆盖面。 从上面的例子中可以看出,基于断言违背的软件故障注入技术可以很好地仿真这类软件故障。但如果在条件语句中涉及到系统调用,那么通过简单的程序变异或断言违背技术通常无法直接修改系统调用的返回结果。本文在设计实现时,拟采用在条件中插入真值法来注入故障,从而引发异常。假设有下列语句: if (p=malloc(sizeof(int))= =NULL) throw OutOfMemoryException; 因为这个语句是一个系统函数,并且不能直接访问它的源代码。为了测试由该异常引发的异常处理代码段,可以将上式条件语句转化为如下形式: if (p=malloc(sizeof(int))= =NULL||true ) throw OutOfMemoryException; 此方法扩大了if语句的条件判断范围,无论系统调用函数运行的结果如何,在并上条件为真的情况下,都将引发异常,执行相应的异常处理语句,达到测试异常机制的目的。 本节主要针对关系表达式和布尔表达式进行研究和讨论,在原程序中做一个很少的语法改变即可得到一个变异程序。例如,一个大于号“>”可以改变为“≥”,可以测试到异常处理代码;我们也可以在条件语句中改变操作数让程序转去执行异常处理代码。假设有下列语句: a>5,a+b<10; 我们可以根据逆向设置的方法,将此关系表达式改变如下: a=5,a+b=10; 让程序的代码在语法上做一个很小的改动,从而引发预期的异常。 本节特别有针对性的选择了几种常见的异常情况,对其进行可发生故障的分析,特别对可能发生的故障设计了故障注入规则库,以确定原程序中的故障注入点以及故障注入的可选列表。 本小节主要针对常见的异常类型,例如:除数为0,数组边界值越界,关系表达式的符号判断条件等进行详细分析和归纳,以具体的示例来设计故障注入规则库,以解决故障注入的问题。 2.1.1 除数为0的示例 常见的异常类型中,除数为0是比较典型的,由于除数不能为0的原则,使得在这个判断原则的基础上,只要遇到除数为0,则引发除数为0的异常,使程序执行其所引发的异常语句。 2.1.2 If判断条件示例 我们以If条件中的关系表达式为例,其示如例图2所示: 图1 除数异常示例图 特别注意的是,判断条件的故障注入的可选列表的设计,我们是基于简单的程序变异,抽取出表达式符号后,根据断言违背或逆向设置等条件列出可以引发故障的注入条件,从而引发故障。 2.1.3 数组越界的示例 关于数组的异常判断,关键在于下标的边界值是否越界,按照数组边界值的定义,我们一般取两种情况来引发数组的异常:取一个下标的上界;取一个下标的下界。由于C#语言的数组下标的起始值为0,所以,在规则库的设计中,我们取下界为-1,上界为抽取出的数组的边界值。从而确定了针对一维数组的故障注入的两个可选择的条件。 我们根据第1节所介绍的几种软件故障注入方法,将相对应的异常程序分析整合,主要包括以下几种异常处理的测试: 1)if的条件判断所引发的异常 ① || 关系表达式 ②单一关系表达式(包括:= = , ! = ,> =, < =, >, <) ③布尔表达式(true、false) 2)除数为0所引发的异常 3)数组索引值越界 ①一元数组下标范围;②二元数组下标范围 图2 If判断条件注入示例图 4)调用系统函数所引发的异常 此测试用例的主要程序变异如下: 1)int[]a=new int[8]; a[4]=123; //数组边界值示例 一元数组边界值的范围为a[0]—a[7],所以引发异常的边界值越界主要有以下两种选择: ① a[-1]=123; ② a[8]=123 2)int nTheZero=10; int nResult=100/nTheZero; //判断除数为0示例 若要引发除数为0的异常,则要把变量nTheZero赋值0即可引发C#的标准异常类DivideByZeroException。 3)if(num= =99) //if的= =判断条件(自定义异常) throw new Exception(); 在本测试用例中,自定义异常为,当num值恒等于99时,抛出自定义的异常,输出“Game Over!”。 由于测试用例中num是一个随机的值,所以恒等于99的几率非常的小,我们改变“= =”的条件,以达到以满足引发异常的条件,如: ① num != 99 ; ② num > = 99 ;③num < = 99 ; ④ num > 99 ; ⑤ num < 99 ; 4)if(n<0) throw(new ArgumentOutOfRangeException()); //if的<判断条件 有以下几种可选择的注入条件: ①n = = 0 ; ② n > = 0 ; ③ n < = 0 ; ④ num > 0 ; ⑤ n ! = 0 ; 任意选择其中的一种条件,引发基本异常类ArgumentOutOfRangeException,从而执行相对应的异常处理语句,达到测试异常处理机制的目的。 10.3969/j.issn.1001-8972.2010.22.0521.2 在条件中插入真值的软件故障注入方法
1.3 逆向设置的软件故障注入方法
2.故障注入规则库的设计与生成
2.1 故障注入规则库的设计
2.2 故障注入规则库的生成与实现