调试进程的方法和系统的制作方法

文档序号:6583985阅读:166来源:国知局
专利名称:调试进程的方法和系统的制作方法
技术领域
本发明涉及计算机软件领域,特别涉及一种调试进程的方法和系统。
背景技术
计算机软件开发过程中,调试器是不可或缺的工具。在嵌入式软件开发领域,目标 机或单板(后面统称“目标机”)的硬件资源通常比较有限,例如存储空间不大、中央处理单 元(Central Processing Unit, CPU)性能也不及PC机和服务器,因此常常使用交叉调试模 式,即在目标机上运行一个尺寸较小、功能相对简单的代理程序(本文后面统称为“调试代 理模块”),而尺寸较大,功能完整的调试主控模块运行在资源相对丰富的主机端。现有的交叉调试器存在一个缺陷,不方便跟踪被调试程序在调试过程中创建 的子进程。被调试程序通常是采用fork、vfork等事件创建子进程,然后,再通过调用 execv系列函数来运行新的程序。开源GDB在本地调试时,可以用set follow-fork-mode parent | child命令预先设置当有子进程生成时,调试器是继续调试被调试程序还是调试子 进程。如果设置的是调试被调试程序,那么用户可以继续在被调试程序中进行调试,而子进 程在创建以后将不受约束地正常运行;如果设置的是调试子进程,那么调试流程进入调试 子进程的状态,而被调试程序脱离调试器的控制,恢复正常运行。开源⑶B进行本地调试的 缺陷在于,如果设置的是调试子进程,子进程调用execv系列函数来运行新的程序时,调试 器将不能跟踪进入新启动的程序,更不能在新启动的程序的入口代码处停住,等待用户进 行调试控制。开源GDB/GDBSERVER交叉调试器则完全不支持从被调试程序调试跟踪子进程 的功能。现有的其它一些交叉调试器,有些提供了调试子进程的功能,例如在调试器感知 到被调试程序创建了子进程时,自动把新创建的子进程置于调试器的控制之下。但是,从其 实际效果来说,与用户知道有子进程创建时,手工把子进程置于调试器控制中没有本质差 别,它们的共同缺点是不方便调试子进程的入口代码,特别是当子进程会很快运行结束并 退出的时候,很难对子进程进行调试。为了解决上述不方便调试子进程入口代码的难题,通常推荐调试器使用者在子进 程的入口代码开始处插入一段条件循环的代码,并将循环条件设置为‘真’,这样,在子进程 启动后,将停在新加的循环代码中;待调试器跟踪到子进程以后,再修改循环条件为‘假’, 终止循环,流程继续往下执行。这样就可以调试子进程的入口代码了。此方法有一个很明显 的缺点,就是要修改被调试程序,并且修改后要重新编译,这给调试器的使用带来了不便。另一种方法是编写脚本文件,例如,子进程要运行的可执行文件是fil印athname, 首先修改该文件的名字,例如,修改为f ilepathname 1 ;然后,写一个shel 1脚本文件命名为 fil印athname,在该脚本文件中,首先启动一个新的shell,然后在新启动的shell中,使用 ⑶B调试fil印athnamel文件。这样,当子进程调用execv函数执行fil印athname文件时, 实际上会在一个新的shell中启动一个⑶B,然后在这个⑶B中对新运行的程序进行调试。 但这种方法不仅使用麻烦,而且只适用于本地调试,不适用于嵌入式交叉调试环境。
综上所述,现有的交叉调试器在调试子进程时,特别是在跟踪子进程入口代码时, 要么是需要修改被调试程序,要么是编写脚本文件,调试过程复杂,工作量大,工作效率低。

发明内容
本发明实施例要解决的问题是提供一种调试进程的方法和系统,以解决现有技术 中无法在嵌入式交叉调试器中,跟踪子进程入口代码的问题。为了解决上述问题,本发明实施例提供了一种调试进程的方法和系统,具体技术 方案如下一种调试进程的方法,包括根据创建子进程事件的信号,使被调试程序和子进程处于停止状态;判断要调试子进程时,切换调试对象为所述子进程;控制所述子进程运行新程序,使新程序的相关调试信息替换原有程序的相关调试 信息,并在所述新程序的入口代码处插入临时断点。一种调试进程的方法,包括在被调试程序调用执行新程序系列函数运行新程序后,获取到执行新程序事件的 信号;根据所述信号,使新程序的相关调试信息替换原有程序的相关调试信息,并在所 述新程序的入口代码处插入临时断点。一种调试进程的系统,包括所述调试代理模块,用于在获取到创建子进程事件的信号时,使被调试程序和所 述子进程处于停止状态;所述调试主控模块,用于在判断要调试所述子进程时,切换调试对象为所述子进 程;使新程序的相关调试信息替换原有程序的相关调试信息,并在所述新程序的入口代码 处插入临时断点。一种调试进程的系统,包括调试代理模块,用于在被调试程序调用执行新程序系列函数运行新程序后,获取 到执行新程序事件的信号;调试主控模块,用于根据所述信号,使新程序的相关调试信息替换原有程序的相 关调试信息,并在所述新程序的入口代码处插入临时断点。在本发明实施例中,根据创建子进程事件的信号,使被调试程序和子进程处于停 止状态;判断要调试子进程时,切换调试对象为所述子进程;控制所述子进程运行新程序, 使新程序的相关调试信息替换原有程序的相关调试信息,并在所述新程序的入口代码处插 入临时断点,解决了现有交叉调试器不便跟踪子进程、特别是很难跟踪子进程入口代码的 问题,使用户可以不修改被调试程序的代码,也不需要任何额外的脚本,即可方便地跟踪子 进程的入口代码,从而简化了调试过程,降低了软件开发人员调试程序的工作量,提高了工 作效率。


图1、7是本发明实施例提供的一种调试进程的方法的流程图2是本发明实施例提供的一种调试进程的系统的结构图;图3是本发明实施例提供的调试代理模块和调试主控模块的结构图;图4是本发明实施例提供的调试代理模块对创建子进程事件的处理流程图;图5是本发明实施例提供的调试主控模块对创建子进程事件的处理流程图。图6是本发明实施例提供的调试主控模块调对execv事件的处理流程图。
具体实施例方式本发明的核心思想在于根据创建子进程事件的信号,使被调试程序和子进程处 于停止状态;判断要调试子进程时,切换调试对象为所述子进程;控制所述子进程运行新 程序,使新程序的相关调试信息替换原有程序的相关调试信息,并在所述新程序的入口代 码处插入临时断点,解决了现有交叉调试器不便跟踪子进程、特别是很难跟踪子进程入口 代码的问题,使用户可以不修改被调试程序的代码,也不需要任何额外的脚本,即可方便地 跟踪子进程的入口代码,从而简化了调试过程,降低了软件开发人员调试程序的工作量,提 高了工作效率。下面结合附图及优选实施方式对本发明技术方案进行详细说明。本发明实施例提供了一种调试进程的方法,如图1所示,包括10,根据创建子进程事件的信号,使被调试程序和子进程处于停止状态;20,判断要调试子进程时,切换调试对象为子进程;30,控制子进程运行新程序,使新程序的相关调试信息替换原有程序的相关调试 信息,并在新程序的入口代码处插入临时断点。进一步地,切换调试对象为所述子进程,包括初始化内部管理数据结构及变量,重新初始化缓存帧内容。进一步地使新程序的相关调试信息替换原有程序的相关调试信息,包括清空当前的符号表,重新加载新程序的符号表,重新加载新程序的共享库符号。进一步地,该方法还包括在判断不调试子进程时,继续调试被调试程序,使子进程脱离跟踪调试状态,并结
束ο下面结合附图,对本发明所述调试进程的系统以及在类UNIX目标机上的具体实 施做进一步说明如图2所示为调试进程的系统结构图,图2所示的系统只是为了描述的需要,本发 明的保护范围并不限于此。图2所示的系统包括调试代理模块100和调试主控模块106。其中,如图3所示,调试代理模块100,运行在目标机端,运行的操作系统环境101 是类UNIX操作系统。调试代理模块100包括连接管理单元102、硬件抽象单元103、任务 管理单元104和命令处理单元105。连接管理单元102负责维护调试代理模块100与调试 主控模块106的网络连接,为上层处理单元提供数据通信通道。硬件抽象单元103负责屏蔽 各种CPU的硬件(例如寄存器)差异,抽象出统一的接口,方便上层处理单元的流程实现; 任务管理单元104负责控制被调试的各个程序的状态,感知并处理被调试对象的各种调试 事件,并把被调试对象的事件及状态变迁通知调试主控模块106,其中,被调试对象可以是子进程,也可以是被调试程序,具体根据实际情况而定;命令处理单元105负责接收来自调 试主控模块106的各种调试命令,执行相应的调试操作,并把操作结果反馈给调试主控模 块 106 ;如图3所示,调试主控模块106运行在调试主机上,其中,调试主机与目标机可以 是不同的计算机,也可以是同一台计算机,它运行的操作系统环境107既可以是Windows, 也可以是类UNIX操作系统。调试主控模块106包括命令处理单元112、目标管理单元111、 符号处理单元110、断点管理单元109和连接管理单元108。其中,连接管理单元108负责 维护调试主控模块106和调试代理模块100的网络连接,为上层处理单元提供数据通信通 道;断点管理单元109负责各种类型断点的插入、删除、属性修改和断点表维护等工作;符 号处理单元110负责分析被调试对象的符号信息和调试信息,它是调试主控模块106的核 心组成部分之一,是实现源代码级调试、断点管理、变量查看、表达式求值和堆栈回溯等诸 多功能的必要基础;目标管理单元111 一方面负责向被调试对象发送指令,另一方面负责 处理来自调试代理模块100的被调试对象的调试事件;命令处理单元112的任务是接收、处 理用户命令,并把命令处理结果反馈给用户,如果是需要调试代理模块100处理的命令,命 令处理单元112会通过目标管理单元111向调试代理模块100发送数据报文,控制调试代 理模块100执行特定的操作,然后接收调试代理模块100返回的处理结果,再把处理结果反 馈给用户。下面结合图3对本发明实施例的方法进行详细的描述,具体如下产生子进程的操作包括以下几种fork事件、vfork事件、clone事件,其中,clone 事件可以属于fork事件,也可以属于vfork事件。在实际应用中,用得最多的是fork事件 和execv事件,或是vfork事件加execv事件创建子进程,但实际应用中,用户也可以只使 用fork事件或vfork事件创建子进程,此时,子进程和被调试程序拥有相同的地址空间,在 本实施例中,在感知到有子进程创建时,可以提示用户来选择是继续调试被调试程序、还是 调试子进程;而对于execv事件,被调试程序调用execv系列函数时,发生该事件,此时,进 程地址空间已经更新为新运行的程序的地址空间。在本实施例中,vfork事件、fork事件为 创建子进程事件,execv事件是执行新程序事件。图4所示为调试代理模块100对创建子进程事件的处理流程,调试代理模块100 的任务管理单元104通过类UNIX操作系统定义的PTRACE_EVENT_F0RK、PTRACE_EVENT_ VFORK或者PTRACE_EVENT_CL0NE等信号感知子进程创建事件(步骤201)。任务管理单元 104感知到创建子进程事件时,使父子进程都处于停止运行状态(步骤20 ;任务管理单元 104判断用户是否设置了调试子进程(步骤20 ,如果用户事先设置了不调试子进程,那么 任务管理单元104删除子进程空间中的断点(步骤213),并使子进程脱离调试跟踪状态, 恢复正常运行(步骤214);如果用户设置了调试子进程,则首先通过连接管理单元102向 调试主控模块106发送携带子进程标识和事件类型的数据报文,报告子进程创建事件(步 骤204),再由任务管理单元104判断是通过fork事件还是vfork事件创建的子进程(步骤 205),如果感知到的是PTRACE_EVENT_VF0RK信号,则是通过vfork事件创建的子进程,那么 任务管理单元104切换当前调试对象为子进程(步骤211),并初始化内部管理数据结构和 变量(步骤212);如果感知到的是PTRACE_EVENT_F0RK信号,则是通过fork事件创建的子 进程,那么任务管理单元104首先删除被调试程序空间中的内存断点(步骤206),使被调试程序脱离调试跟踪状态(步骤207),再切换当前调试对象为子进程(步骤208)、初始化 相关的内部管理数据结构和变量(步骤209),并根据调试主控模块106的指令回插子进程 空间中的断点到内存中(步骤210);如果感知到的是PTRACE_EVENT_CLONE事件,则是通过 clone事件创建的子进程,处理流程与PTRACE_EVENT_FORK事件的处理流程相同,在此不再 赘述。需要说明的是,任务管理单元104切换当前调试对象为子进程也可以是根据调试主 控模块106的指令进行,即调试主控模块106在将当前调试对象切换为子进程后,会通知调 试代理模块100,调试代理模块100中的任务管理单元104根据该指令切换当前的调试对象 为子进程。图5是调试主控模块106对创建子进程事件的处理流程图。调试主控模块106通 过连接管理单元108收到调试代理模块100上报的数据报文后(步骤216),目标管理单元 111配合命令处理单元112首先根据用户的配置或者用户的选择,判断是否要调试子进程 (步骤217),如果不调试子进程,那么当前调试对象不变,继续为被调试程序(步骤221),目 标管理单元111使子进程脱离跟踪状态,恢复正常运行(步骤222);如果要调试子进程,则 连接管理单元108从上报报文中解析出子进程的ID(步骤218),由目标管理单元111切换 当前调试对象为子进程(步骤219),并初始化内部管理数据结构及变量(步骤220),此时, 调试主控模块106处理子进程创建事件的过程结束(步骤223)。然后,调试主控模块106通知调试代理模块100,使调试代理模块100控制其让子 进程继续运行。调试代理模块100控制子进程调用execv系列函数执行新的程序,类UNIX 操作系统感知到该execv事件,生成相应的信号传送给调试代理模块106。调试代理模块 106中的任务管理单元104通过类UNIX操作系统定义的PTRACE_EVENT_EXEC信号感知到 execv事件后,处理流程比较简单如果命令处理单元105设置了调试子进程,则向调试主 控模块106发送数据报文,通知调试主控模块106发生了 execv事件,加载符号表等流程由 调试主控模块106的符号处理单元110完成;如果命令处理单元105没有设置调试子进程 功能,则任务管理单元104直接让子进程继续运行,不做其它处理。如图6所示,调试主控模块106中的连接管理单元108收到调试代理模块105上 报的数据报文时(步骤224),通知符号处理单元110清空当前的符号表,重新加载新程序的 符号表(步骤22 ,重新加载新程序的共享库符号(步骤226),由断点管理单元109在新 程序的入口代码处插入临时断点(步骤227),目标管理单元111重新初始化帧缓冲区的内 容以后(步骤228),让子进程继续运行(步骤229),并结束(步骤230)。在子进程运行到 入口代码的时候,会命中临时断点而停住,这样就可以调试子进程中新程序的代码。本发明实施例还提供了一种调试进程的方法,如图7所示,包括40,在被调试程序调用执行新程序系列函数运行新程序后,获取到执行新程序事 件的信号;50,根据该信号,使新程序的相关调试信息替换原有程序的相关调试信息,并在该 新程序的入口代码处插入临时断点。进一步地,使新程序的相关调试信息替换原有程序的相关调试信息,包括清空当前的符号表,重新加载新程序的符号表,重新加载新程序的共享库符号。下面结合具体的示例对本发明的保护范围进行具体的描述,具体地,被调试程序直接调用execv系列函数执行新程序。这种情况下,没有子进程产生,调试代理模块100通过操作系统的信号感知到execv事件后,向调试主控模块106发送数 据报文,通知调试主控模块106发生了该execv事件。调试主控模块106收到调试代理模 块100上报的数据报文后,清空当前的符号表,重新加载新程序的符号表,重新加载新程序 的共享库符号,在新程序的入口代码处插入临时断点,重新初始化帧缓冲区的内容以后,让 子进程继续运行。通过以上流程,可以在类UNIX目标机上,实现了调试子进程入口代码的方法。基于与方法相同的发明构思,本发明实施例提供了一种调试进程的系统,如图1 所示,包括调试代理模块,用于在获取到创建子进程事件的信号时,使被调试程序和所述子 进程处于停止状态;调试主控模块,用于在判断要调试所述子进程时,切换调试对象为子进程;使新 程序的相关调试信息替换原有程序的相关调试信息,并在新程序的入口代码处插入临时断
点ο进一步地,调试主控模块切换调试对象为子进程,包括调试主控模块根据调试代理模块上报的数据报文中的子进程标识和创建子进程 事件的类型切换调试对象。进一步地,调试代理模块,还用于判断所述创建子进程事件的类型,如果是vfork 事件,则切换调试对象为所述子进程;如果创建子进程事件的类型是fork事件,则删除被 调试程序空间中的内存断点,切换当前调试对象为所述子进程。进一步地,调试主控模块,还用于在判断不调试所述子进程时,继续调试所述被调 试程序,使所述子进程脱离跟踪调试状态,并结束。进一步地,调试代理模块和调试主控模块集成在同一设备上或分布在不同的设备 上。基于与方法相同的发明构思,本发明实施还提供了一种调试进程的系统,如图1 所示,包括调试代理模块,用于在被调试程序调用执行新程序系列函数运行新程序后,获取 到执行新程序事件的信号;调试主控模块,用于根据所述信号,使新程序的相关调试信息替换原有程序的相 关调试信息,并在所述新程序的入口代码处插入临时断点。其中,使新程序的相关调试信息替换原有程序的相关调试信息,包括根据该通知清空当前的符号表,重新加载该新程序的符号表,重新加载该新程序 的共享库符号。本发明实施例可以解决了现有交叉调试器不便跟踪子进程、特别是很难跟踪子进 程入口代码的问题,使用户可以不修改被调试程序的代码,也不需要任何额外的脚本,即可 方便地跟踪子进程的入口代码,从而简化了调试过程,降低了软件开发人员调试程序的工 作量,提高了工作效率。上述说明示出并描述了本发明的一个优选实施例,但如前所述,应当理解本发明 并非局限于本文所披露的形式,不应看作是对其他实施例的排除,而可用于各种其他组合、 修改和环境,并能够在本文所述发明构想范围内,通过上述教导或相关领域的技术或知识进行改动。而本领域人员所进行的改动和变化不脱离本发明的精神和范围,则都应在本发 明所附权利要求的保护范围内。
权利要求
1.一种调试进程的方法,其特征在于,包括根据创建子进程事件的信号,使被调试程序和子进程处于停止状态;判断要调试子进程时,切换调试对象为所述子进程;控制所述子进程运行新程序,使新程序的相关调试信息替换原有程序的相关调试信 息,并在所述新程序的入口代码处插入临时断点。
2.如权利要求1所述的方法,其特征在于,所述切换调试对象为所述子进程,包括初始化内部管理数据结构及变量,重新初始化缓存帧内容。
3.如权利要求1所述的方法,其特征在于,所述使新程序的相关调试信息替换原有程 序的相关调试信息,包括清空当前的符号表,重新加载新程序的符号表,重新加载新程序的共享库符号。
4.如权利要求1所述的方法,其特征在于,还包括在判断不调试所述子进程时,继续调试所述被调试程序,使所述子进程脱离跟踪调试 状态,并结束。
5.一种调试进程的方法,其特征在于,包括在被调试程序调用执行新程序系列函数运行新程序后,获取到执行新程序事件的信号;根据所述信号,使新程序的相关调试信息替换原有程序的相关调试信息,并在所述新 程序的入口代码处插入临时断点。
6.如权利要求5所述的方法,其特征在于,包括使新程序的相关调试信息替换原有程 序的相关调试信息,包括清空当前的符号表,重新加载新程序的符号表,重新加载新程序的共享库符号。
7.—种调试进程的系统,其特征在于,包括所述调试代理模块,用于在获取到创建子进程事件的信号时,使被调试程序和所述子 进程处于停止状态;所述调试主控模块,用于在判断要调试所述子进程时,切换调试对象为所述子进程;使 新程序的相关调试信息替换原有程序的相关调试信息,并在所述新程序的入口代码处插入 临时断点。
8.如权利要求7所述的系统,其特征在于,所述调试主控模块切换调试对象为所述子 进程,包括所述调试主控模块根据所述调试代理模块上报的数据报文中的子进程标识和创建子 进程事件的类型切换调试对象。
9.如权利要求7所述的系统,其特征在于,所述调试代理模块,还用于判断所述创建子 进程事件的类型,如果是vfork事件,则切换调试对象为所述子进程;如果创建子进程事件 的类型是fork事件,则删除被调试程序空间中的内存断点,切换当前调试对象为所述子进 程。
10.如权利要求7至9任意一项权利要求所述的系统,其特征在于,所述调试主控模块, 还用于在判断不调试所述子进程时,继续调试所述被调试程序,使所述子进程脱离跟踪调 试状态,并结束。
11.如权利要求7至9任意一项权利要求所述的系统,其特征在于,所述调试代理模块和所述调试主控模块集成在同一设备上或分布在不同的设备上。
12. —种调试进程的系统,其特征在于,包括调试代理模块,用于在被调试程序调用执行新程序系列函数运行新程序后,获取到执 行新程序事件的信号;调试主控模块,用于根据所述信号,使新程序的相关调试信息替换原有程序的相关调 试信息,并在所述新程序的入口代码处插入临时断点。
全文摘要
本发明公开了一种调试进程的方法和系统,属于计算机软件领域。该方法包括根据创建子进程事件的信号,使被调试程序和子进程处于停止状态;判断要调试子进程时,切换调试对象为所述子进程;控制所述子进程运行新程序,使新程序的相关调试信息替换原有程序的相关调试信息,并在所述新程序的入口代码处插入临时断点。该系统包括调试代理模块和调试主控模块。本发明的技术方案可方便地跟踪子进程的入口代码,从而简化了调试过程,降低了软件开发人员调试程序的工作量,提高了工作效率。
文档编号G06F11/36GK102063366SQ20091022480
公开日2011年5月18日 申请日期2009年11月18日 优先权日2009年11月18日
发明者张华强, 曾义, 汤孝林, 程圣宇, 钟卫东 申请人:中兴通讯股份有限公司
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1