CN113282495A - 一种基于轨迹监控的Java软件故障定位方法 - Google Patents

一种基于轨迹监控的Java软件故障定位方法 Download PDF

Info

Publication number
CN113282495A
CN113282495A CN202110587631.8A CN202110587631A CN113282495A CN 113282495 A CN113282495 A CN 113282495A CN 202110587631 A CN202110587631 A CN 202110587631A CN 113282495 A CN113282495 A CN 113282495A
Authority
CN
China
Prior art keywords
test case
function
track
level
code
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.)
Granted
Application number
CN202110587631.8A
Other languages
English (en)
Other versions
CN113282495B (zh
Inventor
李必信
李渊
王璐璐
孔祥龙
廖力
周颖
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Southeast University
Original Assignee
Southeast University
Priority date (The priority date 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 date listed.)
Filing date
Publication date
Application filed by Southeast University filed Critical Southeast University
Priority to CN202110587631.8A priority Critical patent/CN113282495B/zh
Publication of CN113282495A publication Critical patent/CN113282495A/zh
Application granted granted Critical
Publication of CN113282495B publication Critical patent/CN113282495B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

Images

Classifications

    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/3668Software testing
    • G06F11/3672Test management
    • G06F11/3688Test management for test execution, e.g. scheduling of test suites
    • GPHYSICS
    • G06COMPUTING; CALCULATING OR COUNTING
    • G06FELECTRIC DIGITAL DATA PROCESSING
    • G06F11/00Error detection; Error correction; Monitoring
    • G06F11/36Preventing errors by testing or debugging software
    • G06F11/362Software debugging
    • G06F11/3636Software debugging by tracing the execution of the program

Landscapes

  • Engineering & Computer Science (AREA)
  • Theoretical Computer Science (AREA)
  • Computer Hardware Design (AREA)
  • Quality & Reliability (AREA)
  • Physics & Mathematics (AREA)
  • General Engineering & Computer Science (AREA)
  • General Physics & Mathematics (AREA)
  • Debugging And Monitoring (AREA)

Abstract

本发明公开了一种基于轨迹监控的Java软件故障定位方法,针对Java应用程序构建了二次故障定位算法,首先通过动态插桩技术获取程序的执行轨迹信息,对获取的执行轨迹信息进行预处理,构造出对应的函数调用树,在函数级别对故障进行定位。然后对于可疑度高的函数,进行语句块级别的执行轨迹获取,构建出语句块的控制依赖图,在语句块级别进行故障定位,输出故障定位报告。与现有的故障定位方法相比,本发明方法操作简单,故障定位效果好。

Description

一种基于轨迹监控的Java软件故障定位方法
技术领域
本发明涉及计算机软件自动化调试技术领域,尤其涉及一种基于轨迹监控的Java软件故障定位方法。
背景技术
软件开发过程中进行充分全面的软件测试对于提高软件可靠性,减少软件故障的发生有帮助。在进行软件测试过程中,故障定位是最耗时耗力的阶段。需要故障定位人员进行手工定位,这要求进行故障定位的人员对软件很熟悉,了解软件的执行流程与交互过程,即使这样故障定位的过程也往往耗时耗力。相关调查研究发现,软件开发厂商往往会将软件开发、维护成本的40%~60%投入到软件测试与故障定位和修复中。越到软件开发的后期,进行相关故障的定位和修复所花成本也越大,为了降低开发、维护成本,这就需要提高故障定位的效率,对于自动化故障定位方法的需求也越来越迫切。
目前在软件故障定位领域中,根据故障的数量可分为单故障定位与多故障定位。单故障定位方法假设程序中只有一个故障,找到该故障后即可完成故障定位。这类方法考虑的情形简单,方法实现较多故障定位方法简单。在单故障的情形下,定位效果好,定位时间代价低。单故障定位方法主要可分为以下几类:基于程序切片的故障定位方法、基于程序频谱的故障定位方法、基于模型的故障定位方法。多故障定位比单故障定位更复杂,主要体现在故障数目未知,故障之间的相互叠加影响,往往需要进行多次执行,导致故障定位效率下降。目前故障定位算法研究主要集中在单故障定位领域。
自动化故障定位方法主要具有以下优点:1、简化故障定位的中间过程,降低操作人员的使用要求。2、能够提高故障定位的效率,降低软件开发维护成本。自动化故障定位方法能够根据执行过程的不同,给出故障语句的可疑度排序报告,相关开发人员只需按可疑度由高到低顺序来进行相关代码检查即可,不再需要从头到尾进行检查,提高了故障定位的效率。因此研究一种基于轨迹监控的Java软件故障定位方法,对于提高Java应用程序的故障定位效率,有着重要的意义。
发明内容
本发明的目的是提供一种基于轨迹监控的Java软件故障定位方法,通过动态插桩技术获取Java程序运行时的执行轨迹信息,对轨迹信息进行处理,采用二次故障定位的方式,分别计算出函数级别的可疑度值与语句块级别的可疑度值,并按可疑度值由大到小进行排序,给出相应级别的故障定位报告。
为了实现上述目的,本发明的技术方案如下:一种基于轨迹监控的Java软件故障定位方法,包括如下步骤:
步骤1)运行待测的Java应用程序,利用动态插桩工具向其中织入获取函数级别轨迹信息记录的代码。输入测试用例集合T={t1,t2,...,tn}并执行,获得待测程序运行时函数级别的执行轨迹信息记录集合S={s1,s2,.....,sn}和测试用例的执行结果集合R={r1,r2,...,rn}。;
步骤2)对步骤1)中所获得的S与R,进行预处理,构造出测试用例执行成功的函数调用树Ts与测试用例执行失败的函数调用树Tf,对其进行可疑度计算,函数按照可疑度从大到小进行排序,输出函数级别的故障定位报告;
步骤3)基于步骤2)中获得的函数级别的故障定位报告,选择可疑度高的函数,作为参数输入到动态插桩工具中,动态插桩工具向待测程序中织入获取语句块级别轨迹信息记录的代码;
步骤4)输入测试用例集合T并执行,获得语句块级别的执行轨迹信息记录集合P={p1,p2,...,pn}和测试用例的执行结果集合R;
步骤5)对步骤4)中所获得的P与R,进行预处理,构造出测试用例执行成功的控制依赖图Gs与测试用例执行失败的控制依赖图Gf,对其进行可疑度计算,语句块按照可疑度从大到小进行排序,输出语句块级别的故障定位报告;
进一步的,步骤1)中动态插桩工具向待测程序织入获取函数级别轨迹信息记录的代码,具体如下:
(1)利用JavaAgent技术在Class文件内容加载到JVM时进行拦截,利用第三方字节码修改工具包对拦截的二进制字节码内容进行修改,向每个方法织入二进制字节码形式的函数级别的轨迹信息记录代码。
(2)函数级别的信息记录代码主要包含以下内容:唯一标识这个测试用例的ID;访问的全类名、方法名,格式为“全类名.方法名”;调用该方法的父方法名及父方法所在的全类名,格式为“全类名.父方法名”;异常信息记录代码;获取的信息输出到指定插桩日志文件的代码。
(3)当待测程序运行到插桩点时,会执行织入的代码,进行函数级别的轨迹信息记录,将获取到的轨迹信息输出到指定的插桩日志文件中。
进一步的,步骤2)中对获得的S与R进行预处理,构造出函数调用树,具体如下:
(1)根据轨迹信息记录中记录的测试用例ID,将每个测试用例区分开,将测试用例执行结果Ri与该测试用例函数级别的执行轨迹Si相关联,从而将插桩日志中的轨迹记录分为测试用例执行成功的轨迹记录和测试用例执行失败的轨迹记录两个部分。
(2)针对每一个测试用例的执行轨迹,依次在已有的函数调用树上进行查找。若一个方法a没有符合要求的父方法b,则a为根节点;否则,若a不存在于b的子节点中,则将a添加到b的子节点中,若存在多个子节点,则按字典序的顺序进行排列。针对递归调用的方法,若方法a与函数调用树中父节点b名称相同,则不将a添加到b的子节点中。依次调用上述方法进行合并,最后合并出一棵测试用例执行成功的函数调用树Ts与一棵测试用例执行失败的函数调用树Tf
进一步的,步骤2)中对函数调用树进行可疑度计算,具体如下:
(1)对插桩日志中的轨迹记录进行遍历,抛出异常的轨迹记录可疑度为最高,放在函数级别的故障定位报告最开始。
(2)对于正常执行的方法轨迹记录,采用步骤2)构建的函数调用树进行可疑度计算,具体计算方法如下:
a)根据测试用例执行失败的函数调用树Tf中的树节点Mi去测试用例执行成功的函数调用树Ts中寻找相同位置的树节点Ni,获取以这两个树节点为根节点的子树,对这两棵子树,计算树的编辑距离,记为D(Si,Ti),其中Mi是一个方法,Ni是一个方法,i是该方法的编号,Si代表以Mi为根节点的子树,Ti代表以Ni为根节点的子树。
b)这两棵子树的相似度计算采用如下公式:
Figure BDA0003088340320000041
其中Si代表以Mi为根节点的子树的节点数,Ti代表以Ni为根节点的子树的节点数。
c)函数M的可疑度计算公式:
Figure BDA0003088340320000042
d)采用上述方法,计算出Tf中所有节点的可疑度。
(3)有些方法可能只出现在Ts中,针对这些方法,采用(2)中类似的方法计算函数可疑度值。
进一步的,步骤3)中动态插桩工具向待测程序中织入获取语句块级别轨迹信息记录的代码,具体如下:
(1)动态插桩工具利用JavaAgent技术在Class文件内容加载到JVM时进行拦截,利用第三方字节码修改工具包对拦截的二进制字节码内容进行修改,向指定函数织入二进制字节码形式的语句块级别的轨迹信息记录代码。
(2)进行语句块级别的轨迹信息记录实现思路如下:
a)获取目标方法的JVM指令,向方法的开头插入创建List集合的指令。
b)遍历JVM指令,获取到指令中的分支跳转指令:IF等指令、GOTO指令、GOTO_W指令、LOOKUPSWITCH指令、TABLESWITCH指令、RETURN等指令、ATHROW指令。向IF等指令后和目标跳转位置前;GOTO、GOTO_W指令前;RETURN等、ATHROW指令所在的程序语句前;LOOKUPSWITCH、TABLESWITCH指令中的目标位置,插入向List集合中添加元素的代码,用以记录该语句块是否被执行。
c)调整相关的数据表,使之能够通过JVM校验。
(3)语句块级别的信息记录代码主要包含以下内容:唯一标识这个测试用例的ID;访问的全类名、方法名,格式为“全类名.方法名”;方法执行的语句块级别控制流统计信息;获取的信息输出到指定插桩日志文件的代码。
(4)当待测程序执行到插桩点时,会执行织入的代码,进行语句块级别的轨迹信息记录,将获取到的轨迹信息输出到指定的插桩日志文件中。
进一步的,步骤5)中对获得的P与R进行预处理,构造出控制依赖图,具体如下:
(1)根据轨迹信息记录中记录的测试用例ID,将每个测试用例区分开,将测试用例执行结果Ri与该测试用例语句块级别的执行轨迹Pi相关联,从而将插桩日志中的轨迹记录分为测试用例执行成功的轨迹记录和测试用例执行失败的轨迹记录两个部分。
(2)针对每一条轨迹记录中的控制流信息C:C1→C2→...→C3→C3→C4,在对应方法的控制依赖图G上进行查找。该控制依赖图G是一个带有权值的有向图,现以C中的C1→C2举例,记为S。若G中不存在S,则在G中添加S边,并将边权值设为1;若G中存在S,则将S所在边的权值加一。对于C3→C3这种情况,将其归结为C3一个节点。重复上述步骤,直到对控制流信息处理完毕。此时会生成一个测试用例执行成功的控制依赖图Gs与一个测试用例执行失败的控制依赖图Gf
进一步的,步骤5)中对控制依赖图进行可疑度计算,具体如下:
(1)控制依赖图中的有向边的分布情况主要分为以下三种:
a)该有向边在Gf中存在,在Gs中不存在。该有向边的可疑度为高;
b)该有向边在Gs中存在,在Gf中不存在。该有向边的可疑度为中;
c)该有向边在Gs与Gf中都存在。该有向边的可疑度为低;
(2)可疑度为高、低的有向边e的可疑度值采用如下公式进行计算:
Figure BDA0003088340320000061
可疑度为中的有向边e的可疑度值采用如下公式进行计算:
Figure BDA0003088340320000062
其中Sus(e)代表有向边e的可疑度值,Ncf(e)代表有向边e在Gf中的边权值,Nf代表Gf中的边权值之和,Ncs(e)代表有向边e在Gs中的边权值,Ns代表Gs中的边权值之和。
(3)按上述公式求出所有边的可疑度值,采用如下公式计算控制依赖图中的单个节点的可疑度值:
Sus(Mi)=∑w1*SusH(ei)+∑w2*SusM(ej)+∑w3*SusL(ek);
其中ei、ej、ek表示以节点Mi为始点的边,SusH(ei)代表可疑度高的边ei计算的可疑度值,SusM(ej)代表可疑度中的边ej计算的可疑度值,SusL(ek)代表可疑度低的边ek计算的可疑度值,w1=0.6,w2=0.3,w3=0.1。
有益效果:本发明方法针对Java应用程序,通过JavaAgent技术向待测应用程序插入进行轨迹信息记录的代码,从而获取Java程序运行时的执行轨迹信息。对获取的轨迹记录信息进行处理,分别计算函数级别与语句块级别的可疑度值,并按可疑度值由高到低进行排序,输出相应级别的故障定位报告。本发明方法与现有技术相比,主要有以下一些优点:
(1)不影响待测程序的源代码,待测程序无需重新进行编译。本发明利用JavaAgent技术,对待测软件进行动态插桩,在类加载时,动态修改二进制字节码流,向其中插入进行轨迹信息记录的代码,对源文件无影响,待测程序无需重新编译,节省程序编译时间。
(2)对待测程序性能影响较小。本发明采用二次定位的方式进行软件故障定位,首先进行函数级别的故障定位,只需在函数级别插入轨迹信息记录的代码即可,根据输出的函数级别故障定位报告,选择可疑度高的函数进行语句块级别的故障定位,有利于控制故障定位的范围,减少无关函数插桩对待测程序的性能影响。同时故障定位的级别控制在语句块级别,相对于函数级别定位效果更细致;相对于语句级别,无需向每一条程序语句后插入轨迹信息记录代码,减少了插桩点的数量,能够降低对待测程序性能的影响。
(3)需要的信息较为简单,且易于获取,算法易于实现,故障定位效率高。本发明进行故障定位,只需要函数级别与语句块级别的轨迹记录信息,轨迹记录中包含的相关信息易于获取。故障定位算法计算简便,无需进行复杂模型的构建、神经网络的学习,算法易于实现且故障定位效率高。
附图说明
图1是本发明的流程图。
图2是对函数中语句块插桩的原理图。
图3是根据函数级别的轨迹信息构造出的函数调用树。
图4是根据语句块级别的轨迹信息构造出的控制依赖图。
具体实施方式
为了加深对本发明的认识和理解,下面结合附图对本发明的技术方案进行详细说明:
实施例1:图1给出了本发明的流程图,其中故障定位过程主要包含动态插桩、轨迹信息预处理、可疑度计算、生成故障定位报告四个步骤。根据我们前面提到的步骤,依次实施:
第一步,动态插桩。
动态插桩的主要目的是获取程序的运行轨迹,作为后续操作步骤的输入。动态插桩采用了JavaAgent技术,采用了第三方字节码修改工具包,可以在不影响待测程序源代码的情况下,在类加载时刻修改二进制字节码,向其中插入进行轨迹信息记录的相关代码。由于本故障定位方法采用二次定位的方式,对函数级别的故障定位与语句块级别的故障定位,向其中动态插入的轨迹信息记录代码有所不同。下面分别进行介绍:
(1)函数级别故障定位动态插桩
函数级别的信息记录代码主要包含以下内容:唯一标识这个测试用例的ID;访问的全类名、方法名,格式为“全类名.方法名”;调用该方法的父方法名及父方法所在的全类名,格式为“全类名.父方法名”;异常信息记录代码;获取的信息输出到指定插桩日志文件的代码。
(2)语句块级别故障定位动态插桩
语句块级别的信息记录代码主要包含以下内容:唯一标识这个测试用例的ID;访问的全类名、方法名,格式为“全类名.方法名”;方法执行的语句块级别控制流统计信息;获取的信息输出到指定插桩日志文件的代码。
其中语句块级别的控制流统计信息记录代码采用如下思路进行实现:
a)获取目标方法的JVM指令,向方法的开头插入创建List集合的指令并向其中添加一个元素,证明已经进入该方法。
b)遍历JVM指令,获取到指令中的分支跳转指令:IF等指令、GOTO指令、GOTO_W指令、LOOKUPSWITCH指令、TABLESWITCH指令、RETURN等指令、ATHROW指令。向IF等指令后和目标跳转位置前;GOTO、GOTO_W指令前;RETURN等、ATHROW指令所在的程序语句前;LOOKUPSWITCH、TABLESWITCH指令中的目标位置,插入向List集合中添加元素的代码,用以记录该语句块是否被执行。具体情况如图2所示。
c)调整相关的数据表,使之能够通过JVM校验。
第二步,轨迹信息预处理。
函数级别的轨迹信息预处理的输入为:测试用例执行结果集合R={r1,r2,...,rn},函数级别的执行轨迹信息记录集合S={s1,s2,.....,sn}。输出为测试用例执行成功的函数调用树Ts与测试用例执行失败的函数调用树Tf
语句块级别的轨迹信息预处理的输入为:测试用例执行结果集合R={r1,r2,...,rn},语句块级别的执行轨迹信息记录集合P={p1,p2,...,pn}。输出为测试用例执行成功的控制依赖图Gs与测试用例执行失败的控制依赖图Gf
轨迹信息预处理主要是将执行成功与执行失败的测试用例轨迹记录进行分离,然后分别进行处理,生成可疑度计算需要的输入。函数级别的轨迹记录信息,需要经过预处理生成函数调用树,语句块级别的轨迹记录信息,需要经过预处理生成控制依赖图。
第三步,可疑度计算。
函数级别可疑度计算的输入为测试用例执行成功的函数调用树Ts与测试用例执行失败的函数调用树Tf,输出为函数的可疑度值。
语句块级别可疑度计算的输入为测试用例执行成功的控制依赖图Gs与测试用例执行失败的控制依赖图Gf,输出为语句块的可疑度值。
可疑度计算是本方法的核心,故障定位报告将按照可疑度值进行排序。针对不同级别的故障定位,采用不同的可疑度计算方法。
(1)函数级别可疑度计算
a)对插桩日志中的轨迹记录进行遍历,抛出异常的轨迹记录可疑度为最高,放在函数级别的故障定位报告最开始。
b)对于正常执行的方法轨迹记录,根据测试用例执行失败的函数调用树Tf中的树节点Mi去测试用例执行成功的函数调用树Ts中寻找相同位置的树节点Ni,获取以这两个树节点为根节点的子树,对这两棵子树,计算树的编辑距离,记为D(Si,Ti),其中Mi是一个方法,Ni是一个方法,i是该方法的编号,Si代表以Mi为根节点的子树,Ti代表以Ni为根节点的子树。
c)这两棵子树的相似度计算采用如下公式:
Figure BDA0003088340320000111
其中Si代表以Mi为根节点的子树的节点数,Ti代表以Ni为根节点的子树的节点数。
d)函数M的可疑度计算公式:
Figure BDA0003088340320000112
e)采用上述方法,计算出Tf中所有节点的可疑度。
f)有些方法可能只出现在Ts中,针对这些方法,采用b)到e)中类似的方法计算函数可疑度值。
(2)语句块级别可疑度计算
根据测试用例执行成功的控制依赖图Gs与一个测试用例执行失败的控制依赖图Gf,计算语句块的可疑度值时,分为了三类:可疑度高、可疑度中、可疑度低。这是由于控制依赖图中的有向边的分布情况主要分为以下三种:
a)该有向边在Gf中存在,在Gs中不存在。该有向边的可疑度为高。
b)该有向边在Gs中存在,在Gf中不存在。该有向边的可疑度为中。
c)该有向边在Gs与Gf中都存在。该有向边的可疑度为低。
可疑度为高、低的有向边e的可疑度值采用如下公式进行计算:
Figure BDA0003088340320000113
可疑度为中的有向边e的可疑度值采用如下公式进行计算:
Figure BDA0003088340320000114
其中Sus(e)代表有向边e的可疑度值,Ncf(e)代表有向边e在Gf中的边权值,Nf代表Gf中的边权值之和,Ncs(e)代表有向边e在Gs中的边权值,Ns代表Gs中的边权值之和。
(3)按上述公式求出所有边的可疑度值,采用如下公式计算控制依赖图中的单个节点的可疑度值:
Sus(Mi)=∑w1*SusH(ei)+∑w2*SusM(ej)+∑w3*SusL(ek)
其中ei、ej、ek表示以节点Mi为始点的边,SusH(ei)代表可疑度高的边ei计算的可疑度值,SusM(ej)代表可疑度中的边ej计算的可疑度值,SusL(ek)代表可疑度低的边ek计算的可疑度值,w1=0.6,w2=0.3,w3=0.1。
第四步,生成故障定位报告。
生成故障定位报告的输入为可疑度值,输出为相应级别的故障定位报告。
故障定位报告的主要作用是在软件故障定位时,供故障定位人员进行参考。将函数级别的可疑度值按由大到小的顺序进行排序,输出函数级别的故障定位报告;将语句块级别的可疑度值按由大到小的顺序进行排序,输出语句块级别的故障定位报告。
具体实施例:
为了方便描述,我们假定有如下简化的应用实例:
目标软件已经进行过动态插桩,生成出对应级别的执行轨迹信息,并对轨迹进行进行了预处理,生成了函数调用树,如图3所示。对图三中的methodC方法生成了控制依赖图,如图4所示。
(1)根据函数调用树进行函数级别的可疑度计算如下:
a)计算节点的树编辑距离。计算结果如下:
methodA:3
methodB:1,1
methodC:2
methodD:1,1
因为树中两个地方存在methodB与methodD,因此该节点需要分别计算树编辑距离。
b)计算方法的可疑度值。
函数M的可疑度计算公式:
Figure BDA0003088340320000131
由公式可知函数M的可疑度值等于树中M节点的相似度之和,计算结果如下:Sus(methodA)
=3/(4+5)=0.333
Sus(methodB)=1/(0+1)+1/(2+1)=1.333
Sus(methodC)=2/(3+3)=0.333
Sus(methodD)=1/(1+0)+1/(1+0)=2
c)按可疑度值由大到小排序,生成故障定位的结果。这里排序之后,生成的结果为:methodD,methodB,methodC,methodA。
(2)根据控制依赖图进行语句块级别的可疑度计算如下;
a)计算各边在对应的控制依赖图中所占的比率。
Nf=1+2+3+2=8,Ns=2+3+1+2+2=10,
rcf(e1,2)=1/8=0.125,rcf(e2,3)=2/8=0.25,
rcf(e2,4)=3/8=0.375,rcf(e4,3)=2/8=0.25,
rcs(e1,2)=2/10=0.2,rcs(e2,3)=3/10=0.3,
rcs(e2,5)=1/10=0.1,rcs(e3,5)=2/10=0.2,
rcs(e5,3)=2/10=0.2
b)计算控制依赖图中有向边的可疑度值。
Figure BDA0003088340320000141
Figure BDA0003088340320000142
Figure BDA0003088340320000143
Figure BDA0003088340320000144
Figure BDA0003088340320000145
Figure BDA0003088340320000146
Figure BDA0003088340320000147
c)计算控制依赖图中单个节点的可疑度值。
Sus(M1)=0.1*0.219=0.0219
Sus(M2)=0.6*0.612+0.3*0.316+0.1*0.337=0.4957
Sus(M3)=0.3*0.447=0.1341
Sus(M4)=0.6*0.5=0.3
Sus(M5)=0.3*0.447=0.1341
d)按可疑度值由大到小对语句块进行排序,生成故障定位的结果。这里排序之后,生成的结果为:2,4,3,5,1。
需要说明的是上述实施例仅仅是本发明的优选实施例,对于本技术领域的普通技术人员来说,在不脱离本发明原理的前提下,还可以做出若干改进和等同替换,这些对本发明权利要求进行改进和等同替换后的技术方案,均属于本发明的保护范围。

Claims (7)

1.一种基于轨迹监控的Java软件故障定位方法,其特征在于,该方法包括如下步骤:
步骤1)运行待测的Java应用程序,利用动态插桩工具向其中织入获取函数级别轨迹信息记录的代码,输入测试用例集合T={t1,t2,...,tn}并执行,获得待测程序运行时函数级别的执行轨迹信息记录集合S={s1,s2,.....,sn}和测试用例的执行结果集合R={r1,r2,...,rn};
步骤2)对步骤1)中所获得的S与R,进行预处理,构造出测试用例执行成功的函数调用树Ts与测试用例执行失败的函数调用树Tf,对其进行可疑度计算,函数按照可疑度从大到小进行排序,输出函数级别的故障定位报告;
步骤3)基于步骤2)中获得的函数级别的故障定位报告,选择可疑度高的函数,作为参数输入到动态插桩工具中,动态插桩工具向待测程序中织入获取语句块级别轨迹信息记录的代码;
步骤4)输入测试用例集合T并执行,获得语句块级别的执行轨迹信息记录集合P={p1,p2,...,pn}和测试用例的执行结果集合R;
步骤5)对步骤4)中所获得的P与R,进行预处理,构造出测试用例执行成功的控制依赖图Gs与测试用例执行失败的控制依赖图Gf,对其进行可疑度计算,语句块按照可疑度从大到小进行排序,输出语句块级别的故障定位报告。
2.根据权利要求1中所述的故障定位方法,其特征在于:所述步骤1)中动态插桩工具向待测程序织入获取函数级别轨迹信息记录的代码,具体如下:
(1)利用JavaAgent技术在Class文件内容加载到JVM时进行拦截,利用第三方字节码修改工具包对拦截的二进制字节码内容进行修改,向每个方法织入二进制字节码形式的函数级别的轨迹信息记录代码,
(2)函数级别的信息记录代码主要包含以下内容:唯一标识这个测试用例的ID;访问的全类名、方法名,格式为“全类名.方法名”;调用该方法的父方法名及父方法所在的全类名,格式为“全类名.父方法名”;异常信息记录代码;获取的信息输出到指定插桩日志文件的代码,
(3)当待测程序运行到插桩点时,会执行织入的代码,进行函数级别的轨迹信息记录,将获取到的轨迹信息输出到指定的插桩日志文件中。
3.根据权利要求1中所述的故障定位方法,其特征在于:所述步骤2)中对获得的S与R进行预处理,构造出函数调用树,具体如下:
(1)根据轨迹信息记录中记录的测试用例ID,将每个测试用例区分开,将测试用例执行结果Ri与该测试用例函数级别的执行轨迹Si相关联,从而将插桩日志中的轨迹记录分为测试用例执行成功的轨迹记录和测试用例执行失败的轨迹记录两个部分;
(2)针对每一个测试用例的执行轨迹,依次在已有的函数调用树上进行查找,若一个方法a没有符合要求的父方法b,则a为根节点;否则,若a不存在于b的子节点中,则将a添加到b的子节点中,若存在多个子节点,则按字典序的顺序进行排列,针对递归调用的方法,若方法a与函数调用树中父节点b名称相同,则不将a添加到b的子节点中,依次调用上述方法进行合并,最后合并出一棵测试用例执行成功的函数调用树Ts与一棵测试用例执行失败的函数调用树Tf
4.根据权利要求1中所述的故障定位方法,其特征在于:所述步骤2)中对函数调用树进行可疑度计算,具体如下:
(1)对插桩日志中的轨迹记录进行遍历,抛出异常的轨迹记录可疑度为最高,放在函数级别的故障定位报告最开始,
(2)对于正常执行的方法轨迹记录,采用步骤2)构建的函数调用树进行可疑度计算,具体计算方法如下:
a)根据测试用例执行失败的函数调用树Tf中的树节点Mi去测试用例执行成功的函数调用树Ts中寻找相同位置的树节点Ni,获取以这两个树节点为根节点的子树,对这两棵子树,计算树的编辑距离,记为D(Si,Ti),其中Mi是一个方法,Ni是一个方法,i是该方法的编号,Si代表以Mi为根节点的子树,Ti代表以Ni为根节点的子树,
b)这两棵子树的相似度计算采用如下公式:
Figure FDA0003088340310000031
其中|Si|代表以Mi为根节点的子树的节点数,|Ti|代表以Ni为根节点的子树的节点数,
c)函数M的可疑度计算公式:
Figure FDA0003088340310000032
d)采用上述方法,计算出Tf中所有节点的可疑度,
(3)有些方法可能只出现在Ts中,针对这些方法,采用(2)中类似的方法计算函数可疑度值。
5.根据权利要求1中所述的故障定位方法,其特征在于:所述步骤3)中动态插桩工具向待测程序中织入获取语句块级别轨迹信息记录的代码,具体如下:
(1)动态插桩工具利用JavaAgent技术在Class文件内容加载到JVM时进行拦截,利用第三方字节码修改工具包对拦截的二进制字节码内容进行修改,向指定函数织入二进制字节码形式的语句块级别的轨迹信息记录代码,
(2)进行语句块级别的轨迹信息记录实现思路如下:
a)获取目标方法的JVM指令,向方法的开头插入创建List集合的指令,
b)遍历JVM指令,获取到指令中的分支跳转指令:IF等指令、GOTO指令、GOTO_W指令、LOOKUPSWITCH指令、TABLESWITCH指令、RETURN等指令、ATHROW指令;向IF等指令后和目标跳转位置前;GOTO、GOTO_W指令前;RETURN等、ATHROW指令所在的程序语句前;LOOKUPSWITCH、TABLESWITCH指令中的目标位置,插入向List集合中添加元素的代码,用以记录该语句块是否被执行,
c)调整相关的数据表,使之能够通过JVM校验,
(3)语句块级别的信息记录代码主要包含以下内容:唯一标识这个测试用例的ID;访问的全类名、方法名,格式为“全类名.方法名”;方法执行的语句块级别控制流统计信息;获取的信息输出到指定插桩日志文件的代码,
(4)当待测程序执行到插桩点时,会执行织入的代码,进行语句块级别的轨迹信息记录,将获取到的轨迹信息输出到指定的插桩日志文件中。
6.根据权利要求1中所述的故障定位方法,其特征在于:所述步骤5)中对获得的P与R进行预处理,构造出控制依赖图,具体如下:
(1)根据轨迹信息记录中记录的测试用例ID,将每个测试用例区分开,将测试用例执行结果Ri与该测试用例语句块级别的执行轨迹Pi相关联,从而将插桩日志中的轨迹记录分为测试用例执行成功的轨迹记录和测试用例执行失败的轨迹记录两个部分,
(2)针对每一条轨迹记录中的控制流信息C:C1→C2→...→C3→C3→C4,在对应方法的控制依赖图G上进行查找,该控制依赖图G是一个带有权值的有向图,现以C中的C1→C2举例,记为S,若G中不存在S,则在G中添加S边,并将边权值设为1;若G中存在S,则将S所在边的权值加一,对于C3→C3这种情况,将其归结为C3一个节点,重复上述步骤,直到对控制流信息处理完毕,此时会生成一个测试用例执行成功的控制依赖图Gs与一个测试用例执行失败的控制依赖图Gf
7.根据权利要求1中所述的故障定位方法,其特征在于:所述步骤5)中对控制依赖图进行可疑度计算,具体如下:
(1)控制依赖图中的有向边的分布情况主要分为以下三种:
a)该有向边在Gf中存在,在Gs中不存在,该有向边的可疑度为高,
b)该有向边在Gs中存在,在Gf中不存在,该有向边的可疑度为中,
c)该有向边在Gs与Gf中都存在,该有向边的可疑度为低,
(2)可疑度为高、低的有向边e的可疑度值采用如下公式进行计算:
Figure FDA0003088340310000051
可疑度为中的有向边e的可疑度值采用如下公式进行计算:
Figure FDA0003088340310000052
其中Sus(e)代表有向边e的可疑度值,Ncf(e)代表有向边e在Gf中的边权值,Nf代表Gf中的边权值之和,Ncs(e)代表有向边e在Gs中的边权值,Ns代表Gs中的边权值之和,
(3)按上述公式求出所有边的可疑度值,采用如下公式计算控制依赖图中的单个节点的可疑度值:
Sus(Mi)=∑w1*SusH(ei)+∑w2*SusM(ej)+∑w3*SusL(ek),
其中ei、ej、ek表示以节点Mi为始点的边,SusH(ei)代表可疑度高的边ei计算的可疑度值,SusM(ej)代表可疑度中的边ej计算的可疑度值,SusL(ek)代表可疑度低的边ek计算的可疑度值,w1=0.6,w2=0.3,w3=0.1。
CN202110587631.8A 2021-05-27 2021-05-27 一种基于轨迹监控的Java软件故障定位方法 Active CN113282495B (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN202110587631.8A CN113282495B (zh) 2021-05-27 2021-05-27 一种基于轨迹监控的Java软件故障定位方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN202110587631.8A CN113282495B (zh) 2021-05-27 2021-05-27 一种基于轨迹监控的Java软件故障定位方法

Publications (2)

Publication Number Publication Date
CN113282495A true CN113282495A (zh) 2021-08-20
CN113282495B CN113282495B (zh) 2024-03-22

Family

ID=77282252

Family Applications (1)

Application Number Title Priority Date Filing Date
CN202110587631.8A Active CN113282495B (zh) 2021-05-27 2021-05-27 一种基于轨迹监控的Java软件故障定位方法

Country Status (1)

Country Link
CN (1) CN113282495B (zh)

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN117112448A (zh) * 2023-10-18 2023-11-24 浙江东安检测技术有限公司 基于森林算法的软件测试故障定位方法、系统及介质

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20040230961A1 (en) * 2003-05-14 2004-11-18 International Business Machines Corporation Testing parallel applications using code instrumentation
CN101739339A (zh) * 2009-12-29 2010-06-16 北京航空航天大学 一种基于程序动态依赖关系的软件故障定位方法
CN111026601A (zh) * 2019-09-23 2020-04-17 拉扎斯网络科技(上海)有限公司 Java应用系统的监控方法、装置、电子设备及存储介质

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20040230961A1 (en) * 2003-05-14 2004-11-18 International Business Machines Corporation Testing parallel applications using code instrumentation
CN101739339A (zh) * 2009-12-29 2010-06-16 北京航空航天大学 一种基于程序动态依赖关系的软件故障定位方法
CN111026601A (zh) * 2019-09-23 2020-04-17 拉扎斯网络科技(上海)有限公司 Java应用系统的监控方法、装置、电子设备及存储介质

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN117112448A (zh) * 2023-10-18 2023-11-24 浙江东安检测技术有限公司 基于森林算法的软件测试故障定位方法、系统及介质
CN117112448B (zh) * 2023-10-18 2024-01-30 浙江东安检测技术有限公司 基于森林算法的软件测试故障定位方法、系统及介质

Also Published As

Publication number Publication date
CN113282495B (zh) 2024-03-22

Similar Documents

Publication Publication Date Title
CN109063477B (zh) 一种自动化的智能合约代码缺陷检测系统和方法
US8898647B2 (en) Method and apparatus for test coverage analysis
CN109144882B (zh) 一种基于程序不变量的软件故障定位方法及装置
Schäfer et al. An empirical evaluation of using large language models for automated unit test generation
US8312440B2 (en) Method, computer program product, and hardware product for providing program individuality analysis for source code programs
US8732676B1 (en) System and method for generating unit test based on recorded execution paths
Xie et al. ChatUniTest: a ChatGPT-based automated unit test generation tool
CN111459799A (zh) 一种基于Github的软件缺陷检测模型建立、检测方法及系统
CN110543421A (zh) 基于测试用例自动生成算法的单元测试自动执行方法
CN110399286B (zh) 一种基于独立路径的测试数据自动生成方法
CN105302719A (zh) 一种变异测试方法及装置
Omar et al. HOMAJ: A tool for higher order mutation testing in AspectJ and Java
CN112131120B (zh) 一种源代码缺陷检测方法及装置
CN111581086B (zh) 一种基于RankNet的混合软件错误定位方法及系统
Di Nardo et al. Generating complex and faulty test data through model-based mutation analysis
CN116431476A (zh) 一种基于代码上下文变异的jvm模糊测试方法
Cheon Automated random testing to detect specification-code inconsistencies
CN108563561A (zh) 一种程序隐性约束提取方法及系统
CN113282495A (zh) 一种基于轨迹监控的Java软件故障定位方法
US6889219B2 (en) Method of tuning a decision network and a decision tree model
Xu et al. AJANA: a general framework for source-code-level interprocedural dataflow analysis of AspectJ software
Singhal et al. A critical review of various testing techniques in aspect-oriented software systems
CN115310095A (zh) 一种区块链智能合约混合形式化验证方法及系统
CN115098355A (zh) 基于历史数据驱动的jvm测试程序生成方法
CN114281709A (zh) 一种单元测试方法、系统、电子设备及存储介质

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
GR01 Patent grant
GR01 Patent grant