代码检测方法及装置转让专利

申请号 : CN201410448592.3

文献号 : CN105468508B

文献日 :

基本信息:

PDF:

法律信息:

相似专利:

发明人 : 徐会卿张翔

申请人 : 阿里巴巴集团控股有限公司

摘要 :

本申请提供一种代码检测方法及装置。方法包括:对待检测代码进行动态分析,以获得第一函数调用图,第一函数调用图中的节点表示待检测代码包含的函数,第一函数调用图中的有向边表示有向边连接的两个节点所表示的函数之间的调用关系;根据第一函数调用图,检测待检测代码中是否存在调用环路。本申请可以从整体对代码进行检测,提高检测代码检测稳定性的准确度。

权利要求 :

1.一种代码检测方法,其特征在于,包括:

对待检测代码进行静态分析,获得所述待检测代码在静态时所包含的函数和函数之间的调用关系;

根据所述待检测代码在静态时所包含的函数和函数之间的调用关系,生成第二函数调用图,所述第二函数调用图中的节点表示所述待检测代码在静态时包含的函数,所述第二函数调用图中的有向边表示所述有向边所连接的两个节点所表示的函数之间的调用关系;

运行所述待检测代码,以获得第一函数与另一函数之间的调用关系,并在所述第二函数调用图中添加用于表示所述第一函数与另一函数之间的调用关系的有向边,以获得第一函数调用图,所述第一函数为入度为0或出度为0的节点所表示的函数;

根据所述第一函数调用图,检测所述待检测代码中是否存在调用环路。

2.根据权利要求1所述的方法,其特征在于,在运行所述待检测代码之前,该方法还包括:判断所述第二函数调用图中是否存在入度为0或出度为0的节点;

如果否,则确定所述第二函数调用图为所述第一函数调用图;

如果是,则继续执行运行所述待检测代码的步骤。

3.根据权利要求1所述的方法,其特征在于,所述运行所述待检测代码,以获得第一函数与另一函数之间的调用关系,并在所述第二函数调用图中添加用于表示所述第一函数与另一函数之间的调用关系的有向边,以获得所述第一函数调用图,包括:利用第二插装代码,监控所述待检测代码的运行过程,以确定所述第一函数与另一函数之间的调用关系,并在所述第二函数调用图中添加用于表示所述第一函数与另一函数之间的调用关系的有向边,以获得所述第一函数调用图。

4.根据权利要求1-3任一项所述的方法,其特征在于,所述根据所述第一函数调用图,检测所述待检测代码中是否存在调用环路,包括:对所述第一函数调用图进行拓扑排序处理,以获得不包括入度为0的节点的第三函数调用图;

若所述第三函数调用图中存在节点,确定所述待检测代码中存在调用环路;

若所述第三函数调用图中不存在节点,确定所述待检测代码中不存在调用环路。

5.根据权利要求4所述的方法,其特征在于,还包括:

在所述待检测代码中存在调用环路时,获得所述待检测代码中存在的调用环路的个数;

根据所述调用环路的个数,确定所述待检测代码的稳定性等级。

6.一种代码检测装置,其特征在于,包括:

分析模块,用于对待检测代码进行静态分析,获得所述待检测代码在静态时所包含的函数和函数之间的调用关系;根据所述待检测代码在静态时所包含的函数和函数之间的调用关系,生成第二函数调用图,所述第二函数调用图中的节点表示所述待检测代码在静态时包含的函数,所述第二函数调用图中的有向边表示所述有向边所连接的两个节点所表示的函数之间的调用关系;运行所述待检测代码,以获得第一函数与另一函数之间的调用关系,并在所述第二函数调用图中添加用于表示所述第一函数与另一函数之间的调用关系的有向边,以获得第一函数调用图,所述第一函数为入度为0或出度为0的节点所表示的函数;

检测模块,用于根据所述第一函数调用图,检测所述待检测代码中是否存在的调用环路。

7.根据权利要求6所述的装置,其特征在于,所述分析模块在运行所述待检测代码之前,还用于:判断所述第二函数调用图中是否存在入度为0或出度为0的节点;

如果否,则确定所述第二函数调用图为所述第一函数调用图;

如果是,则继续执行运行所述待检测代码的操作。

8.根据权利要求6所述的装置,其特征在于,所述分析模块具体用于:利用第二插装代码,监控所述待检测代码的运行过程,以确定所述第一函数与另一函数之间的调用关系,并在所述第二函数调用图中添加用于表示所述第一函数与另一函数之间的调用关系的有向边,以获得所述第一函数调用图。

9.根据权利要求6-8任一项所述的装置,其特征在于,所述检测模块具体用于:对所述第一函数调用图进行拓扑排序处理,以获得不包括入度为0的节点的第三函数调用图;若所述第三函数调用图中存在节点,确定所述待检测代码中存在调用环路;若所述第三函数调用图中不存在节点,确定所述待检测代码中不存在调用环路。

10.根据权利要求9所述的装置,其特征在于,还包括:

获得模块,用于在所述待检测代码中存在调用环路时,获得所述待检测代码中存在的调用环路的个数;

确定模块,用于根据所述调用环路的个数,确定所述待检测代码的稳定性等级。

说明书 :

代码检测方法及装置

【技术领域】

[0001] 本申请涉及计算机技术领域,尤其涉及一种代码检测方法及装置。【背景技术】
[0002] 代码是指程序员利用开发工具所支持的语言编写出来的源文件,是一组由字符、符号或信号码元等以离散形式表示信息的明确的规则体系。随着编程技术的发展,大多数功能都可以通过代码实现。在具体实现上,代码会包括一些函数,并通过函数之间的相互调用完成所要实现的功能。
[0003] 在实际应用中,为确保代码的稳定性和可用性等,在开发出代码之后,通常还需要对其进行各种检测,如静态代码检测。现有技术存在以代码中的函数为对象,验证每个函数是否存在循环调用语句的静态检测方法。例如,该方法会检测函数中是否存在类似while(true)这样的初始化死循环语句,或者检测是否存在类似for(;;)这样的无限循环语句等,来判断函数是否存在错误。
[0004] 由于现有这种代码检测方法仅局限于代码包含的函数内,因此无法从整体角度对代码进行检测,检测准确度较低。【发明内容】
[0005] 本申请的多个方面提供一种代码检测方法及装置,用以从整体对代码进行检测,提高代码检测的准确度。
[0006] 本申请的一方面,提供一种代码检测方法,包括:
[0007] 对待检测代码进行动态分析,以获得第一函数调用图,所述第一函数调用图中的节点表示所述待检测代码包含的函数,所述第一函数调用图中的有向边表示所述有向边连接的两个节点所表示的函数之间的调用关系;
[0008] 根据所述第一函数调用图,检测所述待检测代码中是否存在调用环路。
[0009] 本申请的另一方面,提供一种代码检测装置,包括:
[0010] 分析模块,用于对待检测代码进行动态分析,以获得第一函数调用图,所述第一函数调用图中的节点表示所述待检测代码包含的函数,所述第一函数调用图中的有向边表示所述有向边连接的两个节点所表示的函数之间的调用关系;
[0011] 检测模块,用于根据所述第一函数调用图,检测所述待检测代码中是否存在的调用环路。
[0012] 在本申请中,通过对代码进行动态分析,获得可以表示代码包含的函数以及函数之间调用关系的第一函数调用图,根据第一函数调用图,检测代码中是否存在调用环路。与现有函数内这种局部检测方式相比,本申请是从全局角度发现代码包含的函数之间是否存在调用环路,而不再局限于函数内的检测,函数之间的调用环路可能导致代码在运行时出现死循环,会严重影响代码的整体性能,因此本申请通过检测代码中是否存在调用环路达到检测代码的目的,可以极大的提高代码检测的准确度。【附图说明】
[0013] 为了更清楚地说明本申请实施例中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作一简单地介绍,显而易见地,下面描述中的附图是本申请的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
[0014] 图1为本申请一实施例提供的代码检测方法的流程示意图;
[0015] 图2为本申请一实施例提供的第一函数调用图的结构示意图;
[0016] 图3为本申请一实施例提供的步骤101的一种实施方式的流程示意图;
[0017] 图4为本申请一实施例提供的第二函数调用图的结构示意图;
[0018] 图5为本申请另一实施例提供的第一函数调用图的结构示意图;
[0019] 图6为本申请一实施例提供的步骤102的一种实施方式的流程示意图;
[0020] 图7为本申请一实施例提供的第三函数调用图的结构示意图;
[0021] 图8为本申请一实施例提供的代码检测装置的结构示意图。【具体实施方式】
[0022] 为使本申请实施例的目的、技术方案和优点更加清楚,下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有作出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
[0023] 图1为本申请一实施例提供的代码检测方法的流程示意图。如图1所示,该方法包括:
[0024] 101、对待检测代码进行动态分析,以获得第一函数调用图,其中,第一函数调用图中的节点表示待检测代码包含的函数,第一函数调用图中的有向边表示该有向边连接的两个节点所表示的函数之间的调用关系。
[0025] 102、根据上述第一函数调用图,检测待检测代码中是否存在调用环路。
[0026] 本实施例的执行主体可以是代码检测装置,该装置可以是任何具有一定处理能力的设备,例如可以是用户终端、服务器或者代码检测专用设备等。
[0027] 本实施例中待检测代码可以是使用任何编程语言编写的代码,也可以是实现任何功能的代码。编程语言可以是java、C、C++等。
[0028] 对有些代码而言,通过静态分析无法准确获取这些代码所包含的函数之间的调用关系。例如,对于使用spring(它是一个轻量级的J2EE框架,关于spring具体可参见现有技术)进行接口编程、切面编程的代码,静态分析无法准确得到函数之间的调用关系。又例如,对于在运行时存在类型识别的代码来说,静态分析也无法准确获得函数之间的调用关系。例如,在运行时存在类型识别的代码可以是使用了C语言的void*(void是C语言中的一个类型,void*可指向任何数据类型,这会妨碍静态分析的准确性)、C++语言的通过运行时类型信息(Run-Time Type Information,RTTI)或者java语言中的基类等的代码。
[0029] 举例说明,假设一种采用接口编程的代码包括:接口函数A1、B1、C1和D1,以及各个接口函数对应的接口实体函数A2、B2、C2和D2;则通过静态分析可以得到代码包含的函数之间的调用关系,包括接口实体函数A2调用接口函数B1,接口实体函数B2调用接口函数C1、接口实体函数C2调用接口函数D1,接口实体函数D2调用接口函数A1。但在实际运行中,当运行到一个接口实体函数调用另一接口函数时,该接口实体函数会自动调用另一接口函数对应的接口实体函数,即该代码实际上还包含以下函数调用关系:接口实体函数A2调用接口实体函数B2,接口实体函数B2调用接口实体函数C2、接口实体函数C2调用接口实体函数D2,接口实体函数D2调用接口实体函数A2,这些函数调用关系无法通过静态分析获得。
[0030] 基于上述,本实施例在检测代码过程中,代码检测装置对代码进行动态分析,以获得可以表示代码包含的函数和函数之间的调用关系的函数调用图。为便于区分和描述,将这里的函数调用图称为第一函数调用图,这里的“第一”既不是个数的限定,也不是先后顺序的限定。
[0031] 其中,第一函数调用图包括节点和有向边,第一函数调用图中的节点表示待检测代码包含的函数,即一个节点对应一个函数,节点的数目与待检测代码包含的函数的个数相同;第一函数调用图中的有向边表示该有向边所连接的两个节点所表示的两个函数之间的调用关系,如果有向边从一个节点指向另一个节点,表示该节点所表示的函数调用另一个节点所表示的函数。如图2所示,为本实施例给出的一种第一函数调用图的结构示意图,图2中的小圆圈表示节点,两个小圆圈之间的有向箭头表示有向边。图2中的加粗箭头展示了待检测代码中存在的调用环路。
[0032] 值得说明的是,待检测代码可能位于至少一个代码文件中,代码检测装置可以逐个扫描代码文件,获取各个代码文件中的代码并进行动态分析。
[0033] 在一可选实施方式中,上述步骤101的一种具体实施方式为:运行待检测代码,以获得待检测代码在运行状态时所包含的函数和函数之间的调用关系,并根据待检测代码在运行状态时所包含的函数和函数之间的调用关系生成第一函数调用图。
[0034] 在对待检测代码进行动态分析,以获取第一函数调用图时,可采用程序插桩技术、以及其他方式来进行分析处理,只要可以检测出待检测代码运行中的函数调用逻辑即可。可选的,上述实施方式采用程序插桩技术来实现时,可包括:代码检测装置利用第一插装代码,监控待检测代码的运行过程,以确定待检测代码包含的函数和函数之间的调用关系,并在第一函数调用图中添加用于表示函数的节点和用于表示函数之间的调用关系的有向边。
[0035] 第一插装代码是插入待检测代码中的代码,这部分代码负责监控待检测代码的运行过程,以确定待检测代码在运行状态时包含的函数和函数之间的调用关系,并根据监控到的信息生成第一函数调用图。具体的,第一插装代码可以在待检测代码运行到每个函数时,获取该函数的名称以及调用该函数的上一函数的名称,并根据该函数的名称和上一函数的名称,根据该函数的名称和上一函数的名称,在第一函数调用图中添加用于表示该函数的节点和表示该函数和上一函数之间的调用关系的有向边。
[0036] 例如,代码检测装置可以将第一插装代码插在每个函数的入口位置和出口位置;或者,也可以将第一插装代码插在整个待检测代码的入口位置和出口位置。
[0037] 其中,所述的程序插桩技术,具体是借助往被测程序代码中插入操作,来实现测试目的的方法,其可以在不破坏被测试程序原有逻辑完整性的前提下,在程序的相应位置上插入一些探针(插桩代码)。这些插桩代码就是进行信息采集的代码段,可以是赋值语句或采集覆盖信息的函数调用,通过插桩代码的执行并输出程序的运行特征数据,从而可获得程序运行时的函数调用关系,进而得到调用图。插桩代码可以利用JAVA等程序编制而得到。
[0038] 在另一可选实施方式中,如图3所示,上述步骤101的一种具体实施方式为:
[0039] 1011、对待检测代码进行静态分析,获得待检测代码在静态时所包含的函数和函数之间的调用关系。
[0040] 静态分析这种方法主要是对代码的语法文件进行分析,具体的,代码检测装置可以使用静态代码扫描工具扫描待检测代码,获得待检测代码在静态时包含的每一个函数,例如函数Foo(int,int),以及函数之间的调用关系。
[0041] 1012、根据待检测代码在静态时所包含的函数和函数之间的调用关系,生成第二函数调用图,该第二函数调用图中的节点表示待检测代码在静态时包含的函数,第二函数调用图中的有向边表示该有向边所连接的两个节点所表示的函数之间的调用关系。
[0042] 具体的,该第二函数调用图包括节点和有向边,第二函数调用图中的节点表示代码包含的函数,即一个节点对应一个函数,节点的数目与待检测代码包含的函数的个数相同;第二函数调用图中的有向边表示该有向边所连接的两个节点所表示的两个函数之间的调用关系,如果有向边从一个节点指向另一个节点,表示该节点所表示的函数调用另一个节点所表示的函数。值得说明的是,第二函数调用图中的有向边仅体现了待检测代码在静态时所包含的函数之间的调用关系。
[0043] 1013、判断第二函数调用图中是否存在第一节点,若否,则执行步骤1014,若是,则执行步骤1015。
[0044] 1014、确定第二函数调用图为第一函数调用图。
[0045] 1015、运行待检测代码,以获得第一函数与另一函数之间的调用关系,并在第二函数调用图中添加用于表示第一函数与另一函数之间的调用关系的有向边,以获得第一函数调用图。
[0046] 上述第一节点是指入度或出度为0的节点。例如,对一个节点来说,若该节点所表示的函数调用其他函数但没有任何其他函数调用该节点所表示的函数,则该节点属于入度为0的节点,这种节点属于本实施例所说的第一节点。例如,对一个节点来说,若该节点所表示的函数被其他函数调用但没有调用任何其他函数,则该节点属于出度为0的节点,这种节点也属于本实施例所说的第一节点。例如,对一个节点来说,若该节点所表示的函数即不调用其他函数也不被其他函数调用,则该节点属于入度和出度均为0的节点,这种节点也属于本实施例所说的第一节点。值得说明的是,上述第一节点可以是一个或多个。
[0047] 上述第一函数是指第一节点所表示的函数。
[0048] 如果第二函数调用图中不存在第一节点,说明待检测代码在静态时包含的函数之间的调用关系,与待检测代码在动态时包含的函数之间的调用关系相同,故可以直接将第二函数调用图作为第一函数调用图。
[0049] 如果第二函数调用图中存在第一节点,说明待检测代码在静态时包含的函数之间的调用关系,与待检测代码在动态时包含的函数之间的调用关系不相同,于是运行待检测代码,以便获取待检测代码在运行状态时第一节点所表示的函数与另一函数之间的调用关系,并在第二函数调用图中添加用于表示第一节点所表示的函数与另一函数之间的调用关系的有向边,以获得第一函数调用图。
[0050] 上述步骤1015的一种实施方式包括:代码检测装置利用第二插装代码,监控待检测代码的运行过程,以确定第一函数与另一函数之间的调用关系,并在第二函数调用图中添加用于表示第一函数与另一函数之间的调用关系的有向边,以获得第一调用函数。
[0051] 第二插装代码是插入待检测代码中的代码,这部分代码负责监控待检测代码的运行过程,以确定第一函数与另一函数之间的调用关系,并根据监控到的信息对第二函数调用图进行修正从而获得第一函数调用图。具体的,第二插装代码可以在待检测代码运行到第一函数时,获取第一函数的名称以及与第一函数具有调用关系的另一函数的名称,并根据第一函数的名称和另一函数的名称,在第二函数调用图中添加用于表示第一函数与另一函数之间的调用关系的有向边。
[0052] 例如,代码检测装置可以第二插装代码插在第一函数的入口位置和出口位置。
[0053] 本实施例仍以上述采用接口编程的代码为例,假设该采用接口编程的代码即为本实施例中的待检测代码,包括:接口函数A1、B1、C1和D1,以及各个接口函数对应的接口实体函数A2、B2、C2和D2;则通过静态分析可以得到代码处于静态时所包含的函数之间的调用关系,包括接口实体函数A2调用接口函数B1,接口实体函数B2调用接口函数C1、接口实体函数C2调用接口函数D1,接口实体函数D2调用接口函数A1,根据这些函数之间的调用关系可以生成如图4所示的第二函数调用图。但在实际运行中,接口实体函数调用接口函数会转变成调用该接口函数对应的接口实体函数,因此通过运行待检测代码可以发现只有代码在运行状态时才包含的函数调用关系,即接口实体函数A2调用接口实体函数B2,接口实体函数B2调用接口实体函数C2、接口实体函数C2调用接口实体函数D2,接口实体函数D2调用接口实体函数A2,将这些函数之间的调用关系添加到图4所示第二函数调用图中,获得图5所示的第一函数调用图,图5中加粗箭头所示为新添加的有向边。通过图4和图5可知,对某些待检测代码用静态分析获得的函数之间的调用关系并不全面。图4和图5中的小圆圈表示节点,两个小圆圈之间的有向箭头表示有向边。
[0054] 在获得第一函数调用图之后,代码检测装置根据第一函数调用图,检测待检测代码中是否存在调用环路,以达到检测代码的目的。调用环路是指由至少一个函数形成的循环调用。例如,假设有四个函数,分别为函数A、B、C和D,若A调用B,B调用C,C调用D,而D又调用A,在函数A、B、C和D之间形成一条调用环路。又例如,假设有两个函数,分别为函数F和G,若F调用G,G又调用F,则函数F和G之间形成一条调用环路。
[0055] 在一可选实施方式中,如图6所示,上述步骤102的一种具体实施方式包括:
[0056] 1021、对第一函数调用图进行拓扑排序处理,以获得不包括入度为0的节点的第三函数调用图。
[0057] 例如,一种对第一函数调用图进行拓扑排序处理的过程包括:第一步:判断第一函数调用图中是否存在入度为0的节点,如果存在,则执行第二步,如果不存在,则将第一函数调用图直接作为第三函数调用图,并结束操作;第二步:将入度为0的节点以及由该节点发出的有向边全部删除,并返回继续执行第一步以及第二步,直到不存在入度为0的节点为止,将此时的函数调用图作为第三函数调用图。第三函数调用图是不包括入度为0的节点的函数调用图。结合图2所示的第一函数调用图,则得到的第三函数调用图的结构如图7所示,包括两个调用环路。
[0058] 1022、判断第三函数调用图中是否存在节点;如果是,则执行步骤1023;如果否,则执行步骤1024。
[0059] 1023、确定待检测代码存在调用环路。
[0060] 1024、确定待检测代码不存在调用环路。
[0061] 其中,代码中出现调用环路不仅可以反映出代码的分层设计不佳,也可以反映出代码在当前运行时或将来运行时很可能会发生死循环,导致代码稳定性降低,因此代码中是否存在调用环路可以反映代码的整体性能。
[0062] 由此可见,本实施例是从全局角度发现代码包含的函数之间是否存在调用环路,而不再局限于函数内的检测,函数之间的调用环路可能导致代码在运行时出现死循环,会严重影响代码的稳定性,因此本实施例通过检测代码中是否存在调用环路达到检测代码的目的,可以极大的提高代码检测的准确度。
[0063] 进一步,代码中出现的调用环路的数量越多意味着代码的稳定性越差。因此,在检测到待检测代码中存在调用环路,代码检测装置可以确定待检测代码中存在的调用环路的个数,并根据调用环路的个数,确定代码的稳定性等级。
[0064] 例如,代码检测装置可以在判断出第三函数调用图包括节点时,继续对第三函数调用图进行深度优先搜索(Deep First Search,DFS)遍历,以获得遍历第三函数调用图中所有节点需要的DFS遍历次数,并确定DFS遍历次数为调用环路的个数。采用该方法可以提高确定调用环路的个数的效率,但不限于上述实施方式,也可以直接根据函数以及函数之间的调用关系分析出调用环路进而获得调用环路的个数。其中,DFS遍历算法属于现有技术,在此不再赘述。结合图7,需要进行两次DFS遍历,所以调用环路的个数为2。值得说明的是,DFS遍历出的调用环路之间不存在相同节点。
[0065] 在一可选实施方式中,如果待检测代码中不存在调用环路,即调用环路的个数为0,则代码检测装置可以确定待检测代码的稳定性等级为最高等级。如果设置三个稳定性等级,则最高等级就是第三等级;如果设置四个稳定性等级,则最高等级就是第四等级。如果待检测代码中存在调用环路,即调用环路的个数不为0,则代码检测装置可以根据调用环路的个数和预设的个数门限,确定待检测代码的稳定性等级为不同于最高等级的其他等级。
[0066] 举例说明,假设设置有三个等级,则当调用环路的个数为0时,将待检测代码的稳定性等级确定为最高等级,即第三等级;当调用环路的个数大于0且小于预设个数门限时,则将待检测代码的稳定性等级确定为第二等级;如果调用环路的个数大于或等于预设的个数门限,则将待检测代码的稳定性等级确定为第一等级。值得说明的是,预设个数门限可以设置多个,从而将代码的稳定性划分为多个级别。
[0067] 在另一可选实施方式中,如果调用环路的个数为0,则代码检测装置可以确定待检测代码的稳定性等级为最高等级。如果调用环路的个数不为0,则代码检测装置还可以确定每个调用环路上的函数数目,并具体根据调用环路的个数和每个调用环路上的函数数据,确定代码的稳定性等级。
[0068] 结合前述实施方式,代码检测装置具体可以在获得待检测代码中存在的调用环路的个数的同时,确定每个调用环路上的函数数目。例如,代码检测装置在对第三函数调用图进行DFS遍历获得DFS遍历次数的同时,可以获得每次DFS遍历到的节点数目,将每次DFS遍历到的节点数目作为一个调用环路上的函数数目。
[0069] 进一步,代码检测装置根据调用环路的个数和每个调用环路上的函数数据,确定待检测代码的稳定性等级的一种实施方式包括:
[0070] 代码检测装置根据每个调用环路上的函数数目,获得所有调用环路上的函数总数,即将每个调用环路上的函数数目相加,获得所有调用环路上的函数总数;之后,根据调用环路的个数和函数总数,确定待检测代码的稳定性等级。结合图7,调用环路的个数为2,函数总数为12。可选的,代码检测装置可以将DFS遍历到的节点总数直接作为所有调用环路上的函数总数。
[0071] 值得说明的是,根据调用环路的个数和所有调用环路上的函数总数对待检测代码进行稳定等级衡量过程中,调用环路的个数越多,表示待检测代码稳定性等级越低;所有调用环路上的函数总数越多,表示待检测代码稳定性等级越低。并且,调用环路的个数的优先级要高于所有调用环路上的函数总数。
[0072] 基于上述,在一可选实施方式中,代码检测装置针对调用环路的个数设置多个第一门限,并针对函数总数设置多个第二门限,通过这些门限划分出不同的稳定性等级。则代码检测装置具体可以将调用环路的个数和函数总数分别与对应的门限进行比较,确定待检测代码的稳定性等级。
[0073] 本实施例通过对代码进行动态分析,获得可以表示代码包含的函数以及函数之间调用关系的第一函数调用图,根据第一函数调用图,检测代码中是否存在调用环路,并在检测到代码中存在调用环路时,获取代码中存在的调用环路的个数,根据调用环路的个数确定代码的稳定性等级。与现有函数内这种局部检测方式相比,本实施例是从全局角度发现函数之间的调用环路的个数,而不再局限于函数内的检测,函数之间的调用环路可能导致代码在运行时出现死循环,会严重影响代码的稳定性,因此本申请根据调用环路的个数确定代码的稳定性等级,可以极大的提高所确定的稳定性等级的准确度。
[0074] 需要说明的是,对于前述的各方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本申请并不受所描述的动作顺序的限制,因为依据本申请,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作和模块并不一定是本申请所必须的。
[0075] 在上述实施例中,对各个实施例的描述都各有侧重,某个实施例中没有详述的部分,可以参见其他实施例的相关描述。
[0076] 图8为本申请一实施例提供的代码检测装置的结构示意图。如图8所示,该装置包括:分析模块81和检测模块84。
[0077] 分析模块81,用于对待检测代码进行动态分析,以获得第一函数调用图,第一函数调用图中的节点表示待检测代码包含的函数,第一函数调用图中的有向边表示有向边连接的两个节点所表示的函数之间的调用关系。
[0078] 检测模块84,与分析模块81连接,用于根据分析模块81获得的第一函数调用图,检测待检测代码中是否存在调用环路。
[0079] 在一可选实施方式中,分析模块81具体可用于:运行待检测代码,以获得待检测代码在运行状态时所包含的函数和函数之间的调用关系,并根据待检测代码在运行状态时所包含的函数和函数之间的调用关系生成第一函数调用图。
[0080] 进一步,分析模块81具体可用于:
[0081] 利用第一插装代码,监控待检测代码的运行过程,以确定待检测代码包含的函数和函数之间的调用关系,并在第一函数调用图中添加用于表示函数的节点和用于表示函数之间的调用关系的有向边。
[0082] 在一可选实施方式中,分析模块81具体可用于:
[0083] 对待检测代码进行静态分析,获得待检测代码在静态时所包含的函数和函数之间的调用关系;
[0084] 根据待检测代码在静态时所包含的函数和函数之间的调用关系,生成第二函数调用图,第二函数调用图中的节点表示待检测代码在静态时包含的函数,第二函数调用图中的有向边表示有向边所连接的两个节点所表示的函数之间的调用关系;
[0085] 若第二函数调用图中不存在第一节点,确定第二函数调用图为第一函数调用图;第一节点是入度为0或出度为0的节点;
[0086] 若第二函数调用图中存在第一节点,运行待检测代码,以获得第一函数与另一函数之间的调用关系,并在第二函数调用图中添加用于表示第一函数与另一函数之间的调用关系的有向边,以获得第一函数调用图,第一函数是第一节点所表示的函数。
[0087] 进一步,分析模块81具体可用于:
[0088] 对待检测代码进行静态分析,获得待检测代码在静态时所包含的函数和函数之间的调用关系;
[0089] 根据待检测代码在静态时所包含的函数和函数之间的调用关系,生成第二函数调用图;
[0090] 若第二函数调用图中不存在第一节点,确定第二函数调用图为第一函数调用图;
[0091] 若第二函数调用图中存在第一节点,利用第二插装代码,监控待检测代码的运行过程,以确定第一函数与另一函数之间的调用关系,并在第二函数调用图中添加用于表示第一函数与另一函数之间的调用关系的有向边,以获得第一调用函数。
[0092] 在一可选实施方式中,检测模块84具体可用于:
[0093] 对第一函数调用图进行拓扑排序处理,以获得不包括入度为0的节点的第三函数调用图;
[0094] 若第三函数调用图中存在节点,确定待检测代码中存在调用环路;
[0095] 若第三函数调用图中不存在节点,确定待检测代码中不存在调用环路。
[0096] 在一可选实施方式中,如图8所示,代码检测装置还包括:获得模块82和确定模块83。
[0097] 获得模块82,用于在检测模块84检测到待检测代码中存在调用环路时,获得待检测代码中存在的调用环路的个数;
[0098] 确定模块83,与获得模块82连接,用于根据获得模块82获得的调用环路的个数,确定待检测代码的稳定性等级。
[0099] 本实施例提供的代码检测装置,通过对代码进行动态分析,获得可以表示代码包含的函数以及函数之间调用关系的第一函数调用图,根据第一函数调用图,检测代码中是否存在调用环路。与现有函数内这种局部检测方式相比,本实施例提供的代码检测装置是从全局角度发现代码包含的函数之间是否存在调用环路,而不再局限于函数内的检测,函数之间的调用环路可能导致代码在运行时出现死循环,会严重影响代码的整体性能,因此本实施例提供的代码检测装置通过检测代码中是否存在调用环路达到检测代码的目的,可以极大的提高代码检测的准确度。
[0100] 所属领域的技术人员可以清楚地了解到,为描述的方便和简洁,上述描述的系统,装置和单元的具体工作过程,可以参考前述方法实施例中的对应过程,在此不再赘述。
[0101] 在本申请所提供的几个实施例中,应该理解到,所揭露的系统,装置和方法,可以通过其它的方式实现。例如,以上所描述的装置实施例仅仅是示意性的,例如,所述单元的划分,仅仅为一种逻辑功能划分,实际实现时可以有另外的划分方式,例如多个单元或组件可以结合或者可以集成到另一个系统,或一些特征可以忽略,或不执行。另一点,所显示或讨论的相互之间的耦合或直接耦合或通信连接可以是通过一些接口,装置或单元的间接耦合或通信连接,可以是电性,机械或其它的形式。
[0102] 所述作为分离部件说明的单元可以是或者也可以不是物理上分开的,作为单元显示的部件可以是或者也可以不是物理单元,即可以位于一个地方,或者也可以分布到多个网络单元上。可以根据实际的需要选择其中的部分或者全部单元来实现本实施例方案的目的。
[0103] 另外,在本申请各个实施例中的各功能单元可以集成在一个处理单元中,也可以是各个单元单独物理存在,也可以两个或两个以上单元集成在一个单元中。上述集成的单元既可以采用硬件的形式实现,也可以采用硬件加软件功能单元的形式实现。
[0104] 上述以软件功能单元的形式实现的集成的单元,可以存储在一个计算机可读取存储介质中。上述软件功能单元存储在一个存储介质中,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)或处理器(processor)执行本申请各个实施例所述方法的部分步骤。而前述的存储介质包括:U盘、移动硬盘、只读存储器(Read-Only Memory,ROM)、随机存取存储器(Random Access Memory,RAM)、磁碟或者光盘等各种可以存储程序代码的介质。
[0105] 最后应说明的是:以上实施例仅用以说明本申请的技术方案,而非对其限制;尽管参照前述实施例对本申请进行了详细的说明,本领域的普通技术人员应当理解:其依然可以对前述各实施例所记载的技术方案进行修改,或者对其中部分技术特征进行等同替换;而这些修改或者替换,并不使相应技术方案的本质脱离本申请各实施例技术方案的精神和范围。