基于静态分析的冗余代码缺陷检测方法

文档序号:6429736阅读:288来源:国知局
专利名称:基于静态分析的冗余代码缺陷检测方法
技术领域
本发明涉及计算机程序分析技术和计算机软件代码检测方法,具体涉及冗余代码检测方法。
背景技术
冗余代码缺陷检测是计算机软件开发和维护活动中一项重要的任务,在软件维护、软件缺陷检测、程序理解等多个领域中都有广泛的应用。程序中的冗余代码通常存在两种情况,一种是可达的,例如显式幂等操作、隐式幂等操作、冗余的赋值语句、冗余的函数参数等,另一些是不可达的,例如死代码、冗余的条件表达式等。冗余代码不仅影响软件的测试评估和运行效率,而且还存在潜在的安全隐患,并由此而引发语义和逻辑缺陷,而这些缺陷很难被已有的软件缺陷检测工具检测到。目前专门用来检测冗余代码及相关缺陷的方法和工具比较少,有文献报道的只有Yichen Xie和 Dawson Engler两位学者研究了用于检测显式幂等、冗余的赋值语句、死代码、冗余的条件表达式四种冗余代码的缺陷检查器,文中并未检测隐式幂等和冗余的函数参数,也没有给出检测其余四种冗余代码缺陷的具体解决方案。由于对冗余代码及相关缺陷的关注较少, 目前缺少成熟的对冗余代码及相关缺陷检测的方法。

发明内容
本发明的目的是为了解决目前缺少成熟的对冗余代码及相关缺陷检测的方法的问题,提供一种基于静态分析的冗余代码缺陷检测方法。基于静态分析的冗余代码缺陷检测方法,它包括具体步骤如下步骤1 输入待测试程序,将其解析为抽象语法树;步骤2 分析可能包含显式幂等操作的语句,检测显式幂等操作遍历程序的抽象语法树,对可能包含幂等操作的特定类型的抽象语法树子树进行处理,判断是否存在缺陷;步骤3 对局部定义的变量,采用过程内部分析方法,检测冗余的赋值语句在抽象语法树的基础上,跟踪每一个被赋值的变量,如果在函数结束之前或重新被赋值之前没有被使用,则判为缺陷;步骤4 遍历程序的抽象语法树,对每一个函数子树创建对应的程序依赖图PDG, 并将程序依赖图PDG进行选择结构、循环结构的标准化,在标准化后的程序依赖图PDG的基础上查找包含缺陷的结构,检测死代码;步骤5 在抽象语法树的基础上,分析程序的每条路径,计算赋值表达式和条件表达式的值,检测冗余的条件表达式遍历程序的抽象语法树,跟踪抽象语法树中的赋值语句、条件分支中的谓词集合、以及条件语句中的变量值的界限,来检测分支语句中冗余—— 总是真或总是假的条件表达式;步骤6 对程序的路径进行分析,检测隐式幂等操作遍历程序的抽象语法树,分析程序的每条路径,跟踪抽象语法树中的赋值语句,根据赋值语句维护一个等价类集合, 该集合记录值相等的变量;当具有相同值的变量之间互相赋值时,则判为存在隐式幂等缺陷;步骤7 对每个函数的参数,采用过程内部分析方法,检测冗余的函数参数在抽象语法树的基础上,采用过程内部分析方法,跟踪每一个函数参数,如果在函数结束之前或重新被赋值之前没有被使用,则判为存在冗余的函数参数缺陷;根据步骤2至7获得的六种缺陷的检测结果,给出缺陷检测报告。本发明的冗余代码缺陷检测方法能检测程序中显式幂等操作、冗余的赋值语句、 死代码、冗余的条件表达式、隐式幂等操作和冗余的函数参数,误检率和漏检率低于3%,适用于大规模程序代码的检测分析技术领域。


图1是本发明的方法的流程示意图,图2是本发明的方法所采用的基于抽象语法树的冗余的赋值语句检测模型示意图,图3是基于程序依赖图的死代码检测过程示意图, 图4为程序代码的if语句的示意图,图5是程序依赖图中if语句的标准化示意图,图6为程序代码的switch语句的示意图,图7是程序依赖图中switch语句的标准化示意图,图8 为程序代码的循环结构的示意图,图9是程序依赖图中循环结构的标准化示意图,图10是根据程序的每条路径,检测冗余的条件表达式示意图,图11是具体实施方式
一中所述检测冗余的条件表达式过程中,处理选择和循环结构分支的示意图,图12是基于路径分析的隐式幂等操作检测过程示意图,图13是具体实施方式
一中所述检测隐式幂等操作过程中,处理选择和循环结构分支的过程示意图。
具体实施例方式具体实施方式
一结合图1说明本实施方式,本实施方式包括的具体步骤如下步骤1 输入待测试程序,将其解析为抽象语法树;步骤2 分析可能包含显式幂等操作的语句,检测显式幂等操作遍历程序的抽象语法树,对可能包含幂等操作的特定类型的抽象语法树子树进行处理,判断是否存在缺陷;步骤3 对局部定义的变量,采用过程内部分析方法,检测冗余的赋值语句在抽象语法树的基础上,跟踪每一个被赋值的变量,如果在函数结束之前或重新被赋值之前没有被使用,则判为缺陷;步骤4 遍历程序的抽象语法树,对每一个函数子树创建对应的程序依赖图 (Program Dependence Graph, PDG),并将程序依赖图PDG进行选择结构、循环结构的标准化,在标准化后的程序依赖图PDG的基础上查找包含缺陷的结构,检测死代码;步骤5 在抽象语法树的基础上,分析程序的每条路径,计算赋值表达式和条件表达式的值,检测冗余的条件表达式遍历程序的抽象语法树,跟踪抽象语法树中的赋值语句、条件分支中的谓词集合、以及条件语句中的变量值的界限,来检测分支语句中冗余—— 总是真或总是假的条件表达式;步骤6 对程序的路径进行分析,检测隐式幂等操作遍历程序的抽象语法树,分析程序的每条路径,跟踪抽象语法树中的赋值语句,根据赋值语句维护一个等价类集合, 该集合记录值相等的变量;当具有相同值的变量之间互相赋值时,则判为存在隐式幂等缺陷;步骤7 对每个函数的参数,采用过程内部分析方法,检测冗余的函数参数在抽象语法树的基础上,采用过程内部分析方法,跟踪每一个函数参数,如果在函数结束之前或重新被赋值之前没有被使用,则判为存在冗余的函数参数缺陷;根据步骤2至7获得的六种缺陷的检测结果,给出缺陷检测报告。本发明的基本思想是首先对C源代码进行预处理,接着进行词法分析,将源代码转化为token流,并在token流的基础上进行struct标识符和typedef标识符分析;在上面两步的基础上,生成程序的抽象语法树,继而在抽象语法树的基础上采用不同的方法来检测六种冗余缺陷;步骤1 输入待测试程序,将其解析为抽象语法树;这里,首先对C源代码进行预处理,处理头文件包含、宏替换和条件编译,接着进行词法分析,词法分析将程序代码转换为能进行语法分析的token流,并在token流的基础上进行struct标识符和typedef标识符分析,语法分析生成程序的抽象语法树;步骤2 分析可能包含显式幂等操作的语句,查找显式幂等操作;显示幂等操作检测在抽象语法树的基础上,主要检测三种类型的显式幂等操作, 这三种显式幂等操作分别位于程序中的赋值语句、乘法表达式、“与”表达式和“或”表达式中;当程序转化为抽象语法树表示后,赋值语句、乘法表达式、“与”表达式和“或”表达式分别对应于抽象语法树中的某个子树,而且子树的根标识了该子树的类型;因此问题转化为对可能包含显式幂等操作的特定类型的抽象语法树子树进行处理,来判断是否存在缺陷, 对于遍历中遇到的其他类型的节点,则可以直接跳过对其子树的遍历;检测思路如下2-1、遍历程序的抽象语法树,对遍历的节点的类型进行判断;2-2、寻找可能包含显式幂等操作的子树的根节点AypeAssignExpr, typeMulExpr, typeAndExpr,typeInOrExpr ;当找到上述子树时,查找运算符,如果为‘ =’、‘/’、‘&’或‘ I,中的一个,则分别合
并该运算符所在节点的左右兄弟节点的内容,继而对合并后的两部分内容进行比较,如果相等则报告缺陷;步骤3 对局部定义的变量,采用过程内部分析方法,来判断是否存在冗余的赋值语句;结合图2具体说明冗余赋值语句检测规则3-1、从左到右先根遍历抽象语法树,提取全局变量;3-2、重新遍历抽象语法树,对遍历的节点的类型进行判断;3-3、当遍历到函数根节点时,提取函数参数和指针别名,并保存该函数子树的最后一个节点的指针;3-4、由于程序中的赋值表达式对应于抽象语法树中的赋值语句子树和初始化语句子树,因此在遍历的过程中首先寻找根节点类型为赋值语句类型或初始化语句类型的节点,该节点就是该赋值语句子树或初始化语句子树的根节点;
3-5、遍历该赋值语句子树或初始化语句子树,提取并保存被赋值的标识符,保存抽象语法树的断点位置,以便下次检测从此处开始,对该标识符进行一系列的判断(图2中虚线方框中的规则所示),如果其中有一个成立,则开始下一次的缺陷检测;否则继续遍历抽象语法树来判断保存该标识符在赋值后是否被使用;3-6、遍历后面的抽象语法树,分别针对不同节点类型的子树,采用不同的分析方法,来判断保存的标识符是否被使用(例如当遍历到if结构子树时,分析该子树,只要该if 结构中的一个分支中使用了保存的标识符,则认为该标识符被使用,此次赋值不是冗余的赋值语句),如果该标识符被使用,则跳转到保存的抽象语法树的断点位置,进行下一次的缺陷检测;3-7、上述的遍历判断中,当遍历到该标识符的重新赋值时,该标识符都没有被使用,则报告该缺陷;当遍历到函数结束时,如果不是全局变量,则报告该缺陷;跳转到保存的抽象语法树的断点位置,进行下一次的缺陷检测;重复上面的过程,直到遍历完整个的抽象语法树。步骤4 遍历程序的抽象语法树,对每一个函数子树创建对应的程序依赖图,并将程序依赖图进行选择结构、循环结构的标准化,继而在标准化后的程序依赖图的基础上查找包含缺陷的结构,查找死代码;死代码是由于程序中存在逻辑错误,导致不能执行到的一些代码片段,这些逻辑错误是由程序中的控制结构使用不当导致的;程序依赖图清晰的表示了程序的控制依赖关系,而且图中节点为语句或谓词,在不关心多数语句具体操作内容的情况下,极大的方便了死代码的检测;因此本发明在遍历抽象语法树的过程中,对遍历到的每个函数建立单独的程序依赖图,继而在该图上采用了“结构匹配”的方法,在程序依赖图中寻找包含死代码的错误控制结构;程序依赖图并没有统一的表示方法,为了消除程序表示的多样化,同时更方便对生成的程序依赖图的统一处理,分析程序依赖图的控制结构,本文对程序依赖图中的选择结构和循环结构进行了标准化。图4、图5对程序依赖图中的if结构子图进行了标准化。由if语句的条件表达式创建一个谓词节点,作为该子图的根节点,该谓词节点有两个孩子节点=TRUE分支节点和 FALSE分支节点。if结构体中的语句节点则相应的作为TRUE分支和FALSE分支节点的孩子节点。图6、图7对程序依赖图中的switch结构子图进行了标准化。由switch中的条件表达式创建一个谓词节点,作为该子图的根节点;由每个case语句的常量表达式创建谓词节点,作为该子图根节点的孩子节点,对于default语句,创建一个单独的谓词节点,也作为该子图根节点的孩子节点;每个case或default下的语句节点则作为相应谓词节点的孩子节点。图8、图9对程序依赖图中的循环语句结构子图进行了标准化。创建一个代表循环结构的谓词节点,作为该循环子图的根节点;循环体中的语句节点作为该子图根节点的孩子节点。图3为死代码缺陷的检测模型,具体检测规则为遍历程序的抽象语法树,对每一个函数子树创建对应的程序依赖图,接着遍历该CN 102231134 A
说明书
5/6页
程序依赖图,遍历中对程序依赖图中的节点类型进行判断,对选择结构子图、循环结构子图和包含跳转语句的子图进行进一步的分析,其他类型的子图中的节点则直接跳过,不再进行判断,对上面的三种子图,判断是否存在包含死代码的控制结构,如果存在,则报告缺陷。步骤5 在抽象语法树的基础上,分析程序的每条路径,计算赋值表达式和条件表达式的值,查找冗余的条件表达式;结合图10具体说明冗余的条件表达式检测规则遍历程序的抽象语法树,跟踪抽象语法树中的赋值语句、条件分支中的谓词集合、 以及条件语句中的变量值的界限,来检测分支语句中冗余(总是真或总是假)条件表达式。具体思路如下系统维护一个集合,该集合记录两方面的信息一、变量到整数常量的映射系统跟踪执行路径上的赋值,以及条件表达式来获得变量-常量绑定,用来判断后面的条件表达式的逻辑值;二、已知的谓词集合这些谓词在当前的路径上为真,随后使用它们来测试后面的控制谓词的有效性。在抽象语法树的基础上进行分析,对于每一个函数子树,具体的检测思路如下5-1、定义集合,用来保存已知的变量-常量,变量-表达式和条件表达式信息;5-2、跟踪所有被赋值的变量的值,保存已知的变量-常量信息;5-3、当遇到switch、if和while语句时,利用记录的变量-常量信息计算条件表达式的值,如果为永真或永假,则为冗余的条件表达式,报告该缺陷;如果该表达式不能计算,则分析该表达式,保存该表达式中包含的变量-常量信息;5-4、对于switch语句结构,删除集合中保存的在switch结构体中值被改变的变量的信息;5-5、对于if语句结构在进入if结构体之前保存集合副本;利用集合中已知的信息在if结构体内重复5-2之后的步骤;if语句结构分析结束后,删除集合副本中保存的在if结构体中值被改变的变量信息,该集合副本作为后面程序分析的已知信息集合,如图 11所示;5-6、对于循环结构对于while循环结构,则和if结构的分析过程类似;对于 do-while和for循环结构,则不分析其条件表达式,其他步骤和if结构的分析过程类似,如图11所示;直到函数周期结束。步骤6 对程序的路径进行分析,查找隐式幂等操作;结合图12具体说明查找隐式幂等操作规则遍历程序的抽象语法树,分析程序的每条路径,跟踪抽象语法树中的赋值语句来检测隐式幂等操作;具体思路如下系统跟踪每条执行路径上的赋值语句,根据赋值语句维护一个等价类集合,值相等的变量在同一个等价类中;当处于同一个等价类中的变量之间互相赋值时,报告缺陷;在抽象语法树的基础上进行分析,对于每一个函数子树,具体的检测思路如下6-1、定义等价类集合,用来保存已知的具有相同值的变量信息;6-2、跟踪所有被赋值的变量的值,判断是否为隐式幂等缺陷,如果该赋值语句赋值号两端的变量在同一个等价类中,则报告该缺陷,否则,保存已知的具有相同值的变量信息;6-3、对于选择语句和循环语句结构在进入选择结构体或循环结构体之前保存等价类集合副本;利用集合中已知的信息在选择结构体内或循环结构体内重复6-2之后的步骤;当该语句结构分析结束后,删除等价类集合副本中保存的在选择结构体中值被改变的变量信息,该等价类集合副本作为后面程序分析的已知信息集合,如图13所示;直到函数周期结束。步骤7 对每个函数的参数,采用过程内部分析方法,查找冗余的函数参数;冗余的函数参数检测在抽象语法树的基础上,对每一个函数的参数,采用过程内部分析方法,判断参数在函数结束之前或重新被赋值之前是否被使用过;检测思路如下7-1、从左到右先根遍历抽象语法树,提取全局变量;7-2、重新遍历抽象语法树,对遍历的节点的类型进行判断;7-3、当遍历到函数根节点时,提取函数参数和指针别名,并保存该函数子树的最后一个节点的指针;7-4、对函数的每个参数,遍历此函数的抽象抽象语法树子树,分别针对不同节点类型的子树,采用不同的分析方法,来判断该参数是否被使用(例如当遍历到if结构子树时,分析该子树,只要该if结构中的一个分支中使用了该参数,则认为该参数被使用,此参数不是冗余的函数参数),如果该参数被使用,则对下一个参数进行缺陷检测;7-5、上述的遍历判断中,当遍历到该参数的重新赋值时,该参数都没有被使用,则报告该缺陷;当遍历到函数结束时,如果该参数不是全局变量,则报告该缺陷,然后对下一个参数进行缺陷检测;重复上面的过程,直到遍历完整个的抽象语法树。根据步骤2至7获得的六种缺陷的检测结果,给出缺陷检测报告。
权利要求
1.基于静态分析的冗余代码缺陷检测方法,其特征是它包括的具体步骤如下 步骤1 输入待测试程序,将其解析为抽象语法树;步骤2 分析可能包含显式幂等操作的语句,检测显式幂等操作遍历程序的抽象语法树,对可能包含幂等操作的特定类型的抽象语法树子树进行处理,判断是否存在缺陷;步骤3 对局部定义的变量,采用过程内部分析方法,检测冗余的赋值语句在抽象语法树的基础上,跟踪每一个被赋值的变量,如果在函数结束之前或重新被赋值之前没有被使用,则判为缺陷;步骤4 遍历程序的抽象语法树,对每一个函数子树创建对应的程序依赖图PDG,并将程序依赖图PDG进行选择结构、循环结构的标准化,在标准化后的程序依赖图PDG的基础上查找包含缺陷的结构,检测死代码;步骤5 在抽象语法树的基础上,分析程序的每条路径,计算赋值表达式和条件表达式的值,检测冗余的条件表达式遍历程序的抽象语法树,跟踪抽象语法树中的赋值语句、条件分支中的谓词集合、以及条件语句中的变量值的界限,来检测分支语句中冗余——总是真或总是假的条件表达式;步骤6 对程序的路径进行分析,检测隐式幂等操作遍历程序的抽象语法树,分析程序的每条路径,跟踪抽象语法树中的赋值语句,根据赋值语句维护一个等价类集合,该集合记录值相等的变量;当具有相同值的变量之间互相赋值时,则判为存在隐式幂等缺陷;步骤7 对每个函数的参数,采用过程内部分析方法,检测冗余的函数参数在抽象语法树的基础上,采用过程内部分析方法,跟踪每一个函数参数,如果在函数结束之前或重新被赋值之前没有被使用,则判为存在冗余的函数参数缺陷;根据步骤2至7获得的六种缺陷的检测结果,给出缺陷检测报告。
2.根据权利要求1所述基于静态分析的冗余代码缺陷检测方法,其特征在于步骤4中的查找死代码采用了 “结构匹配”的方法,在程序依赖图中寻找包含死代码的错误控制结构。
全文摘要
基于静态分析的冗余代码缺陷检测方法,涉及基于静态分析的冗余代码缺陷检测方法,为了解决目前缺少成熟的对冗余代码及相关缺陷检测的方法的问题,它包括步骤1、输入待测试程序,将其解析为抽象语法树;步骤2、分析可能包含显式幂等操作的语句,检测显式幂等操作;步骤3、对局部定义的变量,采用过程内部分析方法,检测冗余的赋值语句;步骤4、遍历程序的抽象语法树,在标准化后的程序依赖图的基础上查找包含缺陷的结构,检测死代码;步骤5、检测冗余的条件表达式;步骤6、检测隐式幂等操作;步骤7、检测冗余的函数参数;根据步骤2至7获得的六种缺陷的检测结果,给出缺陷检测报告。本发明适用于大规模程序代码的分析。
文档编号G06F11/36GK102231134SQ201110216640
公开日2011年11月2日 申请日期2011年7月29日 优先权日2011年7月29日
发明者王甜甜, 苏小红, 逄龙, 马培军, 龚丹丹 申请人:哈尔滨工业大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1