CN105138335B - 一种基于控制流图的函数调用路径提取方法及装置 - Google Patents
一种基于控制流图的函数调用路径提取方法及装置 Download PDFInfo
- Publication number
- CN105138335B CN105138335B CN201510542043.7A CN201510542043A CN105138335B CN 105138335 B CN105138335 B CN 105138335B CN 201510542043 A CN201510542043 A CN 201510542043A CN 105138335 B CN105138335 B CN 105138335B
- Authority
- CN
- China
- Prior art keywords
- node
- function call
- controlling stream
- graph
- stream graph
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Expired - Fee Related
Links
Landscapes
- Devices For Executing Special Programs (AREA)
- Debugging And Monitoring (AREA)
Abstract
本发明公开了一种基于控制流图的函数调用路径提取方法及装置,所述方法包括:对源代码进行处理,获得包含控制流消息的中间代码;将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;根据所述控制流图中每一个节点包含的函数调用的个数的对控制流图进行处理,将控制流图转换成函数调用关系图;以及根据所述函数调用关系图提取出函数调用路径。本发明可以简化函数调用路径的分析过程,并且更容易获取准确的函数调用路径。
Description
技术领域
本发明涉及软件测试技术领域,具体地,涉及一种基于控制流图的函数调用路径提取方法及装置。
背景技术
函数调用路径是一个由程序入口点到出口点的函数名序列,其将控制逻辑与函数调用相结合,并把代码分析粒度从语句扩展到函数。
一个程序会因为含有判定条件的选择语句和控制语句而产生多条函数调用路径。在程序设计中,源代码中有顺序、选择、循环三种语句结构。顺序语句不增加函数调用路径的条数,只有选择语句和循环语句才可能产生更多的程序分支。以C语言为例,关键字if,for,while,switch将会产生多条执行语句。所以,这些能够产生分支的关键字是提取函数调用关系图的关注点。
目前,提取函数调用路径的方法主要分为两种,一种是通过静态分析工具分析源代码,提取程序中的方法调用和模块之间的交互信息,确定模块之间的控制流的转向,使用自动机或者其他手段建立函数调用关系图,进而提取函数调用路径。静态分析是指在不需要执行源代码的条件下对源代码进行分析,与动态分析是相对的,动态分析是在执行源代码的条件下对源代码进行分析。
另一种更直观地提取函数调用路径的方法是程序插装法,即通过在源代码或汇编代码中插入设计好的探针函数,在程序再次执行时,即可收集到进入函数以及退出函数的插装信息,基于这些插装信息,可以获得程序的控制流的等信息,进而提取函数调用路径。其中,可以使用装点流拆分算法或其他算法实现函数调用路径的提取工作。目前,在软件自动化测试领域中,目标代码插装和源代码插装是主流的插装研究技术,但是动态插装方法的完整性依赖于测试用例的选取,如果测试用例选取不全,会导致测试过程不充分。
因此,在现有技术中提取函数调用路径的方法的基础上,为了保证函数调用路径提取的准确性以及简化函数调用路径的分析过程,提出新的提取函数调用路径的方案是非常有必要的。
发明内容
本发明所要解决的技术问题是提供一种基于控制流图的函数调用路径提取方法及装置,其目的在于使函数调用路径的提取更为简单准确。
本发明解决上述技术问题的技术方案如下:一种基于控制流图的函数调用路径提取方法,包括:对源代码进行处理,获得包含控制流消息的中间代码;将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;根据所述控制流图中每一个节点包含的函数调用的个数的对控制流图进行处理,将控制流图转换成函数调用关系图;以及根据所述函数调用关系图提取出函数调用路径。
优选地,所述对源代码进行处理,获得包含控制流消息的中间代码,包括:基于gcc编译器对源代码进行处理,获得包含控制流消息的GCC-GFG中间代码。
优选地,将所述中间代码转换为控制流图,包括:采用pattern-action模式对所述中间代码进行静态分析,将所述中间代码转换为控制流图;其中,pattern-action模式中的pattern是指采用规则匹配,action是指当匹配到指定规则的代码串后,执行该代码串的相关动作。
优选地,所述规则匹配包括函数声明匹配、基本代码块匹配、goto语句匹配和函数调用匹配。
优选地,所述根据所述控制流图中每一个节点包含的函数调用的个数的对控制流图进行处理,将控制流图转换成函数调用关系图,包括:对所述控制流图中每一个节点包含的函数调用的个数进行分类,分为没有函数调用、函数调用个数仅有一个和函数调用个数大于一个;对于没有函数调用的节点,删除该节点或者将该节点与其上层节点或下层节点进行合并;对于函数调用个数仅有一个的节点,将该节点名称重命名为函数名称;对于函数调用个数大于一个的节点,为该节点的每个函数调用创建一个新节点,并按顺序连接创建的新节点,再删除该节点,并使该节点的上层节点指向按顺序连接的新节点中的第一个节点,而按顺序连接的新节点中最后一个节点则指向该节点的下层节点;以及根据对没有函数调用的节点、函数调用个数仅有一个的节点和函数调用个数大于一个的节点的处理结果,基于选定的数据结构将控制流图转换成函数调用关系图。
本发明的技术方案还提供了一种基于控制流图的函数调用路径提取装置,包括:中间代码获取模块,用于对源代码进行处理,获得包含控制流消息的中间代码;控制流图获取模块,用于将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;函数调用关系图获取模块,用于根据所述控制流图中每一个节点包含的函数调用的个数的对控制流图进行处理,将控制流图转换成函数调用关系图;以及函数调用路径获取模块,用于根据所述函数调用关系图提取出函数调用路径。
优选地,所述对中间代码获取模块中包括gcc编译器模块,其用于对源代码进行处理,获得包含控制流消息的GCC-GFG中间代码。
优选地,所述控制流程图获取模块将所述中间代码转换为控制流图,具体包括:采用pattern-action模式对所述中间代码进行静态分析,将所述中间代码转换为控制流图;其中,pattern-action模式中的pattern是指采用规则匹配,action是指当匹配到指定规则的代码串后,执行该代码串的相关动作。
优选地,所述规则匹配包括函数声明匹配、基本代码块匹配、goto语句匹配和函数调用匹配。
优选地,所述函数调用关系图获取模块包括:
分类模块,用于对所述控制流图中每一个节点包含的函数调用的个数进行分类,分为没有函数调用、函数调用个数仅有一个和函数调用个数大于一个;
处理模块,用于根据所述分类模块的分析结果对各节点进行处理,包括:
对于没有函数调用的节点,删除该节点或者将该节点与其上层节点或下层节点进行合并;
对于函数调用个数仅有一个的节点,将该节点名称重命名为函数名称;
对于函数调用个数大于一个的节点,为该节点的每个函数调用创建一个新节点,并按顺序连接创建的新节点,再删除该节点,并使该节点的上层节点指向按顺序连接的新节点中的第一个节点,而按顺序连接的新节点中最后一个节点则指向该节点的下层节点;以及
转换模块,用于根据所述处理模块的处理结果,基于选定的数据结构将控制流图转换成函数调用关系图。
本发明的有益效果是:本发明可以简化函数调用路径的分析过程,并且更容易获取准确的函数调用路径。
本发明的其他优点和有益效果将在具体实施方式中进一步说明。
附图说明
图1为本发明实施例中基于控制流图的函数调用路径提取方法的流程示意图;
图2为本发明实施例中包含if语句的分析示例的示意图;
图3为本发明实施例中if条件语句执行完成后直接return的分析示例的示意图;
图4为本发明实施例中包含for语句的分析示例的示意图;
图5为本发明实施例中使用while循环实现与图4相同功能的分析示例的示意图;
图6为本发明实施例中根据规则P1-P6提取函数控制流图的流程示意图;
图7为本发明实施例中将控制流图转换成函数调用关系图的流程示意图;
图8(a)-图8(d)为本发明实施例中无函数调用的节点的四种情况的示意图;
图9为本发明实施例中控制流图的数据存储格式的示意图;
图10为本发明实施例中基于控制流图的函数调用路径提取装置的流程示意图;
图11为本发明实施例中应用例一的选择循环嵌套函数的代码分析过程的示意图;
图12为本发明实施例中应用例一的控制流图与函数调用图的比较示意图;
图13(a)-图13(b)为本发明实施例中应用例二的含三目运算符递归函数示例代码分析过程的示意图;
图14(a)-图14(d)分别为本发明实施例中应用例二的main函数控制流图、fib函数控制流图、fib函数的函数调用路径图、全局函数调用路径图。
具体实施方式
以下结合附图对本发明的原理和特征进行描述,所举实例只用于解释本发明,并非用于限定本发明的范围。
本发明的实施例提出了一种基于控制流图的函数调用路径提取方法,如图1所示,具体步骤包括:
S100,对源代码进行处理,获得包含控制流消息的中间代码;
S200,将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;
S300,根据所述控制流图中每一个节点包含的函数调用的个数的对控制流图进行处理,将控制流图转换成函数调用关系图;以及
S400,根据所述函数调用关系图提取出函数调用路径。
对于步骤S100,具体的实施方法为:基于gcc编译器对源代码进行处理,获得包含控制流消息的GCC-GFG中间代码。
gcc是一款强大的C语言编译器,包含了大量的功能选项用于控制编译链接的过程,其中“-fdump-tree”选项可以获取gcc对源代码的预处理信息,选择其中合适的子选项,gcc可以生成格式合适、准确的中间调试信息。“cfg”子选项可以生成类控制流图的中间代码。现对一些简单代码进行示例分析,其中包含if语句的分析示例,如图2所示;if条件语句执行完成后直接return的分析示例,如图3所示。
从图2中可以看出中间代码分为两部分:函数声明和函数体,将此格式的中间代码称为GCC-CFG中间代码。其中,函数声明部分包含了gcc内部的函数索引号信息,对于函数的控制流图的获取用处不大;函数体部分是对源代码进行预处理后的结果,是对源代码分块的表示方法,将整个代码分为简单的代码块,代码块内部代码顺序执行,或者根据goto语句跳到另外一个代码块。其中<bb>模块表示基本代码块basic block,同时gcc在分析代码的过程中可能会合并一部分代码,导致一部分代码块存在两个或更多的名字。基本代码块中的goto语句反映了代码块之间的执行顺序,根据goto语句可以将代码块之间的执行顺序表示出来。通过对GCC-CFG中间代码进行静态分析即可以得到图2、图3中右侧的控制流图。
包含for语句的分析示例如图4所示,另外使用whi le循环实现与图4相同功能的示例代码如图5所示。两个循环示例代码分别使用for和while实现了完全相同的功能,通过gcc得到的GCC-CFG中间代码也是完全相同的,将其绘制成控制流图显示结果一致。
对于步骤S200,由于GCC-CFG中间代码有明显标志性语句,本实施例采用一种pattern-action模式对该GCC-CFG中间代码进行静态分析。其中,pattern是指一种规则匹配,action是当匹配到指定规则的代码串(或称为token)后,执行该代码的相关动作。对于GCC-CFG中间代码而言,主要匹配的pattern部分为函数声明、基本代码块<bb*>以及跳转语句goto。
pattern表示的规则匹配的列表如表1所示:
表1
序号 | 规则 | 说明 |
P1 | ([;][;][]Function)[][_a-zA-Z]*[a-zA-Z0 | 匹配函数声明 |
P2 | \<bb[][0-9]+\> | 匹配bb代码块开始 |
P3 | \<L[0-9]+\> | 匹配L代码块 |
P4 | ((goto)[]\<bb[][0-9]+\>) | 匹配goto语句,连接语句 |
P5 | ((goto)[]\<bb[][0-9]+\>)[]\(\<L[0-9]+ | 匹配特殊格式goto语句 |
P6 | ([_a-zA-Z]*[a-zA-Z0-9][][\(]) | 匹配函数调用 |
表1中共有6种规则,左侧为规则编号,中间为该规则的类正则表达式,右侧为规则说明。控制流图的提取需要寻找3个关键内容:函数声明、基本代码块、跳转语句。在控制流图提取中,是以函数为处理单元的一个函数的控制流图。因此,如图6所示,根据规则P1-P6提取函数控制流图的步骤如下:
S201,根据P1规则,匹配在GCC-CFG中间代码中的函数定义,从而开启一个处理单元。
S202,根据P2和P3规则用于匹配代码段的开始。在一个函数内部,控制流图的每一个节点代表一个基本代码段,基本代码段在GCC-CFG中间代码中是以<bb*>或者<L*>形式表示的。
S203,根据P4和P5匹配goto语句。在函数内部,控制流图的每一条边表示了一条跳转语句。在GCC-CFG中间代码中,产生跳转有两种情况:一种是在一个代码块内没有任何跳转语句,所以按照执行顺序进入下一个紧挨的代码块或者结束,此时产生一条顺序执行的edge;另一种是在代码块内有跳转语句,也就是goto语句,每条goto语句都会产生一条跳转,生成一条edge。
S204,根据P6来匹配函数调用,并且按照顺序将函数调用保留在控制流图的节点中。
通过以上步骤S201-S203可以获取控制流图的全部内容,然而为了生成函数调用关系图,控制流图中的每一个节点需要更多的辅助信息用于生成函数调用关系图。控制流图和函数调用关系图的一点区别在于节点所表示的内容不同,控制流图节点表示一个代码段,函数调用关系图节点表示一个函数。为了能够将控制流图转换为函数调用关系图,需要在提取控制流图时,将每一个基本代码块中的函数调用信息保留在每一个节点中。从图2-图5中可以看出,在代码块内部,函数调用是非常简单的顺序调用,在代码块内没有复杂的跳转。所以在获取控制流图的时候需要执行步骤S204,根据P6来匹配函数调用,并且按照顺序将函数调用保留在控制流图的节点中。
在匹配到不同的规则后需要执行不同的action。在匹配到P1后,需要执行初始化操作,更新函数个数、节点个数、边个数等计数器值;在匹配到P2或者P3后,需要处理上一个代码块的信息,按照需要的格式输出节点信息包括该节点内的函数调用信息,最后更新与代码块相关的值;在匹配到P4或者P5后,需要设置is_bb_with_goto,即本节点是否包含跳转,用于辅助主程序判断是否连接当前节点与下一个节点,然后生成连接本节点与goto所指向的节点的边;在匹配到P6后,需要存储相应的函数调用信息。
根据以上分析,控制流图的提取算法如表2所示:
表2
在表2所示的算法中,针对函数和代码块声明了一些计数器。其中,使用fun_num、node_num、edge_num分别记录函数的个数、某一个函数中节点的个数、边的个数;使用is_bb_with_goto、is_bb_with_function、called_functions分别用来记录代码块是否包含goto语句、代码块是否包含函数调用、包含了那些函数调用;yytext是指根据规则匹配到的名称。并且根据需要定义print_node和print_edge用于生成或者输出指定格式的控制流图,如在内存中生成邻接表或者生成结构化文档(XML,JSON格式)存储到硬盘上。
对于步骤S300,如图7所示,包括:
S301,对所述控制流图中每一个节点包含的函数调用的个数进行分类,分为没有函数调用、函数调用个数仅有一个和函数调用个数大于一个。
S302,根据分类不同,对节点进行不同的处理。
首先,分析没有函数调用的代码块。在控制流图转为函数调用关系图的过程中,如果代码块中没有函数调用,一般可以采取删除该节点的方式,比如在图2中,代码块<bb 2>中没有包含任何的函数调用,同时只有一个节点指向该代码块,所以此时删除该节点或者称为将该节点“向上合并”是正确的。然而在一种特殊的情况下,一个控制流图节点指向多个节点,同时存在多个节点指向该节点,此时该节点是不能删除的。为了更细化的分析无函数调用情况,根据控制流图节点入度和出度的不同,将无函数调用的节点分为如图8(a)-图8(d)所示的4种情况。
对于图8(a)-图8(c)所示的3种情况,可以采用“合并”的策略。合并操作分为“向上合并”和“向下合并”两种。向上合并是指该节点的相关信息与该节点的上层信息合并,向下合并与之相反,下面通过示例进行说明。
向上合并操作:被合并节点为N1,上层节点为N0,下层节点为一个或多个表示为N2s,合并操作为删除N0指向N1的边,同时N0指向所有的N2s,最后删除节点N1。
向下合并操作:被合并节点为N1,上层节点为一个或者多个表示为N0s,下层节点为N2,合并操作为删除N1指向N2的边,同时所有的N0s指向N2,最后删除节点N1。
对于图8(a)的情况可以采用任意一种合并操作,最终结果是一样的,对于图8(b)的情况,只能执行向上合并操作,对于图8(c)的情况只能执行向下合并操作。对于图8(d)的情况,该节点可以采用两种方法处理,一是删除该节点,二是执行向上合并和向下合并两个操作。如果保留该节点,那么需要对该节点指定一个特殊的名称,表示该节点不是一个函数。因此,第一种方法适合获取函数调用路径,第二种方法适合程序员分析阅读,使调用关系图更简洁清晰。
其次,对于函数调用个数仅有一个的节点,将该节点名称重命名为函数名称,即直接替换节点名称,将原来的<bb*>或者<L*>节点名称重命名为函数名称。
最后,对于函数调用个数大于一个的节点,为该节点的每个函数调用创建一个新节点,并按顺序连接创建的新节点,再删除该节点,并使该节点的上层节点指向按顺序连接的新节点中的第一个节点,而按顺序连接的新节点中最后一个节点则指向该节点的下层节点。这种方法可称为“分裂”操作,比如控制流图中的一个节点N1包含函数调用Funs(f1,f2,…,fn),上层节点(一个或多个)表示为N0s,下层节点(一个或多个)表示为N2s,分裂操作为:先为Funs中的每一个函数创建一个节点(如果该函数节点已经存在,则无需重新创建),并按顺序连接这些节点;再删除N0指向N1的边,同时N0指向f1;最后,将fn指向节点N1。
步骤303,根据对没有函数调用的节点、函数调用个数仅有一个的节点和函数调用个数大于一个的节点的处理结果,基于选定的数据结构将控制流图转换成函数调用关系图。
本实施例选定的数据结构优选为json格式,采用json格式存储分析得到的控制流图。json是一种轻量级的数据交换格式,其数据的书写格式是key:value对,其中value可以是数值、字符串或者数组。本实施例中需要多个单独的工具配合使用,所以使用json持久化数据,方便不同程序对分析结果的处理。在图9中,左侧代码为一个C语言版本的mysql数据库调用程序中的初始化程序,中间为其GCC-CFG格式的中间代码,右侧为json格式的CFG数据。
本实施例中,json的数据格式为:functions对应函数数组,数组中的每一个成员表示一个函数的控制流图信息,包括funciton_name和tokens;function_name表示函数的名字;tokens表示该函数对应的控制流图的信息,包括node节点以及edge边;node中包含节点名称node_name以及该节点包含的函数调用数组called_functions,edge中包括控制流图中一条边的连接起点节点begin与终点节点end。
针对以上数据结构,本实施例中控制流图转为函数调用关系图的算法如表3所示,其中输入为控制流图,输出为函数调用关系图,在表3的算法中,以函数为基本单位对控制流图分析每一个token,按照转换规则执行合并、重命名或者拆分操作。与上述分析有一点不同,在表3的算法中分析了在节点不包含任何函数调用的情况下as_end_node为零或者as_begin_node为零时不做任何处理的操作。因为当以上条件成立时,该节点为开始节点或者是结束节点,所以可以不做任何处理。
表3
对于步骤S400,根据所述函数调用关系图提取出函数调用路径。本领域中,对于从函数调用图到函数调用路径的转换已经有了很多相关技术,可采用的一种简单的方法为计算从开始节点到结束节点之间的可达路径,得到的每一条路径即为函数调用路径。
本实施例还提出了一种基于控制流图的函数调用路径提取装置,该函数调用路径提取装置的具体实施步骤与上述的函数调用路径提取方法类似,故不再累述。
如图10所示,本实施例的函数调用路径提取装置包括:
中间代码获取模块500,用于对源代码进行处理,获得包含控制流消息的中间代码;
控制流图获取模块600,用于将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;
函数调用关系图获取模块700,用于根据所述控制流图中每一个节点包含的函数调用的个数的对控制流图进行处理,将控制流图转换成函数调用关系图;以及
函数调用路径获取模块800,用于根据所述函数调用关系图提取出函数调用路径。
进一步地,所述对中间代码获取模块500中包括gcc编译器模块501,其用于对源代码进行处理,获得包含控制流消息的GCC-GFG中间代码。
进一步地,所述控制流程图获取模块将所述中间代码转换为控制流图,具体包括:采用pattern-action模式对所述中间代码进行静态分析,将所述中间代码转换为控制流图。
进一步地,所述函数调用关系图获取模块700包括:
分类模块701,用于对所述控制流图中每一个节点包含的函数调用的个数进行分类,分为没有函数调用、函数调用个数仅有一个和函数调用个数大于一个。
处理模块702,用于根据所述分类模块的分析结果对各节点进行处理,包括:对于没有函数调用的节点,删除该节点或者将该节点与其上层节点或下层节点进行合并;对于函数调用个数仅有一个的节点,将该节点名称重命名为函数名称;对于函数调用个数大于一个的节点,为该节点的每个函数调用创建一个新节点,并按顺序连接创建的新节点,再删除该节点,并使该节点的上层节点指向按顺序连接的新节点中的第一个节点,而按顺序连接的新节点中最后一个节点则指向该节点的下层节点。
转换模块703,用于根据所述处理模块的处理结果,基于选定的数据结构将控制流图转换成函数调用关系图。
本实施例的函数调用路径提取方法及装置是有效的,可以简化函数调用路径的分析过程,并且更容易获取准确的函数调用路径。下面通过两个应用例进一步验证本实施例的函数调用路径提取方法及装置的效果。
应用例一
图11中的左侧部分为选择语句和循环语句嵌套使用的实验源代码,程序定义了两个变量作为程序中不同分支的判断条件,在获取到这两个变量后,根据变量的值进入while循环,然后确定要执行的函数,在一次循环中只有一个函数会执行,并且一旦执行f2就会跳出循环。该程序代码因为变量值的不同会执行不同的函数,因此会对应多条函数调用路径。
源代码在经过gcc编译器处理后,生成如图11中的中间部分所示的GCC-CFG中间代码。Gcc编译器对源代码进行了优化,声明了多个变量优化代码的执行效率,并且没有影响程序的控制逻辑。然后对该中间代码进行静态分析,通过表2的控制流图提取算法,将中间代码转换为图11中的右侧部分的json格式的控制流图,共11个节点,12条边。然后通过graphviz画出控制流图,如图12的左侧部分所示。
采用表3的CFG2FCG算法将图12的左侧部分的控制流图转化为右侧部分的函数调用关系图。在9个节点中,只有<bb 4>和<bb 5>包含函数调用,并且只包含一个函数调用,所以执行了rename操作(<bb 2>包含的函数调用scanf是库函数,没有在实验代码中声明实现,在CFG2FCG过程中忽略该函数调用);其他节点不包含函数调用,在做完合并操作后删除。最后,计算从main到end的可达路径为5条,详细情况见表4。
表4
通过分析5条函数调用路径,可以得到表4右侧变量的取值情况。不进入循环时执行第1条路径;进入循环后执行else语句,生成第2条路径;进入循环执行后,if判断为真后调用f1,然后再次进入循环体执行f2,生成第3条路径;进入循环后多次执行f1,然后执行f2生成第4条路径;进入循环后,只执行了一次f1,然后退出循环,生成第5条路径。
通过该应用例一,可知提取出的函数调用路径与人工分析的预期一致,表明基于控制流图的函数调用路径提取方法,在本发明的实施例中可以正确提取函数的调用路径获取程序的结构信息。
应用例二
图13(a)的左侧上部分为使用三目运算符实现的Fibonacci Sequence函数源代码,以及通过循环多次调用该函数的主函数。源代码在经过gcc处理后,生成GCC-CFG中间代码,其中图13(a)的左侧下部分为main函数的中间部分,图13(a)的右侧部分为fib函数的中间部分。同样,gcc对源代码进行了优化,声明了多个变量优化代码的执行效率,并且不影响程序的控制逻辑。
main函数在循环体内调用fib函数,其函数调用关系应该是fib指向自己,执行多次。fib函数在函数内部递归调用自己,其函数调用关系同样应为fib指向自己。
静态分析中间代码获取json格式的控制流图,如图13(b)所示。通过graphviz画出函数的控制流图,main函数的控制流图如图14(a)所示,fib函数的控制流图如图14(b)所示。
使用表3中的CFG2FCG算法将控制流图转化为函数调用图,同样main函数中的<bb3>的scanf是库函数,没有在实验代码中声明实现,在CFG2FCG过程中忽略该函数调用。main函数与fib函数有相同的函数调用路径图如图14(c)所示,与之前的人工分析一致。生成的全局函数调用图14(d)所示,此函数调用关系图比较简单,不再列表分析。从main到end的函数调用路径一共是三条:main→end、main→fib→end、
该应用例二可以提取通过静态分析得到的不可达路径。在该应用例中,由于i值的取值是事先确定的,其函数调用路径也是确定的,即上述分析中的第三条路径。根据静态分析的特点,可以发现函数执行过程中所有可能的函数调用路径。该特点可以应用到安全领域,发现可能会被黑客利用的不可达路径。在动态分析中将不会产生这样的问题,动态分析只会发现在设计好的测试用例中一定会执行的函数调用路径。
以上结合附图详细描述了本发明的优选实施方式,但是,本发明并不限于上述实施方式中的具体细节,在本发明的技术构思范围内,可以对本发明的技术方案进行多种简单变型,这些简单变型均属于本发明的保护范围。
另外需要说明的是,在上述具体实施方式中所描述的各个具体技术特征,在不矛盾的情况下,可以通过任何合适的方式进行组合,为了避免不必要的重复,本发明对各种可能的组合方式不再另行说明。
此外,本发明的各种不同的实施方式之间也可以进行任意组合,只要其不违背本发明的思想,其同样应当视为本发明所公开的内容。
Claims (8)
1.一种基于控制流图的函数调用路径提取方法,其特征在于,包括:对源代码进行处理,获得包含控制流消息的中间代码;将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;根据所述控制流图中每一个节点包含的函数调用的个数对控制流图进行处理,将控制流图转换成函数调用关系图;以及根据所述函数调用关系图提取出函数调用路径;所述根据所述控制流图中每一个节点包含的函数调用的个数对控制流图进行处理,将控制流图转换成函数调用关系图,包括:对所述控制流图中每一个节点包含的函数调用的个数进行分类,分为没有函数调用、函数调用个数仅有一个和函数调用个数大于一个;对于没有函数调用的节点,删除该节点或者将该节点与其上层节点或下层节点进行合并;对于函数调用个数仅有一个的节点,将该节点的名称重命名为函数名称;对于函数调用个数大于一个的节点,为该节点的每个函数调用创建一个新节点,并按顺序连接创建的新节点,再删除该节点,并使该节点的上层节点指向按顺序连接的新节点中的第一个节点,而按顺序连接的新节点中最后一个节点则指向该节点的下层节点;以及根据对没有函数调用的节点、函数调用个数仅有一个的节点和函数调用个数大于一个的节点的处理结果,基于选定的数据结构将控制流图转换成函数调用关系图。
2.根据权利要求1所述的函数调用路径提取方法,其特征在于,所述对源代码进行处理,获得包含控制流消息的中间代码,包括:基于gcc编译器对源代码进行处理,获得包含控制流消息的GCC-GFG中间代码。
3.根据权利要求1或2所述的函数调用路径提取方法,其特征在于,将所述中间代码转换为控制流图,包括:采用pattern-action模式对所述中间代码进行静态分析,将所述中间代码转换为控制流图;其中,pattern-action模式中的pattern是指采用规则匹配,action是指当匹配到指定规则的代码串后,执行该代码串的相关动作。
4.根据权利要求3所述的函数调用路径提取方法,其特征在于,所述规则匹配包括函数声明匹配、基本代码块匹配、goto语句匹配和函数调用匹配。
5.一种基于控制流图的函数调用路径提取装置,其特征在于,包括:中间代码获取模块,用于对源代码进行处理,获得包含控制流消息的中间代码;控制流图获取模块,用于将所述中间代码转换为控制流图,并将函数调用保留在所述控制流图的节点中;函数调用关系图获取模块,用于根据所述控制流图中每一个节点包含的函数调用的个数对控制流图进行处理,将控制流图转换成函数调用关系图;以及函数调用路径获取模块,用于根据所述函数调用关系图提取出函数调用路径;所述函数调用关系图获取模块包括:分类模块,用于对所述控制流图中每一个节点包含的函数调用的个数进行分类,分为没有函数调用、函数调用个数仅有一个和函数调用个数大于一个;处理模块,用于根据所述分类模块的分析结果对各节点进行处理,包括:对于没有函数调用的节点,删除该节点或者将该节点与其上层节点或下层节点进行合并;对于函数调用个数仅有一个的节点,将该节点的名称重命名为函数名称;对于函数调用个数大于一个的节点,为该节点的每个函数调用创建一个新节点,并按顺序连接创建的新节点,再删除该节点,并使该节点的上层节点指向按顺序连接的新节点中的第一个节点,而按顺序连接的新节点中最后一个节点则指向该节点的下层节点;以及转换模块,用于根据所述处理模块的处理结果,基于选定的数据结构将控制流图转换成函数调用关系图。
6.根据权利要求5所述的函数调用路径提取装置,其特征在于,所述中间代码获取模块中包括gcc编译器模块,其用于对源代码进行处理,获得包含控制流消息的GCC-GFG中间代码。
7.根据权利要求5或6所述的函数调用路径提取装置,其特征在于,所述控制流程图获取模块将所述中间代码转换为控制流图,具体包括:采用pattern-action模式对所述中间代码进行静态分析,将所述中间代码转换为控制流图;其中,pattern-action模式中的pattern是指采用规则匹配,action是指当匹配到指定 规则的代码串后,执行该代码串的相关动作。
8.根据权利要求7所述的函数调用路径提取装置,其特征在于,所述规则匹配包括函数声明匹配、基本代码块匹配、goto语句匹配和函数调用匹配。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510542043.7A CN105138335B (zh) | 2015-08-28 | 2015-08-28 | 一种基于控制流图的函数调用路径提取方法及装置 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201510542043.7A CN105138335B (zh) | 2015-08-28 | 2015-08-28 | 一种基于控制流图的函数调用路径提取方法及装置 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN105138335A CN105138335A (zh) | 2015-12-09 |
CN105138335B true CN105138335B (zh) | 2018-01-23 |
Family
ID=54723693
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201510542043.7A Expired - Fee Related CN105138335B (zh) | 2015-08-28 | 2015-08-28 | 一种基于控制流图的函数调用路径提取方法及装置 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN105138335B (zh) |
Families Citing this family (13)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN106020848A (zh) * | 2016-06-07 | 2016-10-12 | 北京信息科技大学 | 面向c#的函数调用路径生成方法 |
CN106021116B (zh) * | 2016-06-07 | 2018-07-13 | 北京信息科技大学 | 复杂系统中不可达函数调用路径检测方法 |
CN106227573A (zh) * | 2016-07-11 | 2016-12-14 | 北京信息科技大学 | 基于控制流图的函数调用路径提取方法 |
CN106649095A (zh) * | 2016-10-31 | 2017-05-10 | 华东师范大学 | 一种面向目标代码的程序静态分析系统 |
CN106598839A (zh) * | 2016-10-31 | 2017-04-26 | 华东师范大学 | 一种面向目标代码的程序静态分析方法 |
CN107015841B (zh) * | 2017-03-31 | 2021-01-08 | 腾讯科技(深圳)有限公司 | 一种程序编译的预处理方法及程序编译设备 |
FR3086424A1 (fr) * | 2018-09-20 | 2020-03-27 | Amadeus S.A.S. | Traitement d'une sequence d'appels de fonction |
CN112130828A (zh) * | 2019-06-25 | 2020-12-25 | 北京金山云网络技术有限公司 | 一种软件源代码修改方法、装置、设备及存储介质 |
CN110530386A (zh) * | 2019-08-26 | 2019-12-03 | 浙江工业大学 | 一种基于改进Dijkstra算法的动态最短路径规划方法 |
CN113760700A (zh) * | 2020-08-06 | 2021-12-07 | 北京京东振世信息技术有限公司 | 程序死循环检测方法、装置、电子设备及存储介质 |
CN112130848B (zh) * | 2020-09-24 | 2022-06-14 | 中国科学院计算技术研究所 | 一种面向便笺式存储器的带宽感知循环分块优化方法、编译系统、设备及存储介质 |
CN112256644B (zh) * | 2020-10-20 | 2024-05-24 | 抖音视界有限公司 | 一种信息处理方法、装置及计算机存储介质 |
CN114780439B (zh) * | 2022-06-13 | 2022-09-27 | 江西财经大学 | 一种面向参数路径流图的相似程序间测试用例的重用方法 |
Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104035772A (zh) * | 2014-06-09 | 2014-09-10 | 中国科学院软件研究所 | 基于静态分析的源码多版本函数调用关系差异性标识方法 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103186406B (zh) * | 2011-12-30 | 2016-08-17 | 国际商业机器公司 | 用于控制流分析的方法和装置 |
-
2015
- 2015-08-28 CN CN201510542043.7A patent/CN105138335B/zh not_active Expired - Fee Related
Patent Citations (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN104035772A (zh) * | 2014-06-09 | 2014-09-10 | 中国科学院软件研究所 | 基于静态分析的源码多版本函数调用关系差异性标识方法 |
Non-Patent Citations (1)
Title |
---|
基于函数调用路径的软件实现与设计一致性验证;牟永敏 等;《中国科学》;20141231;第44卷(第10期);第1290-1304页 * |
Also Published As
Publication number | Publication date |
---|---|
CN105138335A (zh) | 2015-12-09 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN105138335B (zh) | 一种基于控制流图的函数调用路径提取方法及装置 | |
CN108446540B (zh) | 基于源代码多标签图神经网络的程序代码抄袭类型检测方法与系统 | |
CN106227668B (zh) | 数据处理方法和装置 | |
Moll et al. | An introduction to formal language theory | |
Taentzer | AGG: A tool environment for algebraic graph transformation | |
CN105426711B (zh) | 一种计算机软件源代码相似度检测方法 | |
Bouajjani et al. | Abstract regular (tree) model checking | |
CN107704382A (zh) | 面向Python的函数调用路径生成方法和系统 | |
CN106227573A (zh) | 基于控制流图的函数调用路径提取方法 | |
CN107367686A (zh) | 一种rtl硬件木马测试向量的生成方法 | |
CN113508385B (zh) | 使用子例程图谱进行形式语言处理的方法和系统 | |
CN105808438B (zh) | 一种基于函数调用路径的测试用例复用方法 | |
CN108021507A (zh) | 符号执行的并行路径搜索方法及装置 | |
CN115146279A (zh) | 程序漏洞检测方法、终端设备及存储介质 | |
CN105487983A (zh) | 基于智能路径引导的敏感点逼近方法 | |
Slaby et al. | Compact symbolic execution | |
CN108563561B (zh) | 一种程序隐性约束提取方法及系统 | |
JP2008059515A (ja) | プログラム実行過程の表示方法及びシステム並びにプログラム | |
Bischof et al. | A macro language for derivative definition in ADiMat | |
CN106155668A (zh) | 一种宏语言的图形化表达方法 | |
CN115879868B (zh) | 一种专家系统与深度学习相融合的智能合约安全审计方法 | |
CN112650680B (zh) | 基于抽象语法树的冗余变量和冗余方法的检测方法及系统 | |
JP3584204B2 (ja) | 原始プログラム自動変換装置 | |
Ding | Beyond Natural Language Processing: Advancing Software Engineering Tasks through Code Structure | |
JPS5833775A (ja) | コンパイル方法 |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
C06 | Publication | ||
PB01 | Publication | ||
C10 | Entry into substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant | ||
CF01 | Termination of patent right due to non-payment of annual fee | ||
CF01 | Termination of patent right due to non-payment of annual fee |
Granted publication date: 20180123 Termination date: 20200828 |