本发明涉及软件测试领域,更具体地,涉及指针修改影响的分析方法和系统。
背景技术:
在计算机科学领域,指向分析是一种用于分析指针和内存引用所指向的变量或内存地址的静态代码分析技术。指向分析技术是很多更为复杂的代码分析技术的基础,例如编译优化、代码缺陷检测以及本文提到的指针修改影响分析。
steensgaard算法和andersen算法为两种公认的经典指向分析算法。steensgaard算法效率较高,其时间复杂度几乎是线性的,但精度低;andersen算法有较高的精度,但时间复杂度接近o(n3)。
指针修改影响分析技术能够反映程序中的由指针引起的跨函数定义使用关系,在编译优化、基于数据流的检测、增量静态语义分析等诸多领域被广泛使用。高效的指针修改分析技术在程序分析和编译领域都是十分必要的。
技术实现要素:
本发明提供一种克服上述问题或者至少部分地解决上述问题的指针修改影响的分析方法和系统。
根据本发明的一个方面,提供一种指针修改影响的分析方法,包括:
s1、在程序代码中查找该语句中变量的等价变量,并查找该等价变量所有的定义点,构成分析结果集合;
s2、基于定义点、语句以及程序入口的关系,获得对应该定义点的多个路径条件;以及
s3、判断所有所述路径条件是否可同时满足,若不可同时满足,则将该定义点从所述分析结果集合中剔除。
根据本发明的一个方面,还提供一种判断修改程序的指针是否造成影响的系统,包括:
初步判断模块,用于在程序代码中查找该语句中变量的等价变量,并查找该等价变量所有的定义点,构成分析结果集合;
结果集合模块,在程序代码中查找该语句中变量的等价变量,并查找该等价变量所有的定义点,构成分析结果集合;以及
再判断模块,判断所有所述路径条件是否可同时满足,若不可同时满足,则将该定义点从所述分析结果集合中剔除。
本申请提出一种指针修改影响的分析方法和系统。在传统指针修改影响分析算法的基础上,利用跨函数的多个条件计算,精化获得的结果,从而提高结果的精度,做到了部分路径敏感以及流敏感,使采用该分析算法的静态代码缺陷检测结果更加精确。
附图说明
图1为现有技术中示意图;
图2为根据本发明实施例中采用本发明所述方法的示例程序一的代码示意图;
图3为根据本发明实施例中采用本发明所述方法的示例程序一的控制流图;
图4为根据本发明实施例中采用本发明所述方法的示例程序一的超图;
图5为根据本发明实施例中采用本发明所述方法的示例程序一的指向图;
图6为根据本发明实施例中采用本发明所述方法的示例程序二的代码示意图;
图7为根据本发明实施例中采用本发明所述方法的示例程序二的控制流图;
图8为根据本发明实施例中采用本发明所述方法的示例程序二的超图;
图9为根据本发明实施例中采用本发明所述方法的示例程序二的指向图;
图10为根据本发明实施例中采用本发明所述方法的示例程序三的代码示意图;
图11为根据本发明实施例中采用本发明所述方法的示例程序三的控制流图;
图12为根据本发明实施例中采用本发明所述方法的示例程序三的超图;
图13为根据本发明实施例中采用本发明所述方法的示例程序三的指向图。
具体实施方式
下面结合附图和实施例,对本发明的具体实施方式作进一步详细描述。以下实施例用于说明本发明,但不用来限制本发明的范围。
图1示出了本发明提供的一种指针修改影响的分析方法,包括:
s1、在程序代码中查找该语句中变量的等价变量,并查找该等价变量所有的定义点,构成分析结果集合;
s2、基于定义点、语句以及程序入口的关系,获得对应该定义点的多个路径条件;以及
s3、判断所有所述路径条件是否可同时满足,若不可同时满足,则将该定义点从所述分析结果集合中剔除。
在一个实施例中,所述步骤s2包括:
从所述定义点至该语句的路径条件;
从所述定义点的程序的入口至所述定义点的路径条件;
从所述语句的程序的入口至该语句的路径条件;以及
从使不同变量产生等价关系的控制流语句的程序入口至该控制流语句的路径条件。
在一个实施例中,所述步骤s2进一步包括:所述步骤s2包括:从每一个路径条件的终点进行逆向递归搜索,获得从起点至终点间的所有路径,对具有相同路径的路径条件进行&&操作,再对不同路径的路径条件进行||操作,得到该条件;
其中,所述递归搜索在遇到起点、遇到覆盖起点的定义点或搜索到的语句没有前驱语句时停止。
对于第一条件,该条件的起点为定义点,终点为语句,对于第二条件,该条件的起点为定义点的程序的入口,终点为定义点,对于第三条件,该条件的起点为语句的程序的入口,终点为语句,对于第四条件,该条件的起点为所述控制流语句的程序入口,终点为控制流语句。
两个语句之间的条件示例:
在所述sg中,“intc=0”到“c++”的条件为“a>b”,“intc=0”到“c--”的条件为“!(a>b)”。
在一个实施例中,所述步骤s1包括:
s1.1、基于程序的控制流图cfg,分别获得静态单赋值形式的控制流图ssa_cfg和超图sg;
静态单赋值(staticsingle-assignment,ssa)是程序的一种中间表示,支持高效的数据流分析技术,每个变量名字在ssa形式的程序中只会被赋值一次。目前几乎所有的编译器,包括很多虚拟机、解释器中,都有ssa的应用。可满足性模理论(satisfiabilitymodulotheories)用于研究布尔表达式的可满足性问题,它是对多类型阶逻辑公式进行可满足性判定的理论。常量传播(constantpropagation)技术被应用于编译优化和代码静态分析领域当中,可将程序中能够计算出结果的变量替换为常量,用于计算程序中的控制流约束。
超图(supergraph)描述了程序跨函数控制流关系的有向图,可反映函数间的调用关系,也可在其中获取程序的数据流信息。
s1.2、对所述ssa_cfg进行指向分析,获得指针指向图pg,基于所述pg,获得语句中变量的等价信息;以及
s1.3、基于所述等价信息,在所述sg上进行正向数据流分析,获得指针修改产生的、初步判断为具有定义使用关系的定义点,构成分析结果集合;
其中,所述变量包括指针以及指针所指向的内存地址。
在一个实施例中,所述步骤s1.2包括对所述ssa_cfg中函数内的指向分析:
对于赋值语句a=&b,在所述pg中创建结点“a”、“&b”和“b”(若已存在则无需再创建),并使得结点“a”和“&b”均指向结点“b”,并在有向边上记录该指向产生的语句“a=&b”;
对于赋值语句“a=b;”,且a和b的类型皆为指针,则在所述pg中创建结点“a”和“b”,并使得结点“a”指向结点“b”所指向的所有结点,若“b”未指向任何结点,则创建结点“a=b”并使得该结点被结点“a”、“b”指向,并在有向边上记录该指向产生的语句“a=b”;
对于程序中的变量“*a”,在所述pg中创建结点“a”和“*a”,并使得结点“a”指向“*a”;以及
对于程序中的变量“&a”,在所述pg中创建结点“a”和“&a”,并使得结点“&a”指向“a”。
在一个实施例中,所述步骤s1.2还包括对所述ssa_cfg中函数间的指向分析:
基于函数调用语句“c”及其原型“d”,在所述pg中创建结点“c”和“d”,并使得“c”和“d”指向彼此所指向的结点,若二者均未指向任何结点,则创建结点“c=d”,并使得该结点被结点“c”、“d”指向,并在有向边上记录该指向产生的语句“c”。
在一个实施例中,所述步骤s1.2中的等价信息包括:
等价类指针,即指向同一个结点的指针;以及
等价类内存地址,即被同一个结点指向的内存地址。
在一个实施例中,所述步骤s1.3包括:
s1.3.1、基于所述sg,获得定义点、对应该定义点的被赋变量、使用点和对应该使用点的使用变量;以及
s1.3.2、对所述sg中的每一个语句,从所有定义点中搜索该语句的前驱语句对应的定义点,获得对应该语句的分析结果集合;
其中,所述定义点用于对语句中的被赋变量进行赋值,所述使用点用于对语句中的赋值变量进行使用。
以下列程序为例:
其中指针“a”和指针“b”为等价类,其等价关系由语句“b=a”产生,该程序将得到如下定义使用关系:
{*a=5}—>printf(“%d”,*b)。
在一个实施例中,当所述语句为赋值语句时,所述步骤s1.3还包括:
s1.3.3、从所述分析结果集合中删除对所述被赋变量或被赋变量的等价类进行定义的定义点,并将该赋值语句添加至所述分析结果集合中。
图2示出了采用本发明的示例程序一的代码示意图,本实施例以代码中第11行(*m)++为例,计算对该语句产生影响的别名修改位置,该语句对变量m进行解引用,所以需要考虑m及其等价类的相关定义点产生的影响。
首先构造示例程序一的控制流图和超图,图3示出了示例程序一的控制流图,图4示出了示例程序一的超图,
图4中每一个椭圆框代表一个语句,图中语句entry-g到语句*z=x之间需要满足条件:*x大于*y(语句switch*x>*y就是条件),在条件下面有两条边出去,带*的表示条件成立的时候执行的语句,带0的表示条件不成立的时候要执行的语句,如图可知,如果*x小于*y,entry-g就无法到达*z=x。
在这个程序里,得到的定义点是*z=null,使用点是(*m)++,需要计算四个条件:
1.*z=null到(*m)++的条件;
2.entry-g到*z=null的条件;
3、entry-f到(*m)++的条件;
4、entry-f到callg()的条件。
以计算*z=null到(*m)++的条件为例:当*x>*y时,会执行*z=x,导致*z被重新赋值,这样*z=null的赋值会被覆盖掉,所以首先要满足条件!(*x>*y);当*x<=*y时,会执行*z=y,导致*z被重新赋值,这样*z=null的赋值会被覆盖掉,所以首先要满足条件!(*x<=*y)。
通过指向分析,获得指针指向图,图5示出了示例程序一的指针指向图。
在指针指向图中计算,获取m等价类集合{m,*z}。
在supergraph上进行数据流分析,得到定义使用集合,在(*m)++位置,变量m的分析结果集合为{m=null},*z的分析结果集合为{*z=x,*z=y,*z=null}。在supergraph中,{m=null}到(*m)++之间的定义使用关系,必将被{*z=x,*z=y,*z=null}所覆盖,所以本步骤所得到的指针修改影响结果为{*z=x,*z=y,*z=null}。
计算条件,发现*z=null到(*m)++之间的条件为(!(*x>*y)&&!(*x<=*y)),经smtinterpol判定为不可满足,将其从结果集中删除,最终的指针修改影响结果为{*z=x,*z=y}。
*z=null到(*m)++之间的定义使用关系,在传统的代码静态分析过程中会被误认为是空指针解引用缺陷,而本算法所给出的结果则成功解决了这一问题。
图6示出了采用本发明的方法的示例程序二的代码示意图,本实施例以代码中第10行return*a为例,计算对该语句产生影响的别名修改位置,该语句对变量a进行解引用,所以需考虑*m及其等价类的相关定义点产生的影响。
首先构造示例程序二的控制流图和超图,图7示出了示例程序二的控制流图,图8示出了示例程序二的超图。
通过指向分析,获得指针指向图,图9示出了示例程序二的指针指向图。
在supergraph上进行数据流分析,得到定义使用集合,在printf语句位置,关于变量m的值得分析结果集合为{*m=10,*p=5},所以本步骤所得到指针修改影响结果为{*m=10,*n=9};
计算条件,发现m与*p产生等价关系的语句“m=n”和所计算语句printf语句在逻辑上不可同时被执行,语句执行的条件分别为“a==b”和“a>b”,而smtinterpol判定(a==b&&a>b)为不可满足,所以将*p相关从结果集中删除,最终的指针修改影响结果为{*m=10}。
图10示出了采用本发明的方法的示例程序三的代码示意图,本实施例以代码中第15行returnnum[b]为例,计算对该语句产生影响的别名修改位置,该语句使用变量b作为数组下标,考虑b及其等价类的相关定义点产生的修改影响,获取其数值范围。
首先构造示例程序三的控制流图和超图,图11示出了示例程序三的控制流图,图12示出了示例程序三的超图。
通过指向分析,获得指针指向图,图13示出了示例程序三的指针指向图。
在指针指向图中计算,变量b等价类集合{a,b,*m,*n}。
在supergraph上进行数据流分析,得到定义使用集合,可得在returnnum[b]位置,变量b的定义点集合为{*m=10,*n=9}。
计算条件,对于*m=10到returnnum[b]的定义使用关系进行计算:
*m=10到returnnum[b]的路径条件为true;
entry-f到returnnum[b]的路径条件为true;
entry-f到*m=10的路径条件为!(b>9);
entry-f到m=n的路径条件为b>9;
将四个路径条件进行&&操作,得到最终的条件为(b>9)&&!(b>9),经smt判定为不可满足,所以该定义使用关系不成立,将其从结果集中删除。
同理可得,*n=9到returnnum[b]的定义使用关系成立。
最终的指针修改影响结果为{*n=9}。
在一个实施例中,本发明还提供一种判断修改程序的指针是否造成影响的系统,包括:
初步判断模块,用于在程序代码中查找该语句中变量的等价变量,并查找该等价变量所有的定义点,构成分析结果集合;
结果集合模块,在程序代码中查找该语句中变量的等价变量,并查找该等价变量所有的定义点,构成分析结果集合;以及
再判断模块,判断所有所述路径条件是否可同时满足,若不可同时满足,则将该定义点从所述分析结果集合中剔除。
最后,本申请的方法仅为较佳的实施方案,并非用于限定本发明的保护范围。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。