一种调试时代码动态更新方法

文档序号:6634604阅读:402来源:国知局
一种调试时代码动态更新方法
【专利摘要】本发明公开了一种调试时代码动态更新方法,在软件开发者调试程序时能够立即更新自己代码的方法,包括以下步骤:步骤一、软件开发者使用调试器调试代码;步骤二、软件开发者在调试时更改代码并保存,触发准备更新过程,激活代码检测模块;编写迁移器模板类,完成迁移器模板类的修改,将更新信息传入虚拟机中;步骤三、调试器请求虚拟机完成代码更新。本发明通过扩展现有的调试器,增加了代码检测模块、编译模块、以及状态迁移器生成模块等部件,在此基础上建立了调试时动态更新代码的系统,并且保证了代码更新过程中的正确性。
【专利说明】一种调试时代码动态更新方法

【技术领域】
[0001]本发明公开了一种调试时代码动态更新方法,属于软件调试【技术领域】。

【背景技术】
[0002]软件调试是重现软件故障、定位故障根源,并最终解决软件问题的过程。调试器是用来提供调试功能的软件或硬件工具。在软件开发的过程中,调试技术是必不可少的技术,一般来说主要的调试命令包括:设定断点,单步执行,观测对象和观测堆栈信息,对于调试器的熟练使用会大大提高软件的开发效率。
[0003]当调试一个项目代码时,单步执行到错误点时,需要修改代码,修改的代码可能是各种各样的类型,这时候如果想继续调试代码,传统的方法是要重启项目,然后再单步执行到上一次调试现场,这会消耗很多时间以及增加很多重复的操作,使得软件开发的效率降低。
[0004]动态更新是从旧的版本更新到新版本的过程。图3是JavaEmailServer从1.3.1版本到1.3.2版本的更新实例,可以从图3中版本a和版本b看出三类变化:第一,是1adUser方法体的变化,第二,是setForwardedAddresses方法的参数发生了变化,第三是 User 类的域 forwardAddresses 从 String []变化到 EmailAddress []。在这三种变化中,对于第三种类的域发生改变的更新类型,当更新类的实例时,一般的做法是将新类中的新增加的域初始化为系统默认的初值(比如整型初始化为0,引用初始化为null)。在这个例子中,如果User实例采用系统默认值的更新,新版本的域forwardAddresses就会被初始化为null,但是从新旧版本的对比中可以看出如果要保持更新前后实例的正确,需要将String[]类型转化为EmailAddress []类型,这时候就需要使用迁移函数,将User实例中的String[]的forwardAddresses转换为新EmailAddress[]类型。从这个例子可以看出,对于一些更新类型,为了保证代码更新的正确性,必须提供特定的迁移器来完成更新。
[0005]现有技术中常用的调试软件包括以下几种:
I)Hotswap:虚拟机本身也支持简单的代码更新,从JDK1.4版本开始存在的调试时动态更新的方法,被称为Hotswap功能,这个功能的局限性在于只支持调试时刻对方法体的改变的更新,这样的更新在调试时是远远不够的,并不能满足所有的更新类型。
[0006]2) DCE VM:能支持任意更新的类型,但是在更新的时候,只提供默认的迁移器,也就是在对象更新的时候将新增的域初始化为系统默认的初值,从上面对图3的例子可以看出这样的更新是不正确的,缺少提供迁移器来供软件开发者参与修改,从而保证更新的正确性。
[0007]3)JRebel:一个商业的软件,官方文档没有具体说明具体的支持的动态更新机制,只是说明JRebel不是从JVM本身出发,而是监控类的字节码文件,通过字节码文件和类加载器来完成更新,不支持通过修改JVM来实现代码的更新。


【发明内容】

[0008]本发明所要解决的技术问题是:针对现有技术的缺陷,提供一种调试时代码动态更新方法,具体是提供一种代码在线更新的方法,使得被更新的程序不需要重新启动即可更新代码,同时提供了对于特定更新类型所需要的迁移器,保证代码更新的正确性。
[0009]本发明为解决上述技术问题采用以下技术方案:
一种调试时代码动态更新方法,包括以下步骤:
步骤一、软件开发者使用调试器调试代码;
步骤二、软件开发者在调试时更改代码并保存,触发准备更新过程,包括代码检测,生成迁移器模板类,完成迁移器模板类的修改,将更新信息传入虚拟机中;
步骤三、调试器请求虚拟机完成代码更新。
[0010]作为本发明的进一步优选方案,步骤二中所述准备更新过程的具体步骤是:
21)软件开发者使用调试器对程序进行调试,通过设断点进行单步调试;
22)调试器监听调试时代码发生改变的事件,当代码发生改变时,响应代码改变的事件,再通过检测获取当前调试代码类文件所在位置,获取更改代码之后的类文件以及更改之前的类文件,将新旧代码类文件存放到临时文夹中;
23)编译存放于临时文件夹中的新旧代码类文件,得到对应新旧代码类文件的字节码文件;
24)通过比较新旧代码的字节码文件得到更新说明文件,进而得到更新类型信息;
25)判断是否需要迁移器来完成代码更新,
当不需要时转入步骤26),否则转入27);
26)判断代码更新不需要迁移器,完成代码更新过程;
27)判断代码更新需要迁移器,生成一个迁移器模板;
28)软件开发者修改迁移器模板类中的代码并保存,编译修改后的迁移器模板类;
29)通知调试器完成对迁移器模板类的修改,更新根据迁移器模板类生成的迁移器类,将迁移器类传入虚拟机。
[0011]作为本发明的进一步优选方案,步骤24)中,所述新旧版本字节码文件的比较包括:方法体的变化、类的方法增加或删除、类域的增加或删除、类结构的变化。
[0012]作为本发明的进一步优选方案,步骤27)中,所述迁移器模板包括下述组成部分:
401、定义的域,一个模板类重定义了新类的所有域,使得在模板的方法中可以自由访问要迁移的对象的各个域;
402、对象迁移方法,为实例方法,用以访问旧类对象的域;
403、类迁移方法,为静态方法,用以在更新后对类的第一次访问中被调用,实现更新静态域;
404、父类,当所述父类发生更新时,模板类将声明该父类。
[0013]作为本发明的进一步优选方案,所述步骤28 )中,软件开发者根据前后代码的不同来修改迁移器的模板类文件,保存修改后的迁移器模板类,编译迁移器模板类得到迁移器模板类的字节码文件。
[0014]作为本发明的进一步优选方案,所述步骤29)的具体步骤包括:
29-1)通过迁移器模板类生成迁移器类,将多个模板类合并成一个迁移器类;
29-2)将合并后的迁移器类所在的位置信息通过消息发送到虚拟机,虚拟机端接收迁移器类,完成更新的准备工作。
[0015]作为本发明的进一步优选方案,所述步骤三的具体步骤包括:
31)调试器在更新准备工作完成后,调用JVMTI中的RedefineClasses接口用修改后的类替换原始的类,首先在堆中找到旧类,找到后悬挂正在执行的程序,通知类加载器加载新类的修改后的版本,通过调用迁移类中对应的迁移方法来实现对该类实例的更新;
32)通过调用JVMTI提供的PopFrame接口使JVM重新执行被修改的方法,恢复现场。
[0016]作为本发明的进一步优选方案,所述调试器的调试代码为Java代码。
[0017]作为本发明的进一步优选方案,步骤21)中,所述单步调试的调试命令包括设断点、单步执行、条件执行、监视对象或者监视堆栈。
[0018]作为本发明的进一步优选方案,所述虚拟机为Javelus。
[0019]本发明采用以上技术方案与现有技术相比,具有以下技术效果:能够支持任意类型的更新;提供迁移器来供软件开发者参与修改,从而保证更新的正确性;以修改JVM来支持代码的更新。本发明所公开的方法支持在调试时修改代码,无需重新启动,使得修改的代码能够动态的更新。

【专利附图】

【附图说明】
[0020]图1为本发明的系统结构以及交互顺序示意图。
[0021]图2为调试器调试时代码更新的执行流程示意图。
[0022]图3 为 JavaEmailServer 两个版本的 User 和 Configurat1nManager 类的变化对比示意图。
[0023]图4为本发明生成的迁移器类模板示意图。
[0024]图5为本发明的一个具体实施例,软件开发者对迁移器类模板做出的修改示例。

【具体实施方式】
[0025]下面详细描述本发明的实施方式,所述实施方式的示例在附图中示出,其中自始至终相同或类似的标号表示相同或类似的元件或具有相同或类似功能的元件。下面通过参考附图描述的实施方式是示例性的,仅用于解释本发明,而不能解释为对本发明的限制。
[0026]下面结合附图对本发明的技术方案做进一步的详细说明:
本发明所基于的虚拟机是Javelus, Javelus是基于Hotspot VM实现了软件运行时刻的动态更新系统。在Hotspot VM虚拟机体系中,调试器通过调用虚拟机提供的JVMTI来获取虚拟机运行时刻的信息,本发明是将虚拟机中JVMTI原有的Hotswap功能(对应于RedefineClasses接口)进行扩展,支持任意更新种类,并且加入了迁移器来完成更新。
[0027]本发明的系统结构以及交互顺序示意图如图1所示,所述的调试时动态更新代码的方法,它包含以下步骤:
1)软件开发者使用调试器调试Java代码;
2)软件开发者在调试时更改代码并保存,触发准备更新过程,包括代码检测,判断是否需要编写需要的迁移器模板类,完成迁移器模板类的修改,将更新信息传入虚拟机中;
3)调试器请求虚拟机完成代码更新,继续调试。
[0028]调试器调试时代码更新的执行流程示意图如图2所示,步骤2)软件开发者在调试时更改代码并保存,触发准备更新过程,激活代码检测模块、判断是否需要编写需要的迁移器模板类,完成迁移器模板类的修改,将更新信息传入虚拟机中的具体步骤是:
21)软件开发者在使用调试器对程序调试时,往往通过设断点来单步调试,常用的调试命令是设断点、单步执行,条件执行,监视对象、监视堆栈等。
[0029]22)调试器在调试程序时,同时监听调试时代码发生改变的事件,当被调试程序代码发生改变时,会响应代码改变的事件,接着调试器通过检测获取当前调试代码类文件所在位置,获取更改代码之后的类文件以及更改之前的类文件,将新旧代码类文件存放到临时文夹中;
23)编译新旧代码类文件,得到对应新旧代码类文件的字节码文件;
24)通过比较新旧代码的字节码文件可以得到更新说明文件,得到的更新类型信息;
25)判断是否需要迁移器来完成代码更新,如果不需要转到26),否则转到27);
26)判断代码更新不需要迁移器,完成准备工作;
27)判断代码更新需要迁移器,生成迁移器模板类;
28)软件开发者修改迁移器模板类中的代码并保存,编译修改的迁移器模板类;
29)通知调试器完成对迁移器模板类的修改,更新根据迁移器模板类生成更新所需要的迁移器类,将迁移器类传入虚拟机。
[0030]步骤24)中,通过比较新旧版本字节码文件得到更新的具体步骤是:比较新旧版本字节码文件中的不同,具体来说有方法体的变化,类的方法增加或删除,类域的增加或删除,类结构发生变化。所获取的变化类型可以是以上变化类型的组合。
[0031]步骤27)中,迁移器模板类生成的具体步骤是:根据新旧版本字节码文件的比较可以得到新类中具体域的增加或删除,生成一个模板类文件,一个类迁移器模板类包含四个主要部分:
1.定义的域:一个模板类重定义了新类的所有域,这样在接下来模板的方法中可以自由访问要迁移的对象的各个域;
2.对象迁移方法:该方法是实例方法,可以访问旧类对象的域;
3.类迁移方法:该方法是静态方法,在更新后对类的第一次访问中被调用,用于更新静态域;
4.父类:如果父类发生更新,则模板类会声明该父类。
[0032]根据图3所示的例子,本方法得到的迁移器模板类如图4所示。
[0033]步骤28)中,软件开发者可以根据前后代码的不同来修改迁移器的模板类文件,根据图3所示的例子步骤26生成了图4的模板类,这时可以根据图3例子中的变化写出图5所示的修改后的迁移器模板类。保存修改后的迁移器模板类,编译迁移器模板类得到迁移器模板类的字节码文件。
[0034]步骤29 )中,根据迁移器模板类类生成更新所需要的迁移器类,将迁移器类传入虚拟机的具体步骤是:
291)迁移器模板类和更新的类重名,不能直接将迁移器模板类加载到运行时刻进行更新,对于多个模板类,会将其合并成一个迁移器类。
[0035]292)将合并后的迁移器类所在的位置信息通过消息发送到虚拟机,虚拟机端接收迁移器类,完成更新的准备工作。
[0036]步骤3)调试器请求虚拟机完成代码更新,继续调试的具体步骤是:
31)调试器在更新准备工作完成以后,通过调用JVMTI中的RedefineClasses接口用修改后的类替换原始的类,具体的执行过程是首先在堆中找到旧类,找到后悬挂正在执行的程序,通知类加载器加载新类的修改后的版本,通过调用迁移类中对应的迁移方法来实现对类实例的更新。
[0037]32)接着通过调用JVMTI提供的PopFrame接口使JVM重新执行被修改的方法,恢复现场,这样一个完整的更新过程完成,调试器会等待软件开发者的下一个调试命令。
[0038]下面给出本发明的一个具体实施例:
本发明是对Java语言调试的支持,Java程序以及调试器需要运行在Javelus虚拟机上。
[0039]软件开发者在一个运行在Javelus虚拟机上的调试器里调试Java代码,一般所涉及到的调试命令是设置断点、单步执行、条件执行、查看指定变量,查看堆栈信息等。当软件开发者在调试到某一步时发现错误根源,这时候如果对代码进行修改然后保存,调试器通过监听调试器代码修改的事件,会触发对代码修改事件的响应。
[0040]接下来就是代码更新准备的阶段,首先获取修改前的类文件以及修改后的类文件存放于临时文件夹中,然后将旧类和新类编译为字节码文件,通过比较新旧字节码文件的不同获得更新信息。
[0041]根据比较字节码文件得到的更新信息来判断是否需要迁移器来完成更新,如果需要迁移器,则生成一个迁移器模板类来帮助软件开发者写迁移器,软件开发者需要修改迁移器模板类后,编译迁移器模板类。然后通知调试器完成对迁移器模板类的修改以及编译,接着将根据迁移器模板类合并生成迁移器类,将迁移器类传入虚拟机完成更新的准备工作。
[0042]最后,调试器在更新准备工作完成以后,通过调用JVMTI中的RedefineClasses接口用修改后的类替换原始的类,对该类的实例更新则通过调用迁移类中对应的迁移方法来实现对象的更新。接着通过调用JVMTI提供的PopFrame接口使JVM重新执行被修改过的方法,恢复现场,这样一个完整的更新过程完成,调试器会等待软件开发者的下一个调试命令,可以继续修改代码并更新代码。
[0043]上面结合附图对本发明的实施方式作了详细说明,但是本发明并不限于上述实施方式,在本领域普通技术人员所具备的知识范围内,还可以在不脱离本发明宗旨的前提下做出各种变化。以上所述,仅是本发明的较佳实施例而已,并非对本发明作任何形式上的限制,虽然本发明已以较佳实施例揭露如上,然而并非用以限定本发明,任何熟悉本专业的技术人员,在不脱离本发明技术方案范围内,当可利用上述揭示的技术内容做出些许更动或修饰为等同变化的等效实施例,但凡是未脱离本发明技术方案内容,依据本发明的技术实质,在本发明的精神和原则之内,对以上实施例所作的任何简单的修改、等同替换与改进等,均仍属于本发明技术方案的保护范围之内。应当注意,为了使本发明更容易理解,上述的描述省略了对于本领域的技术人员来说是公知的、并且对于本发明的实现可能是必须的一些技术细节。
【权利要求】
1.一种调试时代码动态更新方法,其特征在于,包括以下步骤: 步骤一、软件开发者使用调试器调试代码; 步骤二、软件开发者在调试时更改代码并保存,触发准备更新过程,包括代码检测,生成迁移器模板类,完成对迁移器模板类的修改,将更新信息传入虚拟机中; 步骤三、调试器请求虚拟机完成代码更新。
2.根据权利要求1所述的一种调试时代码动态更新方法,其特征在于,步骤二中所述准备更新过程的具体步骤是: 21)软件开发者使用调试器对程序进行调试,通过设断点进行单步调试; 22)调试器监听调试时代码发生改变的事件,当代码发生改变时,响应代码改变的事件,再通过检测获取当前调试代码类文件所在位置,获取更改代码之后的类文件以及更改之前的类文件,将新旧代码类文件存放到临时文夹中; 23)编译存放于临时文件夹中的新旧代码类文件,得到对应新旧代码类文件的字节码文件; 24)通过比较新旧代码的字节码文件得到更新说明文件,进而得到更新类型信息; 25)判断是否需要迁移器来完成代码更新, 当不需要时转入步骤26),否则转入27); 26)判断代码更新不需要迁移器,完成代码更新过程; 27)判断代码更新需要迁移器,生成一个迁移器模板; 28)软件开发者修改迁移器模板类中的代码并保存,编译修改后的迁移器模板类; 29)通知调试器完成对迁移器模板类的修改,更新根据迁移器模板类生成的迁移器类,将迁移器类传入虚拟机。
3.根据权利要求2所述的一种调试时代码动态更新方法,其特征在于,步骤24)中,所述新旧版本字节码文件的比较包括:方法体的变化、类的方法增加或删除、类域的增加或删除、类结构的变化。
4.根据权利要求2所述的一种调试时代码动态更新方法,其特征在于,步骤27)中,所述迁移器模板包括下述组成部分: 401、定义的域,一个模板类重定义了新类的所有域,使得在模板的方法中可以自由访问要迁移的对象的各个域; 402、对象迁移方法,为实例方法,用以访问旧类对象的域; 403、类迁移方法,为静态方法,用以在更新后对类的第一次访问中被调用,实现更新静态域; 404、父类,当所述父类发生更新时,模板类将声明该父类。
5.根据权利要求2所述的一种调试时代码动态更新方法,其特征在于:所述步骤28)中,软件开发者根据前后代码的不同来修改迁移器的模板类文件,保存修改后的迁移器模板类,编译迁移器模板类得到迁移器模板类的字节码文件。
6.根据权利要求2所述的一种调试时代码动态更新方法,其特征在于,所述步骤29)的具体步骤包括: 29-1)通过迁移器模板类生成迁移器类,将多个模板类合并成一个迁移器类; 29-2)将合并后的迁移器类所在的位置信息通过消息发送到虚拟机,虚拟机端接收迁移器类,完成更新的准备工作。
7.根据权利要求1所述的一种调试时代码动态更新方法,其特征在于,所述步骤三的具体步骤包括: 31)调试器在更新准备工作完成后,调用JVMTI中的RedefineClasses接口用修改后的类替换原始的类,首先在堆中找到旧类,找到后悬挂正在执行的程序,通知类加载器加载新类的修改后的版本,通过调用迁移类中对应的迁移方法来实现对该类实例的更新; 32)通过调用JVMTI提供的PopFrame接口使JVM重新执行被修改的方法,恢复现场。
8.根据权利要求1所述的一种调试时代码动态更新方法,其特征在于,所述调试器的调试代码为Java代码。
9.根据权利要求2所述的一种调试时代码动态更新方法,其特征在于,步骤21)中,所述单步调试的调试命令包括设断点、单步执行、条件执行、监视对象或者监视堆栈。
10.根据权利要求1或2所述的一种调试时代码动态更新方法,其特征在于:所述虚拟机为 Javelus。
【文档编号】G06F9/445GK104391717SQ201410656737
【公开日】2015年3月4日 申请日期:2014年11月18日 优先权日:2014年11月18日
【发明者】张同宝, 顾天晓, 马晓星 申请人:南京大学
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1