Page 108 - 《软件学报》2020年第11期
P. 108

3424                                Journal of Software  软件学报 Vol.31, No.11, November 2020

                    对于常见的函数,均可以采用上述形式进行表示.根据函数功能的不同,可以分为如下几类.
                    (1)  retval=strstr(arg1,arg2,…)类函数:这类函数实质上是对返回值 retval 进行定义,而对 retval 的定义又引
                        用了函数参数 arg1,arg2,….由于返回值 retval 可能会在后续的数据流中用到,因此可以表示为(strstr,
                        〈[retval],[arg1,arg2,…]〉),其中,[retval]为定义参数的集合,[arg1,arg2,…]为引用参数的集合.
                    (2)  memcpy(arg1,arg2,arg3,…)类函数:这类函数实质上是对某个参数如 arg1 进行定义,而对该参数的定
                        义又引用了其他参数如 arg2,arg3,…;同时,这类函数没有返回值或返回值不会体现在后续的数据流
                        中,因此可以表示为(memcpy,〈[arg1],[arg2,arg3,…]〉),其中,[arg1]为定义参数的集合,[arg2,arg3,…]为
                        引用参数的集合.
                    (3)  retval=strcpy(arg1,arg2,…)类函数:这类函数实质上是对某个参数如 arg1 进行定义,而对该参数的定
                        义又引用了其他参数如 arg2,…;同时,也对返回值 retval 进行了定义,而且返回值可能会体现在后续的
                        数据流中,因此可以表示为(strcpy,〈[arg1,retval],[arg2,…]〉),其中,[arg1,retval]为定义参数的集合,
                        [arg2,…]为引用参数的集合.
                    (4)  system(arg1,…)类函数:这类函数只是引用函数参数如 arg1,…;同时,该函数没有返回值或返回值不会
                        体现在后续的数据流中,因此可以表示为(system,〈[⋅],[arg1,…]〉),其中,[⋅]为定义参数的集合,[arg1,…]
                        为引用参数的集合.
                    除了程序中的函数外,也可以将程序中的某些语句片段(或某条语句)抽象成函数,进而表示为 FDDG 中的
                 节点,最典型的就是实现循环拷贝的语句片段.循环拷贝是指在某个循环体内向不断改变的地址中写入数据,文
                 献[18]给出了识别循环拷贝代码片段的方法.本文方法将循环拷贝代码片段直接抽象成函数,并将存在循环依
                 赖关系的变量作为函数的参数,同时记录参数之间的“定义-引用”关系.在图 3 中,将实现循环拷贝的代码片段抽
                 象成 loop_copy 函数,同时保存循环间隔和循环终止条件等信息.这种处理方法拓展了函数级数据依赖图的表达
                 能力.















                                     Fig.3    Example of abstracting a code snippet into a function
                                                图 3   代码片段抽象为函数示例
                 2.2.2    函数级数据依赖图中的边
                    函数级数据依赖图中的边表示函数之间参数的依赖关系,主要包括“引用”和“消灭”两种关系.若 a 和 b 分别
                 为程序 P 中的两个函数,v 为两个函数共同的参数,这里将函数的返回值也看作函数的参数,当 a 和 b 满足以下
                 条件时,称函数 b 和函数 a 之间关于参数 v 存在“引用”关系.
                    (1)  函数 a 对参数 v 进行定义.
                    (2)  函数 b 引用参数 v.
                    (3)  函数 a 到函数 b 之间存在一条可执行路径,且此路径上不存在其他对参数 v 的定义.
                    类似地,当 a 和 b 满足下列条件时,称函数 b 和函数 a 之间关于参数 v 存在“消灭”关系.
                    (1)  函数 a 对参数 v 进行定义.
                    (2)  函数 b 对参数 v 进行重新定义.
   103   104   105   106   107   108   109   110   111   112   113