一种嵌入式环境下基于检查点的调试方法、系统及装置与流程

文档序号:11950035阅读:253来源:国知局
一种嵌入式环境下基于检查点的调试方法、系统及装置与流程

本发明属于计算机的应用程序调试方法,更具体地,涉及一种嵌入式环境下基于检查点的调试方法、系统及装置。



背景技术:

随着信息化,智能化,网络化的发展,嵌入式系统技术获得了广泛的发展空间。例如,在金融、交通、电力和军事等重要领域,嵌入式软件得到了广泛的应用,已经成为影响国家发展和安全的重要基础设施。其中许多关键的任务的完成均依赖于嵌入式应用程序,如果这些应用程序出现故障,会对生活和生产产生许多影响,提高嵌入式应用的稳定性和可靠性变得尤为重要。

有很多大型嵌入式应用程序的运行时间很长,一旦这些程序遇到故障,从头开始调试会浪费大量的等待时间。为了降低等待时间并且使得错误能够准确再现,程序执行的确定性需要得到保证。由于嵌入式系统比普通系统更加精简,对实时性有更高的要求,在嵌入式系统中检查点功能需要更快地执行速度来满足嵌入式系统的实时性,因此,相对于普通系统来说,实现起来更加困难。

现有的嵌入式环境下的检查点技术通常是对单个进程设置检查点,而对其并发的子进程在设置在检查点时不能保证全局一致性,每个进程保存了多个不同时刻的检查点文件,在检查点恢复的时候可能会出现重复卷回,最终使得应用程序恢复到应用程序运行的初始状态而非检查点保存的状态,从而使得检查点恢复操作失败。



技术实现要素:

针对现有技术的以上缺陷或改进需求,本发明提供了一种基于检查点的调试方法、装置及系统,其目的在于通过宿主机与目标机的交互,在目标机上设置检查点,并用检查点文件保存应用程序对应的进程的上下文信息,使得重新开始调试时,应用程序可以直接恢复到检查点处运行,而不必从头开始程序的执行,从而减少了调试时的等待时间,可以有效地缩短应用程序的调试周期。

为实现上述目的,按照本发明的一个方面,提供了一种基于检查点的调试方法,包括以下步骤:

(1)宿主机向目标机发出第一指令,令目标机上的应用程序开始运行,令检查点的序号i=1;

(2)宿主机接收外部的命令,并判断所述命令的类型;如果所述命令为保存命令,则进入步骤(3);如果所述命令为调试命令,则进入步骤(4);如果所述命令为恢复命令,则进入步骤(5);如果所述命令为退出命令,则入步骤(7);否则进入步骤(6);

(3)宿主机向目标机发出第二指令,令目标机在应用程序的当前位置创建第i检查点,并将所述应用程序对应的进程的上下文信息保存于对应第i检查点的第i检查点文件中;i=i+1,返回步骤(2);所述进程包括父进程以及所述父进程的子进程;

(4)宿主机向目标机发出第三指令,令所述目标机在应用程序的当前位置调试,并向宿主机返回调试结果,宿主机将所述调试结果输出,返回步骤(2);

(5)宿主机向目标机发出第四指令,令所述目标机从第j检查点文件中恢复应用程序对应的进程的上下文信息,并将应用程序运行的当前位置恢复至第j检查点,j为1~i的整数,返回步骤(2);

(6)宿主机向外部发出报错指令,返回步骤(2);

(7)宿主机向目标机发出第五指令,结束目标机上应用程序的运行。

优选地,在所述步骤(1)之前还包括,将宿主机连接至目标机。

优选地,所述应用程序包括目标应用程序以及并发应用程序。

优选地,所述步骤(3)中的上下文信息包括进程的状态、进程的用户变量、进程在寄存器中的地址、进程在进程表项的用户栈以及内核栈中的地址。

作为进一步优选地,所述进程的状态包括进程头、进程的线程、进程的线程的父子关系、进程的线程的共享数据和私有数据。

优选地,所述步骤(4)具体包括如下子步骤:

(4.1)根据调试命令的种类,宿主机向目标机发出第三指令,令所述目标机在应用程序运行的当前位置进行相应种类的调试;

(4.2)在设定的时间段Δt内,宿主机判断是否收到目标机返回的调试结果,是则进入步骤(4.3),否则返回步骤(4.1);

(4.3)宿主机将所述调试结果反馈给外部,返回步骤(2)。

作为进一步优选地,所述调试命令的种类包括条件断点、进入函数、跳出函数、设置观察点、线程核绑定、插入断点、查询断点、单步执行、持续执行、执行至结束、删除断点、查看变量、查看线程运行核、获取核运行线程或统计线程运行时间。

按照本发明的另一方面,还提供了一种基于检查点的调试系统,包括宿主机以及目标机,所述目标机包括解析模块、运行模块、检查点模块以及调试模块;

所述宿主机用于向解析模块发出第一指令、第二指令、第三指令、第四指令以及第五指令,同时接收解析模块返回的运行结果以及调试结果;

所述解析模块用于将第一指令以及第五指令发送给运行模块,第二指令以及第四指令发送给检查点模块,第三指令发送给调试模块;并将运行结果以及调试结果反馈至宿主机;

所述运行模块用于根据第一指令运行应用程序,以及根据第五指令结束应用程序;并在应用程序运行结束时,向解析模块输出运行结果;同时根据恢复指令,将应用程序运行的当前位置恢复至检查点处;

所述检查点模块用于根据第二指令,在应用程序的当前位置创建检查点,并将所述应用程序对应的进程的上下文信息保存于检查点文件中,同时根据第四指令,从检查点文件中恢复应用程序对应的进程的上下文信息,并向运行模块发出恢复指令;

所述调试模块用于在应用程序的当前位置调试,并向解析模块输出调试结果。

按照本发明的另一方面,还提供了一种用于上述调试装置的调试装置,包括解析模块、运行模块、检查点模块以及调试模块;

所述解析模块用于将第一指令以及第五指令发送给运行模块,第二指令以及第四指令发送给检查点模块,第三指令发送给调试模块;并将运行结果以及调试结果反馈至宿主机;

所述运行模块用于根据第一指令运行应用程序,以及根据第五指令结束应用程序;并在应用程序运行结束时,向解析模块输出运行结果;同时根据恢复指令,将应用程序运行的当前位置恢复至检查点处;

所述检查点模块用于根据第二指令,在应用程序的当前位置创建检查点,并将所述应用程序对应的进程的上下文信息保存于检查点文件中,同时根据第四指令,从检查点文件中恢复应用程序对应的进程的上下文信息,并向运行模块发出恢复指令;

所述调试模块用于在应用程序的当前位置调试,并向解析模块输出调试结果。

总体而言,通过本发明所构思的以上技术方案与现有技术相比,由于在调试过程中设置检查点,能够取得下列有益效果:

1、通过宿主机与目标机的交互,并直接在目标机上设置检查点以及创建检查点文件,使得在嵌入式环境下进行调试时,应用程序可以直接恢复到检查点对应的应用程序的位置处运行,而不必从头开始执行应用程序,从而减少了调试时的等待时间,可以有效地缩短应用程序的调试周期;

2、本发明将进程的状态、进程的用户变量、进程在寄存器中的地址、进程在进程表项的用户栈以及内核栈中的地址均作为上下文信息保存于检查点文件中,使得本发明不依赖于操作系统运行,目标机既可以运行在X86等英特尔芯片架构上,也可以运行在国产龙芯等mips架构上,具有广泛的适用性;

3、本发明可以根据外部指令,对目标机发出多种调试命令,适用于多种调试类型;

4、本发明可以设置多个检查点,并从不同的检查点文件中进行选择恢复,从而有针对性地对应用程度进行调试,进一步缩短了调试时间;

5、本发明在检查点文件中保存的上下文信息,不仅包括目标应用程序对应的进程的上下文信息,还包括与目标应用程序并发运行的并发应用程序的进程上下文信息,并且在进行检查点的恢复操作时,恢复所有的应用程序,以保持全局一致性状态,从而实现了多进程协同检查点操作。

附图说明

图1为本发明调试装置结构示意图;

图2为本发明实施例1调试方法的流程示意图;

图3为本发明实施例1运行应用程序流程示意图;

图4为本发明实施例1设置检查点流程示意图;

图5为本发明实施例1调试应用程序流程示意图;

图6为本发明实施例1恢复检查点流程示意图。

具体实施方式

为了使本发明的目的、技术方案及优点更加清楚明白,以下结合附图及实施例,对本发明进行进一步详细说明。应当理解,此处所描述的具体实施例仅仅用以解释本发明,并不用于限定本发明。此外,下面所描述的本发明各个实施方式中所涉及到的技术特征只要彼此之间未构成冲突就可以相互组合。

本发明公开了一种基于检查点的调试方法以及调试系统,所述调试系统包括宿主机以及目标机,所述目标机包括解析模块、运行模块、检查点模块以及调试模块;宿主机连接解析模块,解析模块分别与运行模块、检查点模块以及调试模块相连,运行模块与检查点模块以及调试模块相连;

所述调试方法具体包括以下步骤:

(0)远程连接宿主机与目标机,具体包括如下子步骤:

(0.1)宿主机从外部接收远程登陆的命令,并向目标机发出连接指令,所述远程登陆的命令的参数为所述目标机的用户名以及IP地址;

(0.2)宿主机从外部接收解密的命令,并向目标机发出解密指令,与所述目标机建立远程连接;

(1)宿主机向解析模块发出第一指令,解析模块将所述第一指令解析后发送给运行模块,令所述目标机上的应用程序开始运行;所述应用程序包括目标应用程序以及并发应用程序,目标应用程序运行的同时就会将目标应用程序的进程号记录于目标机的进程号文件中,而并发应用程序并非一定和目标应用程序同时运行,但只要开始运行,该并发应用程序就会向目标应用程序发送信号,从而在目标机的进程号文件中留下所述并发应用程序所对应的进程的进程号;

(2)宿主机接收外部的命令,并判断所述命令的类型;如果所述命令为保存命令,则进入步骤(3);如果所述命令为调试命令,则进入步骤(4);如果所述命令为恢复命令,则进入步骤(5);如果所述命令为退出命令,则入步骤(7);否则该命令的类型宿主机无法识别,进入步骤(6);

(3)宿主机向解析模块发出第二指令,解析模块将所述第一指令解析后发送给检查点模块,令检查点模块在应用程序的当前位置创建第i检查点,并根据进程号文件中所记录的进程号,将所述应用程序对应的进程的上下文信息保存于第i检查点文件中;所述进程包括父进程以及所述父进程的子进程;i=i+1,返回步骤(2);所述上下文信息包括进程的状态(如进程头、进程的线程、进程的线程的父子关系、共享数据和私有数据)、进程的用户变量、进程在寄存器中的地址、进程在进程表项的用户栈以及内核栈中的地址;由于在所述步骤(2)

(4)宿主机向目标机发出第三指令,令所述目标机在应用程序的当前位置调试,并向宿主机返回调试结果,宿主机将所述调试结果输出至外部,返回步骤(2);具体包括如下子步骤:

(4.1)根据调试命令的种类,宿主机向解析模块发出第三指令,解析模块将所述第三指令解析后发送给调试模块,令所述调试模块在应用程序运行的当前位置进行相应种类的调试,获得调试结果后输出至解析模块,解析模块将调试结果解析后发送给宿主机;所述调试命令的种类包括条件断点、进入函数、跳出函数、设置观察点、线程核绑定、插入断点、查询断点、单步执行、持续执行、执行至结束、删除断点、查看变量、查看线程运行核、获取核运行线程或统计线程运行时间;

(4.2)在0.3s~1.0s内,宿主机判断是否收到解析模块返回的调试结果,是则进入步骤(4.3),否则返回步骤(4.1);

(4.3)宿主机将所述调试结果反馈给外部,返回步骤(2);

(5)宿主机向解析模块发出第四指令,解析模块将所述第四指令解析后发送给检查点模块,令所述检查点模块从第j检查点文件中恢复应用程序对应的进程的上下文信息,并向运行模块发出恢复指令,运行模块令应用程序运行的当前位置恢复至第j检查点,j为1~i的整数,返回步骤(2);

(6)宿主机向外部发出报错指令,返回步骤(2);

(7)宿主机向解析模块发出第五指令,解析模块将所述第五指令解析后发送给运行模块,运行模块结束应用程序的运行。

在整个调试过程中,除进行调试以及恢复检查点的时刻,其余时刻应用程序持续运行,直至运行结束;在步骤(5)中可根据需要恢复的应用程序的位置选择检查点;如果应用程序已经运行至某个位置之后,但在该位置需要创建检查点而未创建时,可返回步骤(1),将应用程序从头开始运行。实施例1

该实施例的测试环境如下:

宿主机:CPU为Intel i5-4590@3.30GHz,内存8G,操作系统为Ubuntu 14.04;目标机:CPU为龙芯3A,具有多核芯片,内存型号DDR2 800Mhz(1G),操作系统Debian。

Linux下的主流调试器如GDB,只能运行在x86系统中。在本实施例中mips架构的嵌入式系统,采用精简指令集,相比在x86架构的普通系统上实现检查点系统的难点是:1、需要在精简的检查点系统过程的同时,保证检查点的功能都能实现;2、需要更快的运行速度,来满足嵌入式系统对实时性更高的要求。3、mips架构和x86架构的指令集不同,寄存器等地址不同,导致在mips架构上实现检查点功能更加困难。

如图2所示,本实施例为对被调试应用程序test.c的一次调试过程,主要包括建立远程连接、运行应用程序、设置检查点、调试应用程序、恢复检查点等步骤,具体如下:

(1)建立远程连接,包括下述子步骤:

(1.1)通过宿主机命令行输入ssh命令与目标机建立远程连接,命令的参数为目标机的用户名以及IP地址,然后转步骤(1.2);

(1.2)调试人员在宿主机上输入目标机的登录密码,使得宿主机与目标机完成建立远程连接,然后转步骤(2);

(2)运行应用程序,如图3所示,包括下述子步骤:

(2.1)判断目标机上是否已经加载检查点内核模块epcr_imports.ko和epcr.ko,如果已经加载就直接转步骤(2.2),如果没有就利用目标机命令行执行加载检查点内核模块脚本./sh epcr_module.sh,将检查点内核模块加载到内核,然后转步骤(2.2);

(2.2)判断目标机上检查点的辅助服务器server_for_checkpoint是否运行,如果已经运行就直接转步骤(2.3),否则就利用目标机命令行终端执行命令./server_for_checkpoint启动辅助服务器,然后转步骤(2.3);

(2.3)利用目标机命令行执行应用程序可执行文件./test,启动应用程序,然后转步骤(2.4);

(2.4)启动宿主机上的检查点客户端./client_for_checkpoint,连接到目标机上检查点服务器端server_for_checkpoint,发送步骤(2.3)执行的应用程序的文件名test到检查点服务器端,由检查点服务器端查找目标机上对应应用程序的进程号,然后将进程号发送给检查点客户端client_for_checkpoint,然后转步骤(3);

(3)目标机根据调试人员输入的命令判断是否需要设置检查点;当调试人员需要设置检查点时,则进入下一步,否则进入步骤(5);

(4)设置检查点,如图4所示,包括下述子步骤:

(4.1)宿主机向目标机输入检查点命令./checkpoint pid–backup,创建检查点保存进程,所述检查点保存进程的参数为步骤(2.4)获取的进程号pid,该进程号对应的进程为第一目标进程,然后转步骤(4.2);

(4.2)目标机上的检查点保存进程从命令行读入步骤(4.1)传入的参数,将包括第一目标进程的进程号pid、记录检查点范围、检查点文件context.pid描述符等参数进行初始化,并所述参数的值赋给结构体变量cr_args,格式化成检查点动态链接库libcr可识别的参数,然后转步骤(4.3);

(4.3)检查点动态链接库将步骤(4.2)中的参数初始化成内核可识别cri_info_t结构体形式,然后与内核通信;与此同时打开/proc文件系统中的ctrl文件获取对应检查点文件的描述符,并执行ioctl操作将检查点保存进程注册为Phase2进程,然后注册一个基于线程的回调函数Phase1,然后转步骤(4.4);

(4.4)检查点动态链接库向内核发送检查点保存请求,内核根据检查点保存请求中的cr_scope,构造进程关系树结构,获取需要保存检查点的应用程序对应的第一目标进程,然后唤醒Phase1回调函数,该回调函数发送参数CR_OP_HAND_CHKPT到内核,开始对第一目标进程进行检查点保存,然后转步骤(4.5);

(4.5)内核开始将第一目标进程的上下文信息写入检查点文件context.pid中;首先,内核保存检查点文件的文件头,然后将第一目标进程记录检查点的范围中所有进程的上下文信息保存入检查点文件,包括进程当前的状态、进程的全部用户变量和数据结构的值、当前寄存器的值、保存在进程表项中的值以及它的用户栈和内核栈中的内容;,然后转步骤(4.6);

(4.6)检查点保存进程通过事件循环机制轮询查看步骤(4.5)中检查点保存工作是否完成,如果完成则关闭/proc节点,让应用程序继续运行,然后转步骤(5),否则阻塞直至检查点保存工作完成;

(5)调试应用程序步骤,如图5所示,包括下述子步骤:

(5.1)启动目标机上的调试服务器端,参数为步骤(2.4)中应用程序的文件名;运行宿主机上的调试客户端,参数为目标机的IP地址和步骤(2.4)中获取的被调试应用程序的进程号pid,然后转步骤(5.2);

(5.2)调试服务器端首先创建一个线程,在线程中调用ptrace函数,调试服务器端对pid所对应的子进程进行跟踪:调用ptrace函数,其功能参数为PTRACE_ATTACH,线程号为pid,地址参数和数据参数均为0,然后进行子步骤(5.3);

(5.3)调试服务器端在步骤(5.2)中创建的线程内部加载应用程序,并另外为应用程序建立符号表,加载应用程序的线程处于暂停状态,停在代码当前位置,进行子步骤(5.4);

(5.4)调试客户端向调试服务器端发起远程连接请求,经调试服务器端确认后,接管被调试的进程,建立远程连接;在建立远程连接之后的整个调试过程中,调试服务器端一直处于监听状态,时刻准备接受调试客户端发送的RSP数据包。然后转步骤(5.5);

(5.5)调试客户端即可发送各种RSP数据包对应用程序进行调试,当接收到调试人员输入的调试命令后,判断所述调试命令的命令类型是否为退出命令(quit),是则结束调试,否则进行子步骤(5.6);

(5.6)遍历调试器定义的调试命令集,查找所述调试命令的命令类型在调试命令集中是否存在,是则进行子步骤(5.7),否则向外部输出提示信息,提示调试命令输入错误,转子步骤(5.5);调试命令集除包括主流调试器拥有的调试操作外,还包括调试命令的下述命令类型:线程核绑定、插入断点、查询断点、单步执行、持续执行、执行至结束、删除断点、查看变量、查看线程运行核、获取核运行线程、统计线程运行时间;

(5.7)将所述调试命令作为数据,封装成RSP数据包,发送给目标机调试服务器端,如果在0.5秒内收到目标机调试服务器端的执行结果,则进行子步骤(5.9),否则转子步骤(5.5);

(5.9)调试客户端解析执行结果,获取调试结果,并该调试结果反馈给调试人员;调试人员根据反馈的调试结果判断是否已经定位应用程序中错误,是则向宿主机发出终止调试的指令,返回步骤(5.5),否则转步骤(6);

(6)恢复检查点步骤,如图6所示,包括下述子步骤:

(6.1)根据步骤(2.4)获取的被调试应用程序的进程号pid或者用户指定的检查点文件context.pid,利用目标机执行检查点恢复进程./cr_restart context.pid,参数为要恢复的检查点文件context.pid,然后转步骤(6.2);

(6.2)目标机上的检查点恢复进程从命令行读取步骤(6.1)中传入的检查点文件的参数;该参数包括检查点文件的路径和恢复进程运行后要向检查点恢复进程发送的信号等,然后转步骤(6.3);

(6.3)检查点动态链接库将步骤(6.2)中检查点文件的参数初始化成内核可识别cri_info_t结构体形式,然后与内核取得通信;与此同时,打开/proc文件系统中的ctrl文件,获取对应文件描述符,对其执行ioctl操作将检查点恢复进程注册为Phase2进程,然后为第一目标进程的检查点恢复进程注册一个基于线程的回调函数Phase1,然后转步骤(6.4);

(6.4)检查点动态链接库向内核发送检查点恢复请求,内核读取检查点恢复请求中的结构体cr_rstrt_args数据,并调用函数分配并初始化检查点恢复请求的变量req,然后获取检查点文件的路径,并从检查点文件中读取上下文信息,并判断检查点服务器端的版本,第一目标进程所处的体系结构和内核版本是否和该检查点系统中对应的上下文信息保持一致,如果不一致就直接结束,否则转步骤(6.5);

(6.5)内核从检查点文件context.pid中读取上下文信息,然后将进程头从内核写入用户层,然后对于确定存在于检查点文件中等待恢复的进程,检查点恢复进程作为父进程调用fork()创建子进程,子进程开始检查点恢复操作,调用clone()系统调用,创建第二目标进程,子进程调用ioctl()函数与内核取得通信,发送参数CR_OP_RSTRT_CHILD到内核层,内核层在第二目标进程内恢复第一目标进程对应的检查点文件中所有进程信息的内容,然后转步骤(5.6);

(6.6)检查点恢复进程通过事件循环机制,等待执行检查点恢复操作的检查点恢复进程的子进程完成检查点恢复操作,当第二目标进程完成检查点恢复工作后,检查点恢复进程进行相关的清理工作,释放检查点恢复进程过程中的一些相关数据结构,然后令第一目标进程为第二目标进程,转步骤(5.1),而不必从头执行应用程序,从而缩短了调试时的等待时间。

实施例2

实施例2的测试环境同实施例1

如图2所示,本实施例为对被调试应用程序sigtest1.c的一次调试过程,主要包括建立远程连接、运行应用程序、设置检查点、调试应用程序、恢复检查点等步骤,具体如下:

(1)建立远程连接,包括下述子步骤:

(1.1)通过宿主机命令行输入ssh命令与目标机建立远程连接,命令的参数为目标机的用户名以及IP地址,然后转步骤(1.2);

(1.2)调试人员在宿主机上输入目标机的登录密码,使得宿主机与目标机完成建立远程连接,然后转步骤(2);

(2)运行目标应用程序以及并发应用程序,包括下述子步骤:

(2.1)判断目标机上是否已经加载检查点内核模块epcr_imports.ko和epcr.ko,如果已经加载就直接转步骤(2.2),如果没有就利用目标机命令行执行加载检查点内核模块脚本./sh epcr_module.sh,将检查点内核模块加载到内核,然后转步骤(2.2);

(2.2)判断目标机上检查点的辅助服务器server_for_checkpoint是否运行,如果已经运行就直接转步骤(2.3),否则就利用目标机命令行终端执行命令./server_for_checkpoint启动辅助服务器,然后转步骤(2.3);

(2.3)利用目标机命令行运行mapcreate程序,创建一个文件,用来保存需要进行检查点操作的进程号;

(2.4)利用目标机命令行执行目标应用程序可执行文件./sigtest1,启动目标应用程序,获得目标应用程序对应的第一目标进程,随后同样利用目标机命令执行并发应用程序可执行文件./sigtest2 80,启动并发应用程序,并获得并发应用程序对应的并发进程,此时第一目标进程和并发进程之间并发运行;并发应用程序可执行文件中的80为并发进程向第一目标进程发送的信号,此时运行中的第一目标进程接收此信号;由于目标应用程序和并发应用程序皆与libsigqueue.so动态链接库相链接;此时,该动态链接库重写了sigqueue函数,并发进程调用sigqueue函数发送信号,在运行并发应用程序时,该函数将并发进程以及第一目标进程对应的进程号,以结构体的形式保存到步骤(2.3)中创建的文件中,然后转步骤(2.5);

(2.5)启动宿主机上的检查点客户端./client_for_checkpoint,连接到目标机上检查点服务器端server_for_checkpoint,发送步骤(2.4)执行的目标应用程序的文件名sigtest1到检查点服务器端,由检查点服务器端查找目标机上第一目标进程的对应的第一进程号,然后将该进程号发送给检查点客户端client_for_checkpoint,然后转步骤(3);

(3)目标机根据调试人员输入的命令判断是否需要设置检查点;当调试人员需要设置检查点时,则进入下一步,否则进入步骤(5);

(4)设置检查点,包括下述子步骤:

(4.1)宿主机向目标机输入检查点命令./checkpoint pid–backup,创建检查点保存进程,所述检查点保存进程的参数为步骤(2.5)获取的第一进程号;同时,通过遍历步骤(2.3)创建的文件中在步骤(2.4)保存的结构体得到并发进程对应的第二进程号,然后转步骤(4.2);

(4.2)目标机上的检查点保存进程从命令行读入步骤(4.1)传入的参数,将包括第一目标进程以及并发进程的参数进行初始化,并所述参数的值赋给结构体变,格式化成检查点动态链接库libcr可识别的参数,然后转步骤(4.3);

(4.3)检查点动态链接库将步骤(4.2)中的参数分别初始化成内核可识别cri_info_t结构体形式,然后与内核通信;与此同时打开/proc文件系统中的ctrl文件获取对应检查点文件的描述符,并执行ioctl操作将检查点保存进程注册为Phase2进程,然后分别注册两个基于线程的回调函数Phase1,然后转步骤(4.4);

(4.4)检查点动态链接库向内核发送检查点保存请求,内核根据检查点保存请求中的cr_scope,构造进程关系树结构,获取需要保存检查点的应用程序对应的第一目标进程和并发进程,然后唤醒Phase1回调函数,该回调函数发送参数CR_OP_HAND_CHKPT到内核,开始对第一目标进程以及并发进程进行检查点保存,然后转步骤(4.5);

(4.5)内核开始将第一目标进程以及并发进程的上下文信息分别写入检查点文件context.pid中;首先,内核保存检查点文件的文件头,然后将第一目标进程以及并发进程的上下文信息保存入检查点文件,包括进程当前的状态、进程的全部用户变量和数据结构的值、当前寄存器的值、保存在进程表项中的值以及它的用户栈和内核栈中的内容;,然后转步骤(4.6);

(4.6)检查点保存进程通过事件循环机制轮询查看步骤(4.5)中检查点保存工作是否完成,如果完成则关闭/proc节点,让目标应用程序以及并发程序继续运行,然后转步骤(5),否则阻塞直至检查点保存工作完成;

(5)调试应用程序步骤,如图5所示,包括下述子步骤:

(5.1)启动目标机上的调试服务器端,参数为步骤(2.5)中目标应用程序的文件名;运行宿主机上的调试客户端,参数为目标机的IP地址和步骤(2.5)中获取的目标应用程序的进程号pid,然后转步骤(5.2);

(5.2)调试服务器端首先创建一个线程,在线程中调用ptrace函数,调试服务器端对pid所对应的子进程进行跟踪:调用ptrace函数,其功能参数为PTRACE_ATTACH,线程号为pid,地址参数和数据参数均为0,然后进行子步骤(5.3);

(5.3)调试服务器端在步骤(5.2)中创建的线程内部加载目标应用程序,并另外为目标应用程序建立符号表,加载目标应用程序的线程处于暂停状态,停在代码当前位置,进行子步骤(5.4);

(5.4)调试客户端向调试服务器端发起远程连接请求,经调试服务器端确认后,接管被调试的进程,建立远程连接;在建立远程连接之后的整个调试过程中,调试服务器端一直处于监听状态,时刻准备接受调试客户端发送的RSP数据包。然后转步骤(5.5);

(5.5)调试客户端即可发送各种RSP数据包对目标应用程序进行调试,当接收到调试人员输入的调试命令后,判断所述调试命令的命令类型是否为退出命令(quit),是则结束调试,否则进行子步骤(5.6);

(5.6)遍历调试器定义的调试命令集,查找所述调试命令的命令类型在调试命令集中是否存在,是则进行子步骤(5.7),否则向外部输出提示信息,提示调试命令输入错误,转子步骤(5.5);调试命令集除包括主流调试器拥有的调试操作外,还包括调试命令的下述命令类型:线程核绑定、插入断点、查询断点、单步执行、持续执行、执行至结束、删除断点、查看变量、查看线程运行核、获取核运行线程、统计线程运行时间;

(5.7)将所述调试命令作为数据,封装成RSP数据包,发送给目标机调试服务器端,如果在0.5秒内收到目标机调试服务器端的执行结果,则进行子步骤(5.9),否则转子步骤(5.5);

(5.9)调试客户端解析执行结果,获取调试结果,并该调试结果反馈给调试人员;调试人员根据反馈的调试结果判断是否已经定位应用程序中错误,是则向宿主机发出终止调试的指令,返回步骤(5.5),否则转步骤(6);

(6)恢复检查点步骤,如图6所示,包括下述子步骤:

(6.1)根据步骤(2.4)获取的第一进程号或者步骤(4.3)中的检查点文件context.pid,利用目标机执行检查点恢复进程./restart context.pid,参数为要恢复的检查点文件context.pid,然后转步骤(6.2);

(6.2)目标机上的检查点恢复进程从命令行读取步骤(6.1)中传入的检查点文件的参数;该参数包括检查点文件的路径和恢复进程运行后要向检查点恢复进程发送的信号等,然后转步骤(6.3);

(6.3)检查点动态链接库将步骤(6.2)中检查点文件的参数初始化成内核可识别cri_info_t结构体形式,然后与内核取得通信;与此同时,打开/proc文件系统中的ctrl文件,获取对应文件描述符,对其执行ioctl操作将检查点恢复进程注册为Phase2进程,然后为第一目标进程以及并发进程的检查点恢复进程分别注册基于线程的回调函数,然后转步骤(6.4);

(6.4)检查点动态链接库向内核发送检查点恢复请求,内核读取检查点恢复请求中的结构体cr_rstrt_args数据,并调用函数分配并初始化检查点恢复请求的变量req,然后获取检查点文件的路径,并从检查点文件中读取上下文信息,并判断检查点服务器端的版本,第一目标进程以及并发进程所处的体系结构和内核版本是否和该检查点系统中对应的上下文信息保持一致,如果不一致就直接结束,否则转步骤(6.5);

(6.5)内核从检查点文件context.pid中读取上下文信息,然后将第一目标进程以及并发进程进程头从内核写入用户层,然后对于确定存在于检查点文件中等待恢复的进程,检查点恢复进程作为父进程调用fork()创建子进程,子进程开始检查点恢复操作,调用clone()系统调用,创建第二目标进程以及第三目标进程,子进程调用ioctl()函数与内核取得通信,发送参数CR_OP_RSTRT_CHILD到内核层,内核层分别在第二目标进程以及第三目标进程内恢复第一目标进程以及并发进程对应的检查点文件中所有进程信息的内容,然后转步骤(5.6);

(6.6)检查点恢复进程通过事件循环机制,等待执行检查点恢复操作的检查点恢复进程的子进程完成检查点恢复操作,当第二目标进程完成检查点恢复工作后,检查点恢复进程进行相关的清理工作,释放检查点恢复进程过程中的一些相关数据结构,然后令第一目标进程为第二目标进程,并发进程为第三目标进程,转步骤(5.1),而不必从头执行应用程序,从而缩短了调试时的等待时间。

当并发进程启动,并给第一目标进程发送信号时,检查点文件会记录并发进程发送信号的状态;使得本实施例对进程进行检查点保存操作时,第一目标进程以及所有参与并发运行的并发进程都保持了全局一致性状态,使得检查点文件记录的与并发相关的状态是同步的;并且在进行检查点的恢复操作时,恢复所有并发进程,以保持全局一致性状态,从而实现了多进程协同检查点操作。

本领域的技术人员容易理解,以上所述仅为本发明的较佳实施例而已,并不用以限制本发明,凡在本发明的精神和原则之内所作的任何修改、等同替换和改进等,均应包含在本发明的保护范围之内。

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