一种计算Java程序动态切片的方法、装置及可读存储介质与流程

文档序号:15557719发布日期:2018-09-29 01:31阅读:229来源:国知局

本发明涉及计算机语言技术领域,具体涉及一种计算java程序动态切片的方法、装置及可读存储介质。



背景技术:

java语言的可移植、安全、健壮、简单、动态等特性使之成为目前非常流行的面向对象编程语言,随之出现了大量用java编写的软件产品,相应地,对java开发的大型软件系统的理解,维护,测试等工作变得尤为重要。程序切片作为一种用于分解程序的程序分析技术,极大地丰富了程序分析、程序理解、软件维护的理论基础,为软件工程的各个阶段提供理论和技术支持。

由于面向对象程序的继承,封装,多态等特性,使得语句间的依赖关系复杂。构造面向对象系统依赖图的主要途径是对传统系统依赖图进行面向对象语言特性的扩充。java语言的动态特性使java程序更加的灵活,同时也为java程序构造系统依赖图带来了困难。根据传入的对象类型不同,方法的调用情况也不同,具体情况只能通过程序的执行而获得,这使得构造静态系统依赖图非常复杂,从而造成切片结果的庞大、冗余。另外,java程序中的一些动态信息只能在执行时确定,与静态切片相比,动态切片的结果会更加精确。但由于动态切片需要追踪程序的执行,其执行代价较高。在大型软件系统的动态切片计算过程中,常出现由于执行路径过长而导致需要大量的内存及时间构造动态系统依赖图。



技术实现要素:

本发明的目的在于提供一种计算java程序动态切片的方法、装置及可读存储介质,用以解决现有java程序切片方法不适用于大型软件系统的问题。

为实现上述目的,本发明的技术方案为:

一种计算java程序动态切片的方法,该方法包括以下步骤:

对java程序字节码插桩,跟踪java程序方法的执行及调用,获得执行记录;

根据所述执行记录建立java动态系统依赖图,所述java动态系统依赖图包括静态依赖图和动态依赖图;通过程序动态执行信息建立所述动态依赖图,过语法词法分析获得程序静态信息建立所述静态依赖图;

采用后向遍历所述java动态系统依赖图的切片算法获得java程序动态切片。

进一步的,所述对java程序字节码插桩,跟踪java程序方法的执行及调用,获得执行记录包括:

通过java程序字节码插桩收集方法执行路径,所述方法执行路径中包含了程序方法执行顺序信息及方法调用信息;

进一步的,所述方法执行路径为建立所述java动态系统依赖图提供以下信息:

(1)类执行信息(ce):程序实际运行过程中被装载的类;

(2)方法执行信息(me):程序运行过程中被执行的方法;

(3)方法调用信息(mcali):程序执行过程中方法之问调用信息,可用于过滤静态方法依赖子图中的结点及依赖边。

可选地,所述程序动态执行信息包含类执行信息,方法执行信息及方法调用信息。

进一步的,所述根据所述执行记录建立java动态系统依赖图包括:

(1)提取程序静态信息

通过对java源程序的抽象语法树遍历实现,提取的信息采取树型的层次化结构保存;

(2)构造动态类依赖图

先建立类或接口与类之间的继承与实现关系,再建立类与成员方法、变量之间依赖关系;根据类执行信息、方法执行信息以及通过遍历java源程序的抽象语法树获得的类静态信息建立所述动态类依赖图;

(3)构造动态方法调用图

根据方法调用信息构造动态方法调用图;

(4)构造静态方法依赖子图

根据静态信息为每个被执行的方法建立静态方法依赖子图;

(5)过滤静态方法依赖子图

利用方法调用中的执行信息对静态方法依赖子图进行过滤,消除静态依赖子图中冗余信息,并生成动态方法依赖子图;

(6)构造方法依赖图

根据动态方法调用图在调用点与被调用方法之间添加参数输入输出边及summary边生成动态方法依赖图。

进一步的,所述根据所述执行记录建立java动态系统依赖图还包括:

建立方法依赖关系库,每次建立所述java动态系统依赖图时,直接从所述方法依赖关系库中提取建立静念方法依赖子图的信息。

进一步的,所述构造方法依赖图包括:

将过滤后的静态方法依赖子图与方法调用图中方法调用结点一一对应生成动态方法依赖图,通过参数输入边,参数输出边,以及调用边将两个方法依赖子图中对应的结点连接起来;

通过调用结点的静态信息确定调用点调用的方法,判断调用结点的调用关系是否与方法调用图中的调用关系一致;

调用点的实参与被调用方法对应的形参之间添加实参到形参的参数输入边和形参到实参的参数输出边;

根据实际输出参数对实际输入参数的数据依赖关系,再添加summary边。

基于同一发明构思,本发明的另一方面还提供了一种计算java程序动态切片的装置,该装置包括:

程序插桩器,用于对java字节码进行插桩操作,并执行插桩处理后的程序,获取程序的动态执行信息。

执行信息提取器,用于分析收集到的程序执行信息,生成方法调用对信息和方法执行路径库。

词法、语法分析器,用于通过词法和语法分析工具javacc分析java源程序,生成源程序的抽象语法分析树(ast),主要是获取java源程序的整个系统结构信息。

静态信息存储库模块,用于利用jtb生成的访问器depthfirstvisitor来遍历抽象语法树,并将相关的信息保存在自定义的类结构中。

程序分析器:用于基于抽象语法树,并结合程序执行的方法调用对信息,构造动态类依赖图、动态类层次图、动态方法调用图、方法控制流图、方法控制依赖图、动态方法依赖子图、动态方法依赖图,最终构造程序的动态系统依赖图。

动态类依赖图模块,用于通过分析java源程序被执行的类,得到动态类依赖图。

动态类层次图模块,用于通过分析执行类定义、数据成员定义及方法定义部分,得到java源程序执行的父类、类、类成员、方法参数的层次关系。

动态方法调用图模块,用于在调用方法与被调用方法之间建立调用依赖关系。

方法控制流图模块,用于通过对java源程序执行方法的分析,分析语句之间的控制关系,建立控制流边。

方法控制依赖图模块,用于通过对java源程序执行方法的分析,分析语句之间的控制依赖关系,建立控制依赖边。

动态方法依赖子图模块,用于通过对java源程序执行方法的分析,分析语句之间的控制、数据依赖关系,建立数据依赖边。

动态方法依赖图模块,用于建立调用点和被调用方法问的数据流传递关系,及调用边,即调用点所在的方法和调用点调用的方法之问的数据依赖关系。

方法依赖关系库模块,用于建立动态系统依赖图时,直接从方法依赖关系库中提取建立静态方法依赖子图的信息。

切片生成器,用于根据给定的切片标准,依据动态系统依赖图,生成程序切片的中间表示。

切片表示器,用于根据切片生成器产生的程序切片中间表示,用直观、简洁的方式将程序切片展现给用户。

基于同一发明构思,本发明的另一方面,提供了一种计算机可读存储介质,所述计算机可读存储介质上存储有计算java程序动态切片程序,所述计算java程序动态切片程序被处理器执行时实现上述的计算java程序动态切片方法的步骤。

本发明具有如下优点:

本申请的计算java程序动态切片的方法、装置及可读存储介质,通过跟踪程序方法的执行,利用程序动态执行信息和静态信息建立动态系统依赖图,并在动态系统依赖图上采用两步图可达性算法获得动态切片。本方法有效地提高了java程序动态切片的效率。

附图说明

图1本发明实施例提供的一种计算java程序动态切片的方法流程框图。

图2本发明实施例提供的一种计算java程序动态切片的装置结构框图。

具体实施方式

以下实施例用于说明本发明,但不用来限制本发明的范围。

实施例1

如图1所示,本发明实施例提供了一种计算java程序动态切片的方法,该方法包括以下步骤:

s101、对java程序字节码插桩,跟踪java程序方法的执行及调用,获得执行记录;

avassist、bcel及aspectj都能实现java字节码插桩。基于aspectj系统开销小,能输出的方法调用信息的优点,采用aspectj对程序进行插桩,获得方法的执行信息,每一条记录(action)都精确到方法所在类及方法的参数类型<class.method(args)>。

s102、根据所述执行记录建立java动态系统依赖图,所述java动态系统依赖图包括静态依赖图和动态依赖图;通过程序动态执行信息建立所述动态依赖图,过语法词法分析获得程序静态信息建立所述静态依赖图;

s103、采用后向遍历所述java动态系统依赖图的切片算法获得java程序动态切片。

其中,所述对java程序字节码插桩,跟踪java程序方法的执行及调用,获得执行记录包括:

通过java程序字节码插桩收集方法执行路径,所述方法执行路径中包含了程序方法执行顺序信息及方法调用信息;

其中,所述方法执行路径为建立所述java动态系统依赖图提供以下信息:

(1)类执行信息(ce):程序实际运行过程中被装载的类;

(2)方法执行信息(me):程序运行过程中被执行的方法;

(3)方法调用信息(mcali):程序执行过程中方法之问调用信息,可用于过滤静态方法依赖子图中的结点及依赖边。

可选地,所述程序动态执行信息包含类执行信息,方法执行信息及方法调用信息。

为了体现以上三种信息,本文提出方法调用对的概念,以及从方法执行路径中提取方法调用对的算法,首先介绍两个定义,描述如下:

定义l:若方法a调用了方法b,则a,b之间存在调用关系,记为a—b,在这条调用关系中称a为调用方法,b为被调用方法。

定义2:若以方法a为调用方法的调用关系有a—bl,a—b2,...,a—bn,(n>=o),那么存在一条关于方法a的方法调用对mcall(a)=(a—bl,a—b2,…a—bn),简述之方法调用对是以某方法为调用方法的调用关系的集合,集合可以为空。

从而生成方法调用对的目的是将不同调用方法的调用关系分开存放,从而可以清楚的知道有哪些方法被执行,以及每个方法都具有哪些调用关系。方法调用对的提取分为两个部分,先从方法执行路径中提取方法调用序列,再通过方法调用序列生成方法调用对。方法调用序列中每相连的两个方法之间存在调用关系,收集方法调用关系的过程,犹如将一个长度为2的窗口在方法调用序列上移动,每次向同一个方向移动一格;收集完调用关系后,再将其中属于同一个调用方法的调用关系放入一个集合中,这样就形成了关于每个方法的方法调用对。因为在拆分方法调用序列前会在其尾部加上exit结点,因此方法调用对的集合中的有且仅有一条关于某个方法的方法调用对,若执行路径中出现了n个不重复的方法,那么通过算法将会生成n个方法调用对。

其中,所述根据所述执行记录建立java动态系统依赖图包括:

(1)提取程序静态信息

通过对java源程序的抽象语法树遍历实现,提取的信息采取树型的层次化结构保存;

(2)构造动态类依赖图

先建立类或接口与类之间的继承与实现关系,再建立类与成员方法、变量之间依赖关系;根据类执行信息、方法执行信息以及通过遍历java源程序的抽象语法树获得的类静态信息建立所述动态类依赖图;动态类依赖图描述类与类之间的继承及实现关系(将接口视为抽象类),及每个类与其类成员方法、成员变量的关系。

(3)构造动态方法调用图

根据方法调用信息构造动态方法调用图;

(4)构造静态方法依赖子图

根据静态信息为每个被执行的方法建立静态方法依赖子图;

(5)过滤静态方法依赖子图

利用方法调用中的执行信息对静态方法依赖子图进行过滤,消除静态依赖子图中冗余信息,并生成动态方法依赖子图;

(6)构造方法依赖图

根据动态方法调用图在调用点与被调用方法之间添加参数输入输出边及summary边生成动态方法依赖图。

进一步的,所述根据所述执行记录建立java动态系统依赖图还包括:

建立方法依赖关系库,每次建立所述java动态系统依赖图时,直接从所述方法依赖关系库中提取建立静念方法依赖子图的信息。

在建立动态系统依赖图的过程中,需对每个方法建立静态方法依赖子图,而多个方法执行路径之间可能存在部分或全部执行信息相同。若为多条具有相同执行信息的方法执行路径方法建立动态系统依赖图,在没有建立方法依赖关系库之前,需要反复为同一个方法建立静态方法依赖子图,不仅工作重复,而且效率低。

建立语句依赖关系库后,每次建立动态系统依赖图时,可以直接从方法依赖关系库中提取建立静态方法依赖子图的信息,省去了很多不必要的工作。如果在构造动态系统依赖图的过程中,出现某方法的语句依赖关系信息不存在于方法依赖关系库,那么在为该方法建立静态方法依赖子图的过程中将该方法的依赖关系信息保存至方法依赖关系库中。通过建立方法依赖关系库有效能减少了工作量,使建立动态系统依赖图更加简便,在方法依赖关系库中,语句依赖关系是以方法为单位储存。

其中,所述构造方法依赖图包括:

将过滤后的静态方法依赖子图与方法调用图中方法调用结点一一对应生成动态方法依赖图,通过参数输入边、参数输出边以及调用边将两个方法依赖子图中对应的结点连接起来;

通过调用结点的静态信息确定调用点调用的方法,判断调用结点的调用关系是否与方法调用图中的调用关系一致;

调用点的实参与被调用方法对应的形参之间添加实参到形参的参数输入边和形参到实参的参数输出边;

根据实际输出参数对实际输入参数的数据依赖关系,再添加summary边。

实施例2

如图2所示,本发明的另一方面还提供了一种计算java程序动态切片的装置,该装置包括:

程序插桩器,用于对java字节码进行插桩操作,并执行插桩处理后的程序,获取程序的动态执行信息。

执行信息提取器,用于分析收集到的程序执行信息,生成方法调用对信息和方法执行路径库。

词法、语法分析器,用于通过词法和语法分析工具javacc分析java源程序,生成源程序的抽象语法分析树(ast),主要是获取java源程序的整个系统结构信息。java源代码只是一些普通的文本,它们符合某种特定的结构要求,这种结构就是我们通常所说的语法。根据编译原理知识,这种语法结构我们可以用一种称为ebnf的句法元语言表示。javacc就能够把这种ebnf所写的脚本转化成符合语法要求的解析器,这个解析器就可以用于解析用java编程语言编写的程序。词法语法分析的结果是一个由对象信息结点构成的树型层次结构,利用jtb产生的访问器可对抽象语法树进行访问,以获取分析信息。

静态信息存储库模块,用于利用jtb生成的访问器depthfirstvisitor来遍历抽象语法树,并将相关的信息保存在自定义的类结构中。这些自定义的类也采取层次化的结构,这样不但能保存源程序中的程序元素(对象、方法、语句等)信息,而且能保存程序的结构。

程序分析器:用于基于抽象语法树,并结合程序执行的方法调用对信息,构造动态类依赖图、动态类层次图、动态方法调用图、方法控制流图、方法控制依赖图、动态方法依赖子图、动态方法依赖图,最终构造程序的动态系统依赖图。

动态类依赖图模块,用于通过分析java源程序被执行的类,得到动态类依赖图。描述程序执行路径中类(接口)与类之间的继承与实现关系。图中的结点表示类或接口,图中的边表示一个类继承或实现另一个类。

动态类层次图模块,用于通过分析执行类定义、数据成员定义及方法定义部分,得到java源程序执行的父类、类、类成员、方法参数的层次关系。描述程序执行路径中父类、类、类成员、方法参数之间的层次关系。

动态方法调用图模块,用于在调用方法与被调用方法之间建立调用依赖关系。描述程序执行路径中方法之间的调用关系。在方法调用图中,每个结点表示一个方法,如果两个结点之间存在一条边,表示一个方法调用另一个方法。

方法控制流图模块,用于通过对java源程序执行方法的分析,分析语句之间的控制关系,建立控制流边。描述一个方法内所有语句或谓词执行的可能流向。主要功能是为源程序的每个方法建立控制流图。在一个控制流图中,一个结点对应一个语句或谓词。一个控制流图是对一个方法而言,不同的方法有不同的控制流图。

方法控制依赖图模块,用于通过对java源程序执行方法的分析,分析语句之间的控制依赖关系,建立控制依赖边。该模块是描述方法语句之间的控制依赖关系。主要功能是为源程序的每个方法建立控制依赖图。在一个控制依赖图中,一个结点对应于一个语句或谓词。一个控制依赖图是对一个方法而言,不同的方法有不同的控制依赖图。两个结点之间存在控制依赖边,表明一个结点的语句执行依赖于另一个结点的执行。

动态方法依赖子图模块,用于通过对java源程序执行方法的分析,分析语句之间的控制、数据依赖关系,建立数据依赖边。该模块通过是程序分析器过滤后静态方法依赖子图后得到的,程序分析器可直接从方法关系依赖库中提出静态信息构造静态方法依赖子图。该模块可描述方法语句之间的控制、数据依赖关系。主要功能是建立源程序的每个方法的输入参数和输出参数与方法内的语句结点或者方法内的调用结点参数之间的数据依赖关系,也建立语句结点之间或者语句结点与调用结点参数之间的数据依赖关系。在一个方法依赖子图中,一个结点对应于一个语句或谓词或一个变量,调用结点不与被调用方法相连。一个方法依赖子图是对应一个方法。两个结点之间存在控制依赖边,表明一个结点的语句执行依赖于另一个结点的执行。两个变量结点之间存在数据依赖边,表明一个语句定义的变量的值影响到另一个语句变量的使用。

动态方法依赖图模块,用于建立调用点和被调用方法问的数据流传递关系,及调用边,即调用点所在的方法和调用点调用的方法之问的数据依赖关系。该模块是描述方法之间的数据依赖关系,通过对java源程序执行方法的分析,分析方法之间的数据依赖关系,在相应调用点参数和被调用方法参数之间添加参数输入边和参数输出边。根据实际输出参数对实际输入参数的数据依赖关系,再添加summary边。

方法依赖关系库模块,用于建立动态系统依赖图时,直接从方法依赖关系库中提取建立静态方法依赖子图的信息。在建立动态系统依赖图的过程中,需对每个方法建立静态方法依赖子图并过滤,而多个方法执行路径之间可能存在部分或全部执行信息相同。若为多条具有相同执行信息的方法执行路径方法建立动态系统依赖图,在没有建立语句依赖关系库之前,需要反复为同一个方法建立静态方法依赖子图,不仅工作重复,而且效率低。建立方法依赖关系库后,每次建立动态系统依赖图时,可以直接从方法依赖关系库中提取建立静态方法依赖子图的信息,省去了很多不必要的工作。

切片生成器,用于根据给定的切片标准,依据动态系统依赖图,生成程序切片的中间表示。

切片表示器,用于根据切片生成器产生的程序切片中间表示,用直观、简洁的方式将程序切片展现给用户。

要对java源程序进行切片的应用,首先需要从抽象语法树中提取源程序的具体信息。为了有效地存储信息,本系统采用和抽象语法树相似的层次化存储结构,存储遍历抽象语法树所获得的源程序信息。

本装置的开发环境是eclipse平台,开发的语言采用java语言,采用aspectj对java字节码进行插桩,用在eclipse平台上的javaccplug.in这个解析器生成工具,对java源程序进行词法、语法分析。并且,javacc有两个辅助工具jjtree和jtb,它可以在词法、语法分析的基础上直接生成源程序的抽象语法树(ast),并利用jtb产生的访问器可对抽象语法树进行访问,以获取分析信息。

aspectj提供了一套独有的基于java平台的aop语法,以及专有的aspectj编译器。采用aspectj对java字节码进行插桩的优点是,在程序执行过程收集程序方法执行路径是一个嵌套的跟踪轨迹,描绘了程序在从开头运行到结尾的过程中,堆栈帧在栈上压入和弹出的过程(当调用函数时堆栈帧被压入栈中,当函数返回时堆栈帧被从栈中弹出),因此方法执行路径中包含了程序方法调用关系。并且,采用aspectj静态植入技术,使得运用了aop技术的系统在运行性能上未受到任何损失,因为它没有利用反射技术或代理技术,而仅仅是程序的静态扩展而已。

javacc是一个流行的解析器生成器工具,功能类似于lex和yace。它能够同时、自动化地对程序进行词法分析和语法分析,使用起来相当方便。javacc运行程序读入用javacc语法编写的源程序,即某一语言的词法规则、文法规则及与该文法规则相联系的语义动作说明,就能生成java代码的该文法的词法分析器和语法分析器。同时,javacc除了常规的词法分析和语法分析以外,还提供jjtree和jtb等工具来帮助我们建立并访问抽象语法树。

javatreebuilder(jtb)是一个采用java语言开发的抽象语法树生成器。它需要与javacc配合使用来生成抽象语法树,并且通过访问者(visitor)模式来对抽象语法树进行访问和操作。

jtb可以根据一个符合javacc语法文件规范的语法文件,来生成相对应的操作类。这些类包括生成抽象语法树所需要的各种抽象语法树节点类,以及对抽象语法树进行遍历的各种访问者类。同时jtb也会对这个语法文件进行修改,添加生成抽象语法树的指令。

javacc使用这个语法文件来生成的语法分析器的时候,就会自动构建出符合这个语法的抽象语法树结构。当这个语法分析器对某个语法正确的源代码文件进行解析后,就可以使用jtb所生成的访问者类(depthfirstvisitor)对这棵抽象语法树进行遍历访问。所以只需要在访问者类中添加相关的操作,就可以实现对抽象语法树的信息进行提取和分析的工作。

j_dsiice是针对于java源程序进行动态切片的原型系统。该系统确定java语法规范的一个子集,如不考虑多线程等;

采用javacc工具生成java源程序的抽象语法树(ast);

用jtb工具遍历抽象语法树,存储程序静态信息;

采用aspectj对java字节码进行插桩,收集程序动态执行信息;

基于上述信息,构造动态类依赖图、动态类层次图、动态方法调用图、方法控制流图、方法控制依赖图、动态方法依赖子图、动态方法依赖图;最后,在程序动态系统依赖图的基础上,计算出关于该切片准则的程序切片。

j_dsiice针对java语言源程序进行动态程序切片的原型系统。目前源程序都是以简单文本表示,这样对编程人员来说很方便,但要揭示程序的深层次结构,需要进行词法和语法分析,所以源程序分析器中必须包含有编译程序。

通过对java源程序文件的读入,根据javacc工具生成符合要求的语法分析器和词法分析器;然后对读入的源程序文件进行词法和语法分析,可以按照要求把源程序转化成为相应的抽象语法树表示。抽象语法树中不仅包含所有源程序的文本信息,还有源程序的结构信息。如面向对象程序中类与类之间的层次关系,类与方法之间的包含关系,方法与方法之间的调用关系以及方法与语句之间的关系等所有信息等等。通过jtb工具访问抽象语法树,可以得到所有需要的信息,并通过定义一些类来保存这些信息。以后对源程序的分析就可以通过遍历这些存储程序静态信息的类结构,并结合通过程序插桩收集到的执行路径信息,构造出方法调用图、方法控制流图、方法控制依赖图、方法依赖图等,最终实现java程序的动态切片。

实施例3

基于同一发明构思,本发明的另一方面,提供了一种计算机可读存储介质,所述计算机可读存储介质上存储有计算java程序动态切片程序,所述计算java程序动态切片程序被处理器执行时实现上述的计算java程序动态切片方法的步骤。

本申请的计算java程序动态切片的方法、装置及可读存储介质,通过跟踪程序方法的执行,利用程序动态执行信息和静态信息建立动态系统依赖图,并在动态系统依赖图上采用两步图可达性算法获得动态切片。本方法有效地提高了java程序动态切片的效率。

虽然,上文中已经用一般性说明及具体实施例对本发明作了详尽的描述,但在本发明基础上,可以对之作一些修改或改进,这对本领域技术人员而言是显而易见的。因此,在不偏离本发明精神的基础上所做的这些修改或改进,均属于本发明要求保护的范围。

当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1