应用程序的调试方法、调试工具及调试装置的制作方法

文档序号:6468076阅读:165来源:国知局
专利名称:应用程序的调试方法、调试工具及调试装置的制作方法
技术领域
本发明涉及调试领域,更具体地,本发明涉及用于调试软件程序的方法和工具。
背景技术
在软件技术日益普及的今天,调试技术是必不可少的技术。目前,程序员通常依赖 于调试器来进行调试操作。调试器是这样一种应用或系统,其读取系统表并且使得程序员 可以中断(或挂起)被调试的程序的执行以显示和检查代码,计算和编辑程序中的变量, 查看寄存器,以及查看应用程序所占用的内存空间。 一般来说主要的调试操作包括设断 点-当执行到某行代码时中断程序执行(该操作有利于检查错误条件);指定变量-改变 内部程序变量,并且查看程序如何响应;指定观测对象和条件-当满足某个条件时(诸如变 量达到某个值),中断程序执行。 调试器提供的重要帮助在于以调试模式来运行程序。要调试的程序在调试器形成 的容器内运行。调试器用调式模式来启动程序,并且通过与操作系统通信来执行调式操作。 调式模式通常是针对程序员设计的,并且通常包含下述特性其将触发形成针对二进制文 件的符号信息,不使用优化,并且将基于来自操作系统的支持(诸如中断进程)执行附加的 跟踪和调式功能。 目前的调试方法通常需要停止出故障的系统,并且在调试模式下重新启动该系 统,继而执行调试操作。然而,在某些特定的实际应用场景中,这一做法并不一定可行。
例如,在程序执行期间,可能出现各种各样的意料之外的问题。当程序在实际的操 作系统上运行时,开发人员常常会发现各种错误和异常,而即使重启程序,这些错误和异常 也不一定能够复现。这种情况下,需要一种不需要重启应用程序,能够在任何期望的时候进 入调试模式的调试方法和调试工具。 再例如,对于很多已经投入实际运行的大型系统而言,难以避免存在某些漏洞和 缺陷。但是诸如银行软件之类的系统又不允许中断运行,因为重启这些系统对于用户和实 行条件而言是无法容忍的。目前现场支持人员多数通过查看和分析程序日志(log)来查找 问题,但是日志中记录的信息可能非常庞大且不够直观,查看和分析日志不仅费时,而且可 能难以分析出问题所在。这种情况下,需要一种能够与运行中的系统相连的、在不中断系统 运行的情况下就能容易地执行调试的方法和工具。 又例如,在产品上线前的压力测试时,需要在正常运行模式下运行系统并且检查 错误数据。因为压力测试时所加的负载远超过设计的目标平均负载,这种情况下系统容易 进入不确定状态。这种不确定状态往往是很难重复的。这时,需要一种方法和工具,能够部 分地进入调试状态来检查和定位问题,并且在解决问题后,修改后的系统继续以正常模式 运行。

发明内容
本发明的目的在于提供一种新颖的调试方法、调试工具及调试装置,其不需要重启运行中的应用程序,能够在期望的时候进入调试模式。 根据本发明的一方面,提供了一种调试方法,包括步骤接收调试命令,所述调试 命令至少指定运行中的应用程序中被调试的代码;将所述调试命令解释成执行调试命令的 代码;将所述执行调试命令的代码加入运行中的应用程序中被调试的代码;以及执行带有 执行调试命令的代码的应用程序,从而进入调试模式。 根据本发明的第二方面,提供了一种调试装置,包括命令解释器,其用于将接收 的调试命令解释成执行调试命令的代码;以及代码交换器,其用于将所述执行调试命令的 代码加入运行中的应用程序中被调试的代码。 根据本发明的第三方面,提供了一种调试工具,包括调试客户端和上述的调试装 置,其中所述调试客户端包括用于接收调试命令的单元。 根据本发明的第四方面,提供了一种虚拟机,该虚拟机包括上述的调试装置。


通过对结合附图 加明显,本发明附图中,相
图1示意性示出
图2示意性示出
图3示意性示出
图4示意性示出
图5示意性示出
图6示意性示出
图7示意性示出
所示出的实施例进行详细说明,本发明的上述以及其他特征将更 同的标号表示相同或相似的部件。在附图中, 了现有技术的调试器和被调试的应用程序的关系; 了根据本发明一个实施例的调试方法的流程图; 了根据本发明一个实施例的堆数据探测过程; 了根据本发明一个实施例的运行时堆/栈信息探测过程; 了根据本发明一个实施例的修改运行中的应用程序的过程; 了根据本发明一个实施例的调试工具的框图; 了可以实现根据本发明的实施例的计算设备的结构方框图。
具体实施例方式
在下文中,将参考附图通过实施例对本发明的调试方法以及调试工具进行详细的 描述。以下实施例以JAVA环境为例进行说明,所属技术领域的技术人员应当明白,本发明 并不限于JAVA环境。 在现有的调试方法中,当发现实际应用平台上以正常模式运行的一个应用程序出 现问题时,测试人员通常需要停止应用程序的运行。然后,在调试器中以调试模式重新启动 应用程序,调试应用程序,发现并纠正错误。最后,在调试完成后,在实际应用平台上以正常 模式重新启动应用程序。图1示意性示出了调试器100和应用程序APP101的关系。APP 101在调试器100模拟的环境中运行,就象在调试器形成的容器内一样。
调试器100提供的模拟环境不同于实际应用平台上的环境。例如,在现有的JAVA 调试器100模拟的环境中,不允许在运行时进行实时编译(JIT)。调试器100会产生系统表 以返回源代码。调试器100在自己的指令集仿真器上运行程序以便控制程序的运行以及修 改程序计数器。而且,调试器100能够得到操作系统的支持来执行诸如陷入(Tr即)之类的 系统指令。因此,在调试器100中容易读取系统表并且可以中断(或挂起)被调试的APP 101的执行。在中断APP101的执行后,用户可以容易地进行各种调试操作,例如显示和检查 代码,计算和编辑程序中的变量,查看寄存器,以及查看应用程序所占用的内存空间。然而,当应用程序在实际应用平台上以正常模式运行时,中断(或挂起)应用程序的执行变成了
一个难题。这源于以下事实当应用程序以正常模式运行时,实时编译和垃圾回收机制会动
态改变代码;程序计数器是不可写的;得不到操作系统的帮助来执行Trap等系统操作。因
此难以中断以正常模式运行的应用程序的执行,从而难以对正常模式下运行的应用程序进
行调试操作。换言之,现有技术不支持在调试模式和正常模式之间热切换。 本发明提供了一种调试方法,可以在不重新启动应用程序的情况下,对运行中的
应用程序进行调试。运行中的应用程序一般是已经投入到实际应用中的应用程序,例如购
物网站的交易处理程序。运行中的应用程序还可以是运行中的被调试程序,但该被调试程
序不在调试环境中运行而是在运行环境中运行,而通过本发明的调试工具调试。 下面参考图2详细描述本发明的调试方法的一个优选实施例的流程,其中在JVM
上运行的一个应用程序被调试。 在步骤S202,接收调试命令,所述调试命令至少指定运行中的应用程序中被调试 的代码。调试命令的类型可以是设断点、单步执行、条件执行、监视对象、监视堆/栈等等。
例如,用户可以在调试客户端中点击要调试的应用程序的一行源代码以表示在该 行设置断点,希望当程序执行到该行时停止,使程序员可以检查程序的执行状态是否正确。 此外,调试程序还可以提供按钮或菜单,例如〈next st印〉、〈st印into〉按钮或菜单项,从 而命令调试程序进行相应的操作。以下结合用户希望在指定行设置断点的操作进行说明。
调试客户端发送的调试命令至少指定运行中的应用程序被调试的代码。设断点调 试命令中指定被调试的应用程序中要设断点的代码的位置,例如指定设断点的类或函数的 行号。监视对象调试命令则指定应用程序中要监视的对象名称等等。监视堆/栈调试命令 则指定堆/栈、编码的形式和深度等等。此外,调试命令还可以包含实现调试功能的代码、 所要调试的类的源代码或字节码等等。 在调试客户端接收了调试命令后,将调试命令传递至调试装置(下文将参考图6, 对调试装置进行详细说明)。在调试客户端和调试装置在同一机器上的情况下,调试客户 端可以将调试命令直接传输给调试装置。在调试客户端和调试装置在不同的机器上的情况 下,调试客户端将调试命令打包,通过网络传递所述调试命令至调试装置。调试客户端可以 使用各种已知的传输机制来进行传输。这是本领域技术人员熟知的,在这里不作更详细的 描述。 在步骤S204中,调试装置将收到的调试命令解释为执行调试命令的代码。执行测 试命令的代码可以预先存储在存储器(例如一个文件)中,这样,调试装置可以根据调试命 令中的类型,从存储存储器中查找执行该调试命令的代码。执行测试命令的代码还可以与 调试命令一起发送至调试装置。这样,调试装置可以直接将调试命令解释为执行调试命令 的代码。
作为例子,调试装置可以将设断点的调试命令解释成执行设断点的代码如下 示例代码1 : Function breakpoint (){While(true) {〃进入死循环,挂起程序 package = readCo,ndPackageFromUser ();〃等待从用户接收命 令
6cmd = package, command
if (cmd == CONTINUE) {〃在用户命令是继续时,跳出死循环r6turn j
} else if (cmd == GET_PARAM_VALUE) {〃在用户命令是查看对象时,根据对象的名称获取对象的值name = package. params[O]. namevalue = getObjectValueFromJvm(name);response = new ResponsePackage();response, ralue = ralue ^sendResponseRackageToUser0 ;}else if (cmd == GET_STACK_TRACE) {〃在用户命令是查看栈的信息时,获取当前运行的栈的信息
(氺(gdata_>jvmti))_>GetStackTrace(gdata_>jvmti, thread,0, DEPTH,&frames, &frameCount);
response = new ResponsePackage();response.trace = &frames ;response. traceD印th = &frameCount ;sendResponseRackageToUser0 ;

}
}
} 上述代码被插入应用程序中要调试的类中用户指定的需要设置断点的行之前。当应用程序运行到该段代码时挂起。这样,通过该段代码即可实现调试时设置断点的功能。
与设断点命令相似,调试装置也将单步调试命令解释为以上代码,只不过将上述代码插入每个步骤之前,以实现单步执行调试。 调试装置将条件执行命令解释为基本上与设断点代码相同,只是将上述示例代码中的while (true)改成while (条件==用户输入)来实现。 在步骤S206中,调试装置将执行调试命令的代码加入运行中的应用程序中被调试的代码。仍然以设断点为例。调试装置首先找到调试命令中指定的类,例如是类A。如果客户端传送了类A的源代码或其地址,则调试装置在类A的源代码中的指定行,例如第10行前,插入上文例示的执行设断点的代码,得到修改的类A的源代码,然后调用编译器将其编译成字节码。另外,如果客户端只提供了类A的字节码,则可以通过反编译得到类A的源代码。如果客户端只提供了类A的名称,则调试装置可以根据类名称从JVM中的代码存储区找到类A的字节码,然后通过反编译得到源代码。JAVA的反编译和实时编译是技术人员所熟知的,在此不作更详细的描述。 可选地,还可以存储在插入执行调试命令的代码之前的原始的类,并建立和维护被修改的类的列表,以便在将来恢复运行原始的应用程序。 接着,调试装置调用JVM的类装载器重新载入修改后的的类以替代原始的类。例如,这可以通过Redef ineClasses接口来实现。在Redef ineClasses接口的执行过程中,首先在堆(he即)中查找指定的类。找到后(即,指定的类正在执行中),悬挂正在执行的程序,然后通知类装载器从指定的位置重新载入该指定的类的修改后的版本,类装载器可以触发实时编译将重新装载的类的字节码文件即时生效,替换运行中的实时编译过的类的代码。接着通过PopFrame使JVM重新执行改过的方法(注一个类中可以包括一个或多个方法)。如果在堆中没有找到指定的类(B卩,指定的类不在执行中),则通知类装载器从指定的位置重新载入指定的类的修改后的版本。Redef ineClasses和PopFrame接口的参数是修改的类的名称或修改的方法的名称以及用来替换原始定义的类的字节码的文件地址。在所述的例子中,Redef ineClasses和PopFrame接口的参数是类的名称A以及修改后的A的字节码的文件地址。上述的Redef ineClasses接口和PopFrame是JVM提供的现有的API。上述的类装载器是现有技术的JVM的一部分,都是技术人员所熟知的,在此不作更详细的介绍。
在步骤S208中,执行带有执行调试命令的代码的应用程序。当应用程序运行到执行设断点的代码时,中断(挂起)应用程序,以等待接收用户进一步的调试命令。也即,程序从正常运行模式进入调试模式。 此时,由于被调试的应用程序处于等待用户的命令的状态,用户可以输入其他调试命令。例如,通过堆数据探测来查看对象的值。通过运行时堆/栈探测来查看堆/栈的状态,下面将结合图3、4此进行说明。用户还可以根据对应用程序的调试结果而修改应用程序或返回运行程序的原始状态,下面将结合图5对此进行说明。这样本发明即可实现不重启运行中的应用程序,而能够在期望的时候进入调试模式。 图3示出了堆数据探测过程和图4示出了运行时堆/栈信息探测过程。该功能通过上述示例代码1中相关代码实现。 如示例代码1所示,当被调试的应用程序执行breakpoint函数后进入调试模式而等待用户进一步到调试命令。如示例代码1所示,支持用户监测对象的值的代码嵌入在breakpoint函数内。当调试装置从接收到监测对象的调试命令后,根据调试命令中指定的对象名称,通过调用getObjectValueFromJvm(),访问虚拟机内部的内容,获得对象的值,并且将对象的值返回给用户。 同样,支持用户检查运行时的栈的代码也嵌入在示例代码1的breakpoint函数内。其中,根据调试命令中指定的编码形式和深度,通过GetStackTrace()获得栈的信息,并且将栈的信息返回给用户。getObjectValueFromJvm()和GetStackTrace ()是现有的JVM/TI (JavaVirtual Machine/Tool Interface, Java虚拟机/工具接口 )定义的接口。其中,JVM/TI是Java虚拟机提供的用于访问虚拟机内部内容的应用程序接口 (API,Application Programming Interface) 。 TI现在属于Java虚拟机规范的一部分,在任何标准虚拟机中均有实现。利用这些接口,可以实现支持各种调试功能的代理,即通过基于TI编码实现的、经编译后形成的类库(library)。 技术人员容易理解,可以在本发明的执行调试命令的代码中,加入支持其他各种调试功能的代码。例如,支持对运行时堆信息的探测等等。应该注意,上述示出的代码是示例性的,而不是对本发明的限制。在其它实施例中,执行调试命令的代码可以包括更多或更少的功能。 返回图3,详细说明执行堆数据探测的过程。例如,示例代码1中的对象监视通过堆数据探测过程来实现。
在步骤S302中,数据探测器跟踪从堆上进行分配空间产生对象的过程(比如对应 于应用程序的"new object"语句的执行),对产生的每个对象标记一个标识(ID)。数据探 测器的一个实施例可以是利用JVM/TI定义的接口实现的代理(下面简称为JVM/TI代理)。
在步骤S304,调试装置接收用户输入的观察对象的调试命令后,激活数据探测器。 需要注意,当用户发现运行程序的异常想触发即时调试功能时,可以输入观察对象的调试 命令,帮助在进入调试模式后对数据探测器进行初始化,为用户提供数据探测和调试数据 的功能。 在步骤S306中,数据探测器利用对象的ID,在堆中找到要观察的对象,读取其值 和状态。对象的状态是对象的状态属性,例如对象存活的时间长度,来帮助判断是否应该对 该对象进行回收检测以及回收该对象占用的堆空间。
在步骤S308,将观察到的对象值和状态信息返回给用户。 图4说明了调试模式中探测运行时堆/栈信息的过程。例如,示例代码1中的运 行时栈的监视通过运行时栈信息的探测过程来实现。应该理解,运行时堆信息的探测过程 与运行时栈的探测过程类似。 在步骤S402,调试装置接收探测运行时堆/栈信息的调试命令。当应用程序进入 调试模式后,用户可能希望获取当前堆/栈的信息以判断应用程序当前状态。这样,用户通 过调试客户端向调试装置发送探测运行时堆/栈信息的调试命令。 在步骤S404,调试装置从调试命令中获取用户指定的堆/栈的编码形式和深度。 在用户不指定的情况下,可以使用默认的编码形式和深度。 在步骤S406,数据探测器根据所指定的编码形式和深度获得当前运行堆/栈的信
息。如上文已经说明的,数据探测器的一个实施例可以是JVM/TI代理。 在步骤S408,调试装置将当前运行的堆/栈的信息返回给用户。 优选地,本发明的调试方法还包括回退步骤。在回退步骤中,删除插入的执行调试
命令的代码。 在调试完一段程序后,程序员可以删除指定的一个或多个断点。例如,程序员点击 一行源代码上的断点标记表示需要取消在该行设置的断点。于是调试客户端将取消断点的 命令、相关的类和源程序的行号打包传输给调试装置。调试装置根据回退命令删除在该行 前执行设断点命令的代码。然后,调试装置可以调用类加载器重新加载修改后的类。这样, 当再次运行到应用程序的对应行时,应用程序不会在该行挂起,从而删除了该行上的断点。
此外,程序员还可以删除所有断点,以将应用程序恢复到原始状态。例如,程序员 可以点击结束调试的命令,或者直接退出调试窗口,表示希望应用程序返回原始状态。于 是,调试客户端将结束调试的命令传输给调试装置。调试装置根据在步骤S206中存储的被 修改的类列表来确定曾经被修改的类。接着,从所确定的类中删除加入的执行调试命令的 代码。然后,调用JVM的类加载器来重新装载不再包括执行调试命令的代码的类。从而消 除本发明的调试工具对应用程序的代码带来的改变。 可选地,调试装置还可以在每次修改应用程序的时候,存储不含有执行调试命令 的代码的类的版本。于是,在回退步骤中,可以重新加载这些不含有执行调试命令的代码的 类版本,以便消除调试工具对应用程序的改变。然后结束调试模式。
下面结合图5具体说明修改应用程序的过程。
在步骤S502,调试装置接收修改应用程序的调试命令。当程序员在调试过程中发 现了程序中的错误需要修改应用程序时,调试客户端将修改应用程序的命令以及与修改相 关的信息打包成信息包传输给调试装置。其中,与修改相关的信息可以是被修改的完整的 类或其所在的地址。可选地,与修改相关的信息可以是被修改的类的名称和修改的代码及 其行号。 在步骤504中,调试装置确定被修改的类。如果调试客户端传输了完整的类或其 所在的地址,则调试装置可以容易地得到被修改的类。如果调试客户端传输了被修改的类 的名称和修改的代码及其行号,则与步骤S206中描述的情形类似。调试装置可以根据类名 称从JVM中的代码存储区找到所述类的字节码,通过反编译技术得到源代码。接着,根据接 收的修改的代码及其行号,修改所述类的源代码。然后,通过编译器将修改后的类的源代码 编译成字节码。如上面已经提到的,JAVA的反编译技术和JIT是技术人员所熟知的,在此 不作更详细的描述。 可选地,在步骤S504中,还可以存储修改前的类和被修改的类的列表,以及/或者 存储不合用于执行调试命令的代码的类及其类列表。 在步骤S506中,通过调用JVM的类装载器重新载入修改后的类,从而修改了运行
中的应用程序。该修改可以是对应用程序的代码的增加、删除和替换。 在步骤S506,如上面已经提到的,可以通过RedefineClasses接口来实现类的重
新载入。 此外,用户也可以在设断点的同时修改代码。应当理解,设断点的功能是通过修改 应用程序的代码实现的,因此,其他修改应用程序的代码的情形与设断点的过程类似。在 此,不再详细说明。 下面结合图6对本发明的调试系统进行详细说明。 图6示意性示出了可以应用本发明的调试技术的调试工具的一个实施例的结构 框图。本发明的调试工具包括调试客户端610和调试装置620。 调试客户端610和调试装置620可以位于同一机器上。或者,如图6所示,调试客 户端610和调试装置620可以位于不同的机器上,通过网络连接。 调试客户端610作为一个用户接口,用于接收用户的调试命令、发送调试命令至 调试装置、显示调试结果等等。调试客户端610可以是IDE集成开发环境,也可以是一个独 立的调试器。调试客户端610可以是简单的命令行形式,或者是可视的调试窗口。可视的 调试客户端还可以提供按钮或菜单,例如〈next st印〉,〈st印into〉按钮或菜单项。
调试客户端610包括接收单元611和传输单元612。接收单元611用于从用户接 收调试命令。用户可以通过点击按钮、菜单或者源程序所在的行来输入,或者是通过命令行 的形式输入。传输单元612用于发送调试命令至调试装置以及接收从调试装置返回的信 息。其中,传输单元612将调试命令的类型、所要调试的类和源程序的行号、所要监视的对 象等信息打包并传输给调试装置。 调试客户端610和调试装置620可以位于同一机器上。或者,如图6所示,调试客 户端610和调试装置620可以位于不同的机器上,通过网络连接。在此情况下,调试客户端 610的传输单元612还包括命令打包单元6121、数据翻译单元6122和连接管理器6123。连 接管理器6123用于发起调试客户端610与调试装置620之间的连接,并且维护该连接。命令打包单元6121按指定的协议将接收的命令打包成信息包进行传输。数据翻译单元6122 则根据指定的协议从接收的信息包中翻译出要显示的数据。 优选地,调试客户端610还包括显示单元613,用于根据从调试装置返回的信息向 用户显示要观测的对象的值和状态。 调试装置620用于执行调试功能。调试装置620包括命令解释器621和代码交换 器622。调试装置620可以是IDE中的一部分,也可以实现为JVM 630的扩展,从而得到增 强的JVM。 命令解释器621用于将接收的调试命令解释成执行调试命令的代码。例如,如果 调试命令的类型是设断点,则命令解释器将其解释为执行设断点的代码。如果调试命令的 类型是单步执行,则将其解释为N次执行设断点的代码,其中N是被调试的代码的行数目。 如果调试命令的类型是条件执行,则将其解释为执行条件执行的代码。在上文中已经例举 了执行设断点的代码和执行条件执行的代码的例子,在此不再详细描述。在一个优选实施 例中,各种执行调试命令的代码,例如执行设断点的代码、执行条件执行的代码等等,可以 作为代码块存储在命令解释器621中。命令解释器621根据调试命令的类型找到对应的执
行代码。 代码交换器622用于将执行调试代码的代码加入运行中的应用程序中被调试的 代码。代码交换器622首先根据调试命令的类型以及所要调试的类、源程序的行号等信息 修改类,在指定的类的代码中插入所述执行调试命令的代码,得到修改后的类。例如,对于 设断点的命令,代码交换器622在指定的行插入执行设断点的代码。对于单步执行命令,代 码交换器622在被调试的每一行插入执行设断点的代码,如要调试N行代码,则插入N次。 对于条件执行的命令,代码交换器622在指定的行插入执行条件执行的代码。然后,代码交 换器622调用JVM的类装载器重新载入被修改的类以替代运行中的应用程序中的原始的 类。优选地,这可以通过RedefineClasses接口来实现。在用户激活调试功能后,可以用信 号触发代码交换器622。每次用户修改了特定的类或者方法时,将触发Redef ineClasses接 口的调用。在RedefineClasses接口的执行过程中,首先在堆(heap)中查找指定的类,找到 后,悬挂正在执行的程序,通知类装载器631,从指定的位置重新载入指定的类。应当理解, 本发明是通过代码交换器修改应用程序的代码以加入调试命令,其中将修改后的代码加载 到虚拟机是通过调用现有的JVM的类装载器实现的。 在一个实施例中,代码交换器622还可以用于在调试模式下,修改运行中的应用 程序。在另一实施例中,代码交换器622还可以用于在调试结束后,从运行中的应用程序中 删除执行调试命令的代码。应当理解,将执行调试命令的代码加入运行中的应用程序中是 通过修改应用程序的代码实现的,因此,其他修改应用程序的代码的情形与该情形类似。在 此,不再详细说明。 优选地,调试装置620还包括数据探测器623,用于执行堆数据探测和/或执行运 行时堆/栈信息探测。这样,在调试过程中,用户可以输入检查对象的值以及堆/栈的内容 的调试命令。数据探测器623根据用户的调试命令检查对象的值以及堆/栈的内容,并将 对象的值以及堆/栈的内容返回给调试客户端610。数据探测器623的一个优选实施例可 以是利用TI定义的接口实现的代理,即JVM/TI代理。JVM/TI代理在初始化时,跟踪对象生 成,对于每一个产生的对象,打入标记ID。当用户想知道某个对象的值和状态的时候,数据探测器623利用ID和TI接口在堆上查找到需要的对象,读出它的值,返回给用户。每次用户需要获得当前运行堆/栈的信息时,JVM/TI代理将调用TI定义的接口获得当前运行堆/栈的信息,返回给用户。应当理解,数据探测器可以通过JVM提供的各种现有的TI接口来访问虚拟机的内部内容。技术人员容易想到可以利用TI接口实现不同的JVM/TI代理,进行各种数据探测功能。 优选地,调试装置620还包括存储库,用于存储被修改的类的原始代码以及/或者被修改的类的列表。优选地,存储库还可以存储在调试过程中修改的各个版本的类及其记录。当用户期望回退时,代码交换器622可以调用JVM的类装载器重新装载所存储的类的版本之一。 优选地,调试装置620还包括控制器,用于控制调试装置的各个单元的执行,例如控制代码交换器和/或数据探测器的激活和停止。 JVM 630用于执行应用程序。应用程序运行在JVM 630上。JVM包括类装载器631、存储代码的常数池632、堆633以及栈634。代码交换器622将执行调试命令的代码插入对应的类,然后调用JVM上的类装载器631装载修改后的类以替换运行中的应用程序中的原始的类。继而,JVM 630将运行带有执行调试命令的代码的应用程序,从而进入调试模式。在调试模式下,用户可以对应用程序进行各种调试。 以上结合JAVA环境对本发明进行了说明。应当理解本发明还可以应用于其他解释性语言环境,例如,Perl、 PHP、 Ruby、 Python等等。以上所描述的实施例是示例性的,而不是限制性的。所例举的各个步骤不是必不可少的,其顺序也不是限制性的。例如,根据实际的需要,可以定制调试方法,增加或删除某些步骤。或者可以以不同的顺序来执行上述步骤,或者可以并行地执行某些步骤。同样,所例举的调试装置和调试客户端还可以包括更多或更少的单元。 图7示意性示出了可以实现根据本发明的实施例的计算设备的结构方框图。图7中所示的计算机系统包括CPU(中央处理单元)701、 RAM(随机存取存储器)702、 ROM(只读存储器)703、系统总线704,硬盘控制器705、键盘控制器706、串行接口控制器707、并行接口控制器708、显示器控制器709、硬盘710、键盘711、串行外部设备712、并行外部设备713和显示器714。在这些部件中,与系统总线704相连的有CPU 701、RAM 702、R0M 703、硬盘控制器705、键盘控制器706,串行接口控制器707,并行接口控制器708和显示器控制器709。硬盘710与硬盘控制器705相连,键盘711与键盘控制器706相连,串行外部设备712与串行接口控制器707相连,并行外部设备713与并行接口控制器708相连,以及显示器714与显示器控制器709相连。另外需要指出的是,本发明不但可以在个人计算机中实现,而且还应用于大型工作站,或其它带计算功能的设备中实现。 应当注意,为了使本发明更容易理解,上面的描述省略了对于本领域的技术人员
来说是公知的、并且对于本发明的实现可能是必需的更具体的一些技术细节。 提供本发明的说明书的目的是为了说明和描述,而不是用来穷举或将本发明限制
为所公开的形式。对本领域的普通技术人员而言,许多修改和变更都是显而易见的。本领
域技术人员还应该理解,可以通过软件、硬件、固件或者它们的结合的方式,来实现本发明
实施例中的方法和装置。硬件部分可以利用专用逻辑来实现;软件部分可以存储在存储器
中,由适当的指令执行系统,例如微处理器、个人计算机或大型机来执行。
12
因此,应该理解,选择并描述实施例是为了更好地解释本发明的原理及其实际应用,并使本领域普通技术人员明白,在不脱离本发明实质的前提下,所有修改和变更均落入由权利要求所限定的本发明的保护范围之内。
权利要求
一种调试方法,包括步骤接收调试命令,所述调试命令至少指定运行中的应用程序中被调试的代码;将所述调试命令解释成执行调试命令的代码;将所述执行调试命令的代码加入运行中的应用程序中被调试的代码;执行带有执行调试命令的代码的应用程序,从而进入调试模式。
2. 根据权利要求1所述的方法,其中所述调试命令的类型包括设断点、单步执行、条件 执行命令、监视对象和监视堆/栈中的至少一个。
3. 根据权利要求1所述的方法,其中所述将所述执行调试命令的代码加入运行中的应 用程序的步骤进一步包括将执行调试命令的代码插入被调试的类,得到修改的类;以及 由类装载器重新载入所述修改的类以替换被调试的类。
4. 根据权利要求1所述的方法,进一步包括 在调试模式下,修改运行中的应用程序。
5. 根据权利要求2所述的方法,其中在所述调试命令的类型是监视对象时,所述方法 进一步包括跟踪对象生成,对产生的每个对象标记标识; 利用所述标识在堆中找到要监测对象的值和状态。
6. 根据权利要求2所述的方法,其中在所述调试命令的类型是监视堆/栈时,所述方法 进一步包括确定获取堆/栈的编码形式和深度,根据所确定的编码形式和深度获得当前运行堆/栈的信息。
7. 根据权利要求1所述的方法,进一步包括存储所述指定的运行中的应用程序中被调试的代码的原始版本;以及 在调试结束后,由类装载器重新装载存储的所述指定的运行中的应用程序中被调试的 代码的原始版本并恢复运行原始的应用程序。
8. 根据权利要求1所述的方法,进一步包括在所述包括执行调试命令的代码的应用程序代码中删除执行调试命令的代码,获得不 包括执行调试命令的代码的应用程序代码;由类装载器重新装载所述不包括执行调试命令的代码的应用程序代码并继续运行。
9. 一种调试装置,包括命令解释器,其用于将接收的调试命令解释成执行调试命令的代码;以及 代码交换器,其用于将所述执行调试命令的代码加入运行中的应用程序中被调试的代码。
10. 根据权利要求9所述的调试装置,其中所述调试命令的类型包括设断点、单步执行和条件执行命令、监视对象和监视堆/栈 中的至少一个。
11. 根据权利要求9所述的调试装置,其中所述代码交换器进一步将执行调试命令的 代码插入被调试的类,得到修改的类;以及由类装载器重新载入所述修改的类以替换被调 试的类。
12. 根据权利要求9所述的调试装置,所述代码交换器进一步用于在调试模式下,修改 运行中的应用程序。
13. 根据权利要求9所述的调试装置,进一步包括数据探测器,其用于跟踪对象生成, 对产生的每个对象标记标识;以及利用所述标识在堆中找到要监测对象的值和状态。
14. 根据权利要求9所述的调试装置,进一步包括数据探测器,其用于根据指定的编码 形式和深度获得当前运行堆/栈的信息。
15. 根据权利要求9所述的调试装置,还包括存储库,其存储所述运行中的应用程序中被调试的代码的原始版本, 其中所述代码交换器还用于在调试结束后调用类装载器重新装载存储的所述运行中 的应用程序中被调试的代码的原始版本。
16. 根据权利要求9所述的调试装置,所述代码交换器进一步用于在所述包括执行调 试命令的代码的应用程序代码中删除所述执行调试命令的代码,获得不包括执行调试命令 的代码的应用程序代码,以及调用类装载器重新装载所述不包括执行调试命令的代码的应 用程序代码。
17. —种调试工具,包括调试客户端和调试装置,其中所述调试客户端包括用于接收调 试命令的单元,所述调试装置是根据权利要求9-16之一所述的调试装置。
18. 根据权利要求17所述的调试工具,其中所述调试客户端和所述调试装置在不同的 主机上,并且二者通过网络连接。
19. 一种虚拟机,包括根据权利要求9-16之一所述的调试装置。
全文摘要
本发明提供了一种应用程序的调试方法、调试工具及调试装置。该调试方法包括步骤接收调试命令,所述调试命令至少指定运行中的应用程序被调试的代码;将所述调试命令解释成执行调试命令的代码;将所述执行调试命令的代码加入运行中的应用程序中被调试的代码;执行带有执行调试命令的代码的应用程序,从而进入调试模式。该方法不需要重新启动应用程序,有利于调试不便中断运行的系统以及解决会引起运行时出现的不易重复的故障的程序缺陷。
文档编号G06F11/36GK101739333SQ20081017817
公开日2010年6月16日 申请日期2008年11月25日 优先权日2008年11月25日
发明者李欣慧, 肖文鹏, 迟长燕 申请人:国际商业机器公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1