CN102346708B - 一种调试器及其调试方法 - Google Patents

一种调试器及其调试方法 Download PDF

Info

Publication number
CN102346708B
CN102346708B CN201010243471.7A CN201010243471A CN102346708B CN 102346708 B CN102346708 B CN 102346708B CN 201010243471 A CN201010243471 A CN 201010243471A CN 102346708 B CN102346708 B CN 102346708B
Authority
CN
China
Prior art keywords
task
debugged
debugger
kernel
address space
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.)
Active
Application number
CN201010243471.7A
Other languages
English (en)
Other versions
CN102346708A (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.)
ZTE Corp
Original Assignee
ZTE Corp
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 ZTE Corp filed Critical ZTE Corp
Priority to CN201010243471.7A priority Critical patent/CN102346708B/zh
Priority to PCT/CN2011/071015 priority patent/WO2012016438A1/zh
Publication of CN102346708A publication Critical patent/CN102346708A/zh
Application granted granted Critical
Publication of CN102346708B publication Critical patent/CN102346708B/zh
Active legal-status Critical Current
Anticipated expiration legal-status Critical

Links

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/362Software debugging

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

本发明公开了一种调试器及其调试方法,所述方法包括:调试器在调试关系建立后,运行被调试任务,所述被调试任务运行在内核态或用户态;调试器在接收到上层发送的停止指令,或者在调试所述被调试任务时命中异常事件,或者在调试用户态被调试任务时捕获到关心的信号消息,停止运行所述被调试任务,所述停止的方式包括在被调试任务中设置停止标志位;调试器在所述被调试任务停止运行后进行任务访问,所述任务访问类型包括访问所述被调试任务的内存信息和/或访问寄存器信息。本发明所述方法实现了对被调试任务在用户地址空间和内核地址空间的运行进行跟踪和调试的目的。

Description

一种调试器及其调试方法
技术领域
本发明涉及计算机技术领域,尤其涉及一种调试器及其调试方法。
背景技术
在类UNIX操作系统中,提供了一种标准的服务使得用户态程序能够实现对底层硬件和服务的控制(如对文件系统的控制),这种服务称为系统调用(system calls)。而连接用户态程序和系统调用的桥梁称为库函数。当一个程序需要作系统调用的时候,它首先调用与之对应的库函数,通过库函数找到系统调用表和对应的系统调用号,再将相关参数放进与系统调用相关的寄存器中,然后调用软中断。这个中断就像一个让用户态程序得以接触到内核模式的窗口,使得库函数能够将参数和系统调用号交给内核,最后由内核完成系统调用的执行。用户态程序和库函数都是运行在用户地址空间,而系统调用则是运行在内核地址空间。
在嵌入式软件开发过程中,往往需要修改内核的相关接口,再由用户态程序通过库函数调用到这些内核接口。要对这类程序进行调试,就需要调试器具有从用户地址空间跟踪调试进内核地址空间的功能。因此,如何能够同时对被调试任务的用户地址空间和内核地址空间进行调试,成为调试器设计的一种需要。
调试器是用来帮助开发人员分析和定位程序故障的一种工具。按照调试的地址空间范围进行划分,目前的调试器可以分为内核级调试器和用户态调试器。内核级调试器能够跟踪和调试运行在内核态的任务。而用户态调试器只能对运行在用户态的任务进行跟踪和调试。
类UNIX操作系统已经提供了一套完整的机制用于用户态任务的跟踪和调试,即ptrace系统调用。ptrace系统调用提供了一种使得父进程得以监视和控制其他进程的方式,它能够改变子进程中的寄存器和内存信息,从而可以实现断点调试和系统调用的跟踪。目前已有的用户态调试器大多采用ptrace系统调用进行跟踪调试。虽然ptrace系统调用能够跟踪和调试子进程的运行,但ptrace系统调用只能对被调试任务的用户地址空间进行跟踪和调试,最多跟踪到库函数一级,无法通过库函数跟踪进内核。
内核级调试器是运行在内核态的,它能够对内核任务进行跟踪和调试。以WindRiver公司的Vxworks(一种嵌入式实时操作系统)为例,它提供了一种shell调试器,这种shell调试器就属于内核级调试器。而目前已有的内核级调试器只针对内核任务进行调试,不能对用户态任务进行调试,更不能从用户地址空间跟踪调试进内核地址空间。
在目前已有的各种调试器中,还没有实现能够同时对用户地址空间和内核地址空间进行调试的功能。
发明内容
本发明提供一种调试器及其调试方法,用以解决现有技术中的调试器不能同时对用户地址空间和内核地址空间进行跟踪调试的问题。
具体的,本发明提供一种调试方法,包括:
调试器在调试关系建立后,运行被调试任务,所述被调试任务运行在内核态或用户态;
调试器判断是否停止所述被调试任务,若是,在所述被调试任务中设置停止标志位,停止所述被调试任务的运行后进行任务访问;所述任务访问类型包括访问所述被调试任务的内存信息和/或寄存器信息;
其中,所述调制器对于因中断或异常停止的被调试任务,从内核堆栈上访问寄存器信息;对于非中断或非异常停止的内核态被调试任务,以及停止在用户地址空间的用户态被调试任务,通过调用ptrace系统调用,在thread_struct结构体中访问寄存器信息。
进一步地,本发明所述方法中,所述调试器在所述被调试任务为内核态任务时,直接对内核地址空间进行内存信息访问;在所述被调试任务为用户态任务时,调用ptrace系统调用对用户地址空间进行内存信息访问。
本发明所述方法进一步具有以下特点:
本发明所述方法中,调试器判断所述被调试任务是否停止的判断条件包括:
所述调试器接收到上层发送的停止指令;或者,所述调试器在调试所述被调试任务时发生异常事件;或者,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信号消息。
其中,所述调试器调试所述被调试任务时发生异常事件的处理过程包括:
所述调试器调用相应的异常处理函数进行异常处理,并在检测出当前异常事件为有效异常事件时,上报当前异常事件,并停止所述被调试任务的运行;所述异常事件至少包括断点异常事件和单步异常事件。
其中,所述断点异常事件中断点的设置方式包括:
所述调试器获取断点设置的内存地址,若为用户地址空间断点,直接将内存指令替换为断点指令;若为内核地址空间断点,待所述被调试任务被调度时,将内存指令替换为断点指令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原内存指令。
进一步地,本发明所述方法中,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,检测是否存在未处理的信号消息,若是,获取待处理信号消息的信号值,上报信号处理事件,并基于获取的所述信号值得到所关心的信号消息时,停止所述被调试任务。
本发明还提供一种调试器,包括:
调试开启模块,用于建立调试关系,运行被调试任务,所述被调试任务运行在内核态或用户态;
任务运行控制模块,用于在判断出需要停止所述被调试任务时,在所述被调试任务中设置停止标志位,停止所述被调试任务的运行;
任务访问模块,用于在所述任务运行控制模块停止运行所述被调试任务时,进行任务访问,所述任务访问类型包括访问所述被调试任务的内存信息和/或寄存器信息;其中,所述任务访问模块对于因中断或异常停止的被调试任务,从内核堆栈上获取寄存器信息。
其中,所述任务运行控制模块判断所述被调试任务是否停止的判断条件包括:
所述调试器接收到上层发送的停止指令;或者,所述调试器在调试所述被调试任务时发生异常事件;或者,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信号消息。
进一步地,本发明所述的调试器还包括:
异常处理模块,用于调用相应的异常处理函数进行异常处理,并在检测出当前异常事件为有效异常事件时,上报当前异常事件,并触发所述任务运行控制模块,停止所述被调试任务的运行;所述异常事件至少包括断点异常事件和单步异常事件。
进一步地,所述调试器还包括:
断点设置模块,用于获取断点设置的内存地址,若为用户地址空间断点,直接将内存指令替换为断点指令;若为内核地址空间断点,待所述被调试任务被调度时,将内存指令替换为断点指令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原内存指令。
进一步地,所述调试器还包括:
信号处理模块,用于在用户态被调试任务从内核地址空间切换到用户地址空间时,检测是否存在未处理的信号消息,若是,获取待处理信号消息的信号值,上报信号处理事件,并基于获取的所述信号值得到所关心的信号消息时,触发所述任务运行控制模块,停止所述被调试任务。
与现有技术相比,本发明有益效果如下:
本发明提供的调试方法和调试器,克服了现有的各种调试器不能同时支持对用户地址空间和内核地址空间进行调试功能的问题,达到了能够对被调试任务在用户地址空间和内核地址空间的运行进行跟踪和调试的目的。
附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作一简单地介绍,显而易见地,下面描述中的附图仅仅是本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下,还可以根据这些附图获得其他的附图。
图1为本发明提供的一种调试方法流程图;
图2为本发明提供的一种调试器的结构图;
图3为本发明实施例提供的一种调试器的结构图;
图4为本发明中调试器停止被调试任务运行流程图;
图5为本发明中调试器恢复被调试任务运行流程图;
图6为本发明中调试器访问被调试任务内存流程图;
图7为本发明中调试器访问被调试任务寄存器流程图;
图8为本发明中调试器断点设置流程图;
图9为本发明中调试器断点异常处理流程图;
图10为本发明中调试器单步异常处理流程图;
图11为本发明中调试器信号处理流程图。
具体实施方式
下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本发明一部分实施例,而不是全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本发明保护的范围。
为了解决现有技术中存在的各种调试器不能够同时支持对用户地址空间和内核地址空间进行跟踪调试的问题,本发明提供一种调试器及其调试方法。该调试器实现了对被调试程序在用户地址空间和内核地址空间的运行进行跟踪和调试的目的。该支持双态调试的调试器不仅支持对用户态任务的调试,同时也支持对内核态任务的调试;所述支持双态调试的调试器是一种内核级调试器。
如图1所示,为本发明提供的一种调试方法流程图,该方法具体包括:
步骤S101、调试器在调试关系建立后,运行被调试任务,所述被调试任务运行在内核态或用户态。
步骤S102、调试器判断是否停止所述被调试任务,若是,在所述被调试任务中设置停止标志位,停止所述被调试任务的运行。
该步骤中,所述调试器判断所述被调试任务是否停止的判断条件包括:
所述调试器接收到上层发送的停止指令;或者,所述调试器在调试所述被调试任务时发生异常事件;或者,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信号消息。
其中,所述调试器调试所述被调试任务时发生异常事件的处理过程包括:
所述调试器调用相应的异常处理函数进行异常处理,并在检测出当前异常事件为有效异常事件时,上报当前异常事件,并停止所述被调试任务的运行;所述异常事件至少包括断点异常事件和单步异常事件。
其中,所述断点异常事件中断点的设置方式包括:
所述调试器获取断点设置的内存地址,若为用户地址空间断点,直接将内存指令替换为断点指令;若为内核地址空间断点,待所述被调试任务被调度时,将内存指令替换为断点指令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原内存指令。
进一步的,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,检测是否存在未处理的信号消息,若是,获取待处理信号消息的信号值,上报信号处理事件,并基于获取的所述信号值得到所关心的信号消息时,停止所述被调试任务。
其中,所述调试器根据获取的信号值,查找预先配置的信号列表,根据信号列表中记录的信息,判断该信号值所对应的信号消息是否为所关心的信号消息。其中,信号列表是用户根据具体需求所配置的。
步骤S103、调试器在所述被调试任务停止运行后进行任务访问,所述任务访问类型包括访问所述被调试任务的内存信息和/或寄存器信息;其中,所述调制器对于因中断或异常停止的被调试任务,从内核堆栈上访问寄存器信息。
进一步的,调试器在进行任务访问后,恢复被调试任务的运行;其中,恢复方式为将所述被调试任务中设置的停止标志位删除。
如图2所示,为本发明提供的一种调试器,该调试器包括:
调试开启模块210,用于建立调试关系,运行被调试任务,所述被调试任务运行在内核态或用户态;
任务运行控制模块220,用于在判断出需要停止所述被调试任务时,在所述被调试任务中设置停止标志位,停止所述被调试任务的运行;
任务访问模块230,用于在任务运行控制模块220停止运行所述被调试任务时,进行任务访问;所述任务访问类型包括访问所述被调试任务的内存信息和/或寄存器信息;
其中,对于寄存器信息访问,任务访问模块230对于因中断或异常停止的被调试任务,从内核堆栈上获取寄存器信息;对于非中断或异常停止的内核态被调试任务,以及停止在用户地址空间的用户态被调试任务,通过调用ptrace系统调用,在thread_struct结构体中获取寄存器信息。
进一步地,对于内存信息访问,所述任务访问模块230在所述被调试任务为内核态任务时,直接对内核地址空间进行内存信息访问;在所述被调试任务为用户态任务时,调用ptrace系统调用对用户地址空间进行内存信息访问。
进一步地,所述任务运行控制模块220判断被调试任务是否停止的判断条件包括:
调试器接收到上层发送的停止指令;或者,调试器在调试被调试任务时发生异常事件;或者,调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信号消息。
基于上述特征,本发明所提供的调试器进一步包括:
异常处理模块240,用于调用相应的异常处理函数进行异常处理,并在检测出当前异常事件为有效异常事件时,上报当前异常事件,并触发所述任务运行控制模块220,停止所述被调试任务的运行;所述异常事件至少包括断点异常事件和单步异常事件。
断点设置模块250,用于获取断点设置的内存地址,若为用户地址空间断点,直接将内存指令替换为断点指令;若为内核地址空间断点,待所述被调试任务被调度时,将内存指令替换为断点指令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原指令。
以及,信号处理模块260,用于在用户态被调试任务从内核地址空间切换到用户地址空间时,检测是否存在未处理的信号消息,若是,获取待处理信号消息的信号值,上报信号处理事件,并基于获取的所述信号值得到所关心的信号消息时,触发所述任务运行控制模块220,停止所述被调试任务。
下面根据图3~图11给出本发明一个较佳的实施例,并结合对实施例的描述,进一步给出本发明的技术细节,使其能够更好地说明本发明的具体实现过程。
如图3所示,本发明还提供一种调试器,该调试器包括:调试开启模块300、任务运行控制模块310、内存访问控制模块320、寄存器访问控制模块330、断点设置模块340、异常处理模块350、信号处理模块360;具体的:
调试开启模块300,用于建立调试关系,运行被调试任务,所述被调试任务运行在内核态或用户态;
具体的,调试开启模块300通过执行attach操作,建立调试关系。
其中,attach被调试任务是支持双态调试的调试器进行调试的第一个操作,在实现了控制被调试任务运行的基础上,attach被调试任务操作除了执行设置被调试任务的ptrace属性,建立调试器与被调试任务父子关系外,还需要调用kertsk_inner_suspend_tsk()接口停止被调试任务的运行。需要修改的是linux/kernel/ptrace.c文件中的ptrace_attach()函数接口,其关键伪代码如下所示:
int ptrace_attach(struct task_struct*task){
      task->ptrace|=PT_PTRACED;    /*设置被调试任务attach属性*/
      __ptrace_link(task,current);  /*建立父子进程关系*/
      kertsk_inner_suspend_tsk(task);/*停止被调试任务*/
}
与attach任务对应的,还存在detach任务;
detach被调试任务是支持双态调试的调试器进行调试的最后一个操作。与attach任务相对应,支持双态调试的调试器detach任务调用的是sys_ptrace()函数接口,执行PTRACE_DETACH操作。detach被调试任务除了删除调试器与被调试任务父子关系外,还需要调用kertsk_inner_resume_tsk()接口恢复被调试任务的运行。需要修改的是linux/kernel/ptrace.c文件中的__ptrace_detach()函数接口,其关键伪代码如下所示:
static inline void__ptrace_detach(struct task_struct*child,unsigned int data){
      __ptrace_unlink(child);/*取消被调试关系*/
      kertsk_inner_resume_tsk(child);/*恢复被调试任务运行*/
}
任务运行控制模块310,控制被调试任务的运行,是调试器各种调试功能的基础,用于在判断出需要停止被调试任务时,在相应的被调试任务中设置停止标志位,使得对应被调试任务被停止调用。
该任务运行控制模块通过设置停止标志位的方式,控制被调试任务是否能够被内核调度,从而达到控制被调试任务运行的目的。
为了清楚的说明该任务运行控制模块310的具体控制过程,下面结合图4给出停止被调试任务运行的基本流程,具体包括:
步骤401、开始;
步骤402、任务运行控制模块310在相应被调试任务中设置停止标志位;
步骤403、判断上述被调试任务是否正在CPU上运行,若是,执行步骤404;否则,执行步骤410;
步骤404、CPU停止当前运行的被调试任务,重新选择一个任务进行调度;
步骤405、内核调度到被调试任务;
步骤406、检测是否设置了停止标志位,若是,执行步骤407;否则,执行步骤409。
步骤407、将被调试任务从任务队列中删除。
步骤408、重新选择一个任务调度,执行步骤412;
步骤409、执行被调试任务相关代码,执行步骤412;
步骤410、判断被调试任务是否在任务队列中,若是,执行步骤411;否则,执行步骤405;
步骤411、将被调试任务从任务队列中删除,执行步骤405;
步骤412、结束。
进一步地,任务运行控制模块310,还用于基于上层指令或任务访问完成后,撤销相应被调试任务中设置的停止标志位,使得对应被调试任务重新被唤醒接受调用。
如图5所示,为恢复被调试任务运行的基本流程,包括:
步骤501、开始;
步骤502、删除被调试任务停止标志位;
步骤503、唤醒被调试任务;
步骤504、内核调度到被调试任务;
步骤505、判断是否设置了停止标志位,若是,执行步骤507;否则,执行步骤506;
步骤506、执行被调试任务相关代码,执行步骤509;
步骤507、将被调试任务从任务队列中删除;
步骤508、重新选择一个任务调度;
步骤509、结束。
上述任务运行控制模块310从linux系统方面的改进,主要体现在以下几个方面:
(1)定义被调试任务停止标志位
在linux/include/sched.h文件的task_struct结构体中,增加被调试任务停止标志掩码值和相应的成员变量,如下所示:
struct task_struct{
#define KERTSK_SUSPEND 0x100 /*定义停止标志掩码值*/
int kertask_special_flags;/*标志位成员变量*/
}
(2)定义停止被调试任务运行接口
在linux/kernel/sched.c文件中,增加停止被调试任务函数接口kertsk_inner_suspend_tsk(),其关键伪代码如下所示:
int kertsk_inner_suspend_tsk(struct task_struct*tsk){
tsk->kertask_special_flags|=KERTSK_SUSPEND;/*设置停止标志位*/
tsk->state=TASK_STOPPED;/*设置任务停止状态*/
schedule();/*重新调度任务*/
}
(3)定义恢复被调试任务运行接口
在linux/kernel/sched.c文件中,增加停止被调试任务函数接口kertsk_inner_resume_tsk(),其关键伪代码如下所示:
     int kertsk_inner_resume_tsk(struct task_struct*tsk){
           tsk->kertask_special_flags&=~KERTASK_SUSPEND;
           wake_up_state(tsk,TASK_STOPPED|TASK_TRACED);
}
(4)修改内核任务调度流程
在内核任务调度流程中,当调度出来的任务判断被置了KERTSK_SUSPEND标志,则重新调度一个新的任务。以上操作需要对linux/kemel/sched.c文件中的schedule()函数进行相应的修改,其关键伪代码如下所示:
asmlinkage void__sched schedule(void){
reselect_next_kertsk:
next=pick_next_task(rq,prev);/*选择下一个被调度的任务*/
/*被调度的任务被设置了停止标志位*/
if(unlikely(next->ketask_special_flags & KERTASK_SUSPEND)){
next->state=TASK_STOP;     /*设置任务停止状态*/
deactivate_task(rq,next,1);/*从任务队列中删除*/
goto reselect_next_kertsk;   /*重新选择下一个被调度的任务*/
}
}
内存访问控制模块320;
内存访问控制模块,用于在被调试任务停止运行后,获取待访问的内存地址,在所述内存地址为用户态地址时,调用ptrace系统调用进行内存访问操作;在所述内存地址为内核态地址时,直接进行内存访问操作。
本发明所述调试器对被调试任务的内存访问主要分为用户地址空间的内存访问和内核地址空间的内存访问。
由于支持双态调试的调试器是一种内核级调试器,运行在内核地址空间,因此,支持双态调试的调试器可以直接对被调试任务的内核地址空间进行读写操作,不需要进行任何地址转换操作。
当支持双态调试的调试器对被调试任务的用户地址空间进行访问时,由于用户态地址是一个虚拟地址,需要通过地址转换才能进行访问。对于用户地址空间的访问,类UNIX操作系统已经提供了相关接口,如access_process_vm()函数等。因此,访问被调试任务的用户地址空间,支持双态调试的调试器可以调用ptrace系统调用,执行PTRACE_PEEKTEXT或者PTRACE_POKETEXT操作,来实现对被调试任务用户地址空间的读写操作。
如图6所示,为内存访问控制模块320对被调试任务的内存访问流程,包括:
步骤601、开始;
步骤602、获取待访问的内存地址;
步骤603、判断待访问的内存地址是否为用户态地址,若是,执行步骤605;否则,执行步骤604;
步骤604、直接对内核地址空间进行读写操作,执行步骤607;
步骤605、调用ptrace系统调用;
步骤606、执行PTRACE_PEEKTEXT或者PTRACE_POKETEXT操作,对用户地址空间进行读写操作;
步骤607、结束。
根据图6的流程,支持双态调试的调试器调用sys_ptrace()函数接口,执行PTRACE_PEEKTEXT或者PTRACE_POKETEXT操作,实现对被调试任务的内存访问。内存访问主要分为用户地址空间的内存访问和内核地址空间的内存访问,需要修改的是linux/mm/memory.c文件中的access_process_vm()函数接口,其关键伪代码如下所示:
    int access_process_vm(struct task_struct*tsk,unsigned long addr,void*buf,int
len,int write){
           if(IS_VALID_KADD(addr)){/*访问内核地址空间内存*/
                if(write){/*写内存*/
                     *addr=*buf;/*直接修改目标地址的值*/
    }
    else{ /*读内存*/
        *buf=*addr;/*直接读取目标地址的值*/
    }
    }
    else{ /*访问用户地址空间内存*/
        if(write){ /*写内存*/
            copy_to_user_page();/*修改用户地址空间内存接口*/
    }
    else{ /*读内存*/
        copy_from_user_page();/*读取用记地址空间内存接口*/
    }
    }
}
寄存器访问控制模块330;
寄存器访问控制模块,用于在被调试任务停止运行后,获取被调试任务信息,若该被调试任务为内核态任务且为中断或异常停止,从内核堆栈上访问被调试任务的寄存器信息;否则,通过调用ptrace系统调用进行寄存器访问;若被调试任务为用户态任务,则在所述被调试任务停止在用户地址空间时,通过调用ptrace系统调用进行寄存器访问;在所述被调试任务停止在内核地址空间时(此时用户态被调试任务肯定发生了中断或异常),从内核堆栈上访问被调试任务的寄存器信息。
其中,寄存器访问控制模块330在内核堆栈上访问被调试任务的寄存器信息时,记录下被调试任务发生中断或异常时的栈帧信息,根据栈帧信息和对应的CPU类型的pt_regs结构体信息,从内核堆栈上相应位置访问pt_regs结构体大小的内存值,这段内存值就对应着被调试任务发生中断或者异常时的寄存器信息。
本发明所述调试器对被调试任务的寄存器访问主要分为两种,一种是对内核态被调试任务的寄存器访问,另一种是对用户态被调试任务的寄存器访问。
在类UNIX操作系统中,不论是用户态任务还是内核态任务,都在内核中对应着一个task_struct结构体,用于保存与任务相关的一些信息。在task_struct结构体中,还存在一个thread_struct结构体,用于保存与任务相关的寄存器信息。
当内核态任务发生调度时,内核会将一些主要的寄存器信息(包括:指令寄存器、堆栈寄存器、通用寄存器、返回地址寄存器以及参数寄存器)保存到thread_struct结构体中。当内核态任务发生中断或者异常时,内核会将内核态任务的所有寄存器信息保存到内核堆栈上。
因此,支持双态调试的调试器访问内核态被调试任务的寄存器时,首先判断内核态被调试任务是否发生中断或者异常,如果内核态被调试任务发生了中断或者异常,调试器就从内核堆栈上访问被调试任务的寄存器信息;如果被调试任务发生了调度,就可以通过ptrace系统调用,执行PTRACE_PEEKUSER或者PTRACE_POKEUSER操作,来实现对内核态被调试任务的寄存器访问。
对于用户态被调试任务的寄存器访问,支持双态调试的调试器首先判断用户态被调试任务停止的地址空间。如果用户态被调试任务停止在用户地址空间,此时内核会将一些主要的寄存器信息保存到thread_struct结构体中,支持双态调试的调试器就可以通过ptrace系统调用,执行PTRACE_PEEKUSER或者PTRACE_POKEUSER操作,来实现对用户态被调试任务的寄存器访问;如果用户态被调试任务停止在内核地址空间,此时用户态被调试任务肯定发生了中断或者异常,内核会将被调试任务的所有寄存器信息保存到内核堆栈上,支持双态调试的调试器从内核堆栈上访问用户态被调试任务的寄存器信息即可。
支持双态调试的调试器访问被调试任务的寄存器流程,如图7所示,包括以下步骤:
步骤701、开始;
步骤702、获取被调试任务信息;
步骤703、判断是否是内核态被调试任务,若是,执行步骤704,否则,执行步骤709;
步骤704、判断被调试任务停止是否是发生中断或者异常,若是,执行步骤707;否则,执行步骤705;
步骤705、调用ptrace系统调用;
步骤706、执行PTRACE_PEEKUSER或者PTRACE_POKEUSER操作,进行寄存器访问后,执行步骤714;
步骤707、获取栈帧地址;
步骤708、从内核堆栈上相应位置访问pt_regs结构体大小的内存值,执行步骤714;
步骤709、判断被调试任务是否停止在用户地址空间,若是,执行步骤710;否则,执行步骤712;
步骤710、调用ptrace系统调用;
步骤711、执行PTRACE_PEEKUSER或者PTRACE_POKEUSER操作,进行寄存器访问后,执行步骤714;
步骤712、获取栈帧地址;
步骤713、从内核堆栈上相应位置访问pt_regs结构体大小的内存值,执行步骤714;
步骤714、结束。
根据图7的流程,支持双态调试的调试器调用sys_ptrace()函数接口,执行PTRACE_PEEKUSR或者PTRACE_POKEUSR操作,实现对被调试任务的寄存器访问。寄存器访问主要分为内核态被调试任务的寄存器访问和用户态被调试任务的寄存器访问,每种类型又可以分为从堆栈上访问和从寄存器结构体上访问两种。需要修改的是linux/arch/i386/kernel/ptrace.c文件中的getreg()和putreg()函数接口,其关键伪代码如下所示:
    static unsigned long getreg(struct task_struct*child,unsigned long regno){
          if(child->mm){ /*用户态被调试任务*/
               if(!IS_STOPPED_IN_KERNEL_SPACE(child)){ /*停止在用户地
址空间*/
                     retval=get_usr_reg(child,regno);/*从寄存器结构体上获取
寄存器信息*/
    }
               else {/*停止在内核地址空间*/
                    retval=get_reg_from_stack(child,regno);/*从堆栈上获取寄
存器信息*/
    }
    }
    else/*内核态被调试任务*/
    {
        if(!IS_INTERRUPTED(child)){/*发生调度*/
                  retval=get_usr_reg(child,regno);/*从寄存器结构体上获取
寄存器信息*/
    }
    else{/*发生中断或者异常*/
               retval=get_reg_from_stack(child,regno);/*从堆栈上获取寄
存器信息*/
    }
    }
    }
    static int putreg(struct task_struct*child,unsigned long regno,unsigned long
value){
        if(child->mm){/*用户态被调试任务*/
             if(!IS_STOPPED_IN_KERNEL_SPACE(child)){/*停止在用户地
址空间*/
                   put_usr_reg(child,regno,value);/*从寄存器结构体上修改寄
存器信息*/
    }
             else{/*停止在内核地址空间*/
                 put_reg_to_stack(child,regno,value);/*从堆栈上修改寄存器
信息*/
    }
    }
    else/*内核态被调试任务*/
    {
        if(!IS_INTERRUPTED(child)){/*发生调度*/
                  put_usr_reg(child,regno,value);/*从寄存器结构体上修改寄
存器信息*/
    }
    else{/*发生中断或者异常*/
               put_reg_to_stack(child,regno,value);/*从堆栈上修改寄存器
信息*/
    }
    }
    }
断点设置模块340;
在调试器需要设置断点时,断点设置模块,获取断点设置的内存地址,若断点为用户地址空间断点,直接修改用户地址空间内存,将内存指令替换为断点指令;若断点为内核地址空间断点,在被调试任务被调度时,修改用户地址空间内存,将内存指令替换为断点指令;并在被调试任务被内核调度出CPU时,将内核地址空间中的断点指令恢复成原内存指令。
调试器通常是通过将内存中的指令替换成断点指令进行断点设置的。当被调试任务运行到断点指令时,就会产生断点异常停止下来,并上报事件给调试器,此时调试器就可以查看被调试任务的信息。当被调试任务恢复运行以后,调试器再将原指令恢复回来。
支持双态调试的调试器的断点设置主要分为两种,一种是用户地址空间的断点设置,另一种是内核地址空间的断点设置。
由于被调试任务的用户地址空间是独立于其他任务,不会被其他任务所访问。因此,处于用户地址空间的断点不会被其他任务所遇到。而被调试任务的内核地址空间是与其他任务所共用的,如果在内核地址空间设置断点,就有可能被其他任务所遇到,造成非法的断点异常。
因此,对于支持双态调试的调试器进行断点设置时,如果断点是用户地址空间的断点,可以直接修改用户地址空间的内存,将内存指令替换为断点指令。如果断点是内核地址空间的断点,只有当被调试任务被内核调度进CPU时,才修改内核地址空间的内存,将内存指令替换为断点指令;当被调试任务被内核调度出CPU时,就将内核地址空间中的断点指令恢复成原指令。
支持双态调试的调试器的断点设置流程,如图8所示,包括以下步骤:
步骤801、开始;
步骤802、获取断点设置的内存地址;
步骤803、判断是否是用户地址空间断点,若是,执行步骤804;否则,执行步骤805;
步骤804、直接修改用户地址空间内存,将内存指令替换为断点指令,执行步骤807;
步骤805、判断被调试任务是否被调度,若是,执行步骤806;否则,执行步骤807;
步骤806、修改内核地址空间内存,将内存指令替换为断点指令,执行步骤807;
步骤807、结束。
异常处理模块350;
异常处理模块,用于在被调试任务被调度时,若发生异常事件,则基于异常类型,调用异常处理函数执行异常处理,并在上报当前的异常事件,并在当前异常事件为有效事件时,触发任务运行控制模块310,停止被调试任务的运行。
支持双态调试的调试器涉及到异常处理主要分为断点异常处理和单步异常处理。
在类UNIX操作系统中,当用户态任务运行遇到断点指令时,会停止下来进行断点异常处理,并发送SIGTRAP信号给调试器。而内核态任务运行遇到断点指令时,也会进入断点异常处理函数中进行相关的处理操作。
同时,在类UNIX操作系统中,ptrace系统调用也已经提供了对被调试任务进行单步操作的功能。ptrace(PTRACE_SINGLESTEP,...)会使内核在被调试任务的每一条指令执行前先将其阻塞,然后发送信号给调试器,并将控制权交给调试器。
由于支持双态调试的调试器是一种内核级调试器,不支持对信号的处理。并且不论是用户态被调试任务还是内核态被调试任务,当被调试任务运行遇到断点指令或者执行单步操作时,都会进入到内核的断点异常处理函数或者单步异常处理函数中。因此,可以通过修改内核的断点异常处理函数的方式来实现对被调试任务命中断点操作的处理。
在内核的断点异常处理函数和单步异常处理函数中,支持双态调试的调试器除了执行异常处理的相关操作外,还需要执行上报断点命中事件和停止被调试任务运行的操作,其流程如图9和图10所示。
如图9所示,为支持双态调试的调试器断点异常处理流程,具体包括:
步骤901、开始;
步骤902、被调试任务命中断点;
步骤903、进入内核的断点异常处理函数;
步骤904、断点命中相关处理;
步骤905、判断是否是有效断点,若是,执行步骤906,否则,执行步骤910;
步骤906、上报断点命中事件;
步骤907、删除内核地址空间中的断点;
步骤908、设置被调试任务的停止标志位;
步骤909、将被调试任务从任务运行队列中删除;
步骤910、结束。
根据图9所述的流程,支持双态调试的调试器的断点设置实际上是将内存中的指令修改为断点指令,其操作流程属于内存访问范畴,修改方法可以是在支持双态调试的调试器的代码中调用内存访问的相关接口进行断点指令的设置。
不论是用户态被调试任务还是内核态被调试任务,当遇到断点指令时,都会进入到内核的断点异常处理函数。在内核的断点异常处理函数中,支持双态调试的调试器除了执行断点异常处理的相关操作外,还需要执行上报断点命中事件和停止被调试任务运行的操作。需要修改的是linux/arch/i386/kernel/traps.c文件中的do_trap()函数接口,其关键伪代码如下所示:
    static void__kprobes do_trap(int trapnr,int signr,char*str,int vm86,
                   struct pt_regs*regs,long error_code,
                   siginfo_t*info){
           bp=lookup_breakpoint(regs->eip);/*根据断点异常地址查找断点*/
           if(bp){/*命中有效断点*/
                report_hit_breakpoint();/*上报命中断点事件*/
                kertsk_inner_suspend_task(current);/*停止被调试任务运行*/
                regs->eflags|=TF_MASK;/*设置单步标志*/
                current->kertask_special_flags|=DBG_STEP_OVER;/*设置跨断
点标志*/
                return;/*从断点异常中返回*/
    }
    }
如图10所示,为支持双态调试的调试器单步异常处理流程,具体包括:
步骤1001、开始;
步骤1002、调用ptrace系统调用设置被调试任务单步标志;
步骤1003、进入内核的单步异常处理函数;
步骤1004、单步异常相关处理;
步骤1005、判断是否是有效单步,若是,执行步骤1006;否则,执行步骤1009;
步骤1006、上报单步异常事件;
步骤1007、设置被调试任务的停止标志位;
步骤1008、将被调试任务从任务运行队列中删除,执行步骤1009;
步骤1009、结束。
根据图10的流程,对于单步异常处理,支持双态调试的调试器可以调用sys_ptrace()函数接口,执行PTRACE_SINGLESTEP操作,实现被调试任务的单步操作。为了实现这一功能,需要对内核实现以下几方面的修改。
(1)设置单步标志
由于支持双态调试的调试器采用设置停止标志位的方式来控制被调试任务的运行,因此,在设置被调试任务的单步标志后,还需要取消停止标志位,恢复被调试任务的运行。需要修改的是linux/arch/i386/kernel/ptrace.c文件中的arch_ptrace()函数接口,其关键伪代码如下:
long arch_ptrace(struct task_struct*child,long request,long addr,long data){
     case PTRACE_SINGLESTEP:/*设置单步标志操作*/
          set_singlestep(child);/*设置单步标志*/
kertsk_inner_resume_tsk(child);/*恢复被调试任务运行*/
          break;/*设置单步标志操作结束*/
}
(2)单步异常事件处理
当被调试任务进入单步异常函数时,支持双态调试的调试器除了执行单步异常处理的相关操作外,还需要执行上报单步异常事件和停止被调试任务运行的操作。需要修改的是linux/arch/i386/kernel/traps.c文件中的do_debug()函数接口,其关键伪代码如下所示:
    fastcall void__kprobes do_debug(struct pt_regs*regs,long error_code){
          regs->eflags&=~TF_MASK;/*取消单步标志*/
          if(is_valid_singstep(regs->eip)){/*有效单步*/
               report_singlestep_exception();/*上报单步异常事件*/
               kertsk_inner_suspend_task(current);/*停止被调试任务运行*/
               return;/*从单步异常中返回*/
    }
               else if(current->kertask_special_flags & DBG_STEP_OVER){/*
跨断点操作*/
                    insert_all_breakpoint();/*回插所有的断点*/
                    return;/*从单步异常中返回*/
    }
    }
信号处理模块360;
信号处理模块,用于在用户态被调试任务从内核地址空间切换到用户地址空间时,若用户态被调试任务的信号队列不为空,则调用信号处理函数,逐一获取信号队列中待处理信号,上报信号处理事件,并根据信号对应的信号值判定为关心的信号消息时,触发任务运行控制模块310,停止相应被调试任务的运行;若判定为不关心的信号消息时,不做处理,获取下一个信号。
在类UNIX操作系统中,当用户态被调试任务从内核地址空间切换到用户地址空间时,需要判断用户态被调试任务的信号队列是否为空。如果存在未处理的信号,需要对信号队列中的信号进行提取并进行相应的处理,同时上报给父进程。
由于支持双态调试的调试器是一种内核级调试器,虽然同用户态被调试任务存在父子进程关系,但对用户态被调试任务上报的信号不会进行处理。因此,支持双态调试的调试器要想获取用户态被调试任务信号处理的状态,就必须对内核中信号处理函数进行相应的修改。
当用户态被调试任务从内核地址空间切换到用户地址空间时,如果存在未处理的信号,就会进入内核的信号处理函数。在该函数中,支持双态调试的调试器首先获取用户态被调试任务待处理的信号值,再根据该信号值在预先配置的信号列表中查找相关设置,决定用户态被调试任务对该信号的处理流程,该处理流程具体包括停止被调试任务的运行,或者当前信号为不关心的信号,不做处理。
支持双态调试的调试器信号处理流程,如图11所示,包括以下步骤:
步骤1101、开始;
步骤1102、用户态被调试任务从内核地址空间切换到用户地址空间;
步骤1103、判断是否存在未处理的信号,若是,执行步骤1104;否则,执行步骤1107;
步骤1104、获取待处理信号值;
步骤1105、上报信号处理事件;
步骤1106、根据信号列表设置决定用户态被调试任务处理流程;
步骤1107、结束。
根据图11所述的流程,当用户态被调试任务从内核地址空间切换到用户地址空间时,如果存在未处理的信号,就会进入内核的信号处理函数。在该函数中,支持双态调试的调试器首先获取用户态被调试任务待处理的信号值,再根据信号列表中的相关设置,决定用户态被调试任务对该信号的处理流程。需要修改的是linux/kernel/signal.c文件中的get_signal_to_deliver()函数接口,其关键伪代码如下所示:
    int get_signal_to_deliver(siginfo_t*info,struct k_sigaction*return_ka,
    struct pt_regs*regs,void*cookie){
          for(;;){
                 signr=dequeue_signal(current,mask,info);/*从信号队列中获取
一个信号*/
                 if(!signr)
                        break;/*没有待处理的信号则退出*/
                 ret=report_debug_signal(signr);/*上报获取信号事件,确定信号
处理流程*/
                 if(ret==HANDLE_SIG_IGN){/*忽略信号处理*/
                      continue;/*获取下一个信号*/
    }
    else if(ret==HANDL_SIG_STOP){/*信号处理需要停止被调试任务*/
               kertsk_inner_suspend_task(current);/*停止被调试任务运行*/
    }
    else if(ret==HANDLE_SIG_ACT){/*执行信号处理函数*/
               do_sig_action(signr);/*根据信号值,执行信号处理函数*/
    }
        }
}
本发明提供的调试方法和调试器,克服了现有的各种调试器不能同时支持对用户地址空间和内核地址空间进行调试功能的问题,达到了能够对被调试程序在用户地址空间和内核地址空间的运行进行跟踪和调试的目的。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神和范围。这样,倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围之内,则本发明也意图包含这些改动和变型在内。

Claims (10)

1.一种调试方法,其特征在于,包括:
调试器在调试关系建立后,运行被调试任务,所述被调试任务运行在内核态或用户态;
调试器判断是否停止所述被调试任务,若是,在所述被调试任务中设置停止标志位,停止所述被调试任务的运行后进行任务访问;所述任务访问类型包括访问所述被调试任务的内存信息和/或寄存器信息;
其中,所述调试器对于因中断或异常停止的被调试任务,从内核堆栈上访问寄存器信息;对于非中断或非异常停止的内核态被调试任务,以及停止在用户地址空间的用户态被调试任务,通过调用ptrace系统调用,在thread_struct结构体中访问寄存器信息;
所述调试器在所述被调试任务为内核态任务时,直接对内核地址空间进行内存信息访问;在所述被调试任务为用户态任务时,调用ptrace系统调用对用户地址空间进行内存信息访问。
2.如权利要求1所述的方法,其特征在于,所述调试器判断所述被调试任务是否停止的判断条件包括:
所述调试器接收到上层发送的停止指令;或者,所述调试器在调试所述被调试任务时发生异常事件;或者,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信号消息。
3.如权利要求2所述的方法,其特征在于,所述调试器调试所述被调试任务时发生异常事件的处理过程包括:
所述调试器调用相应的异常处理函数进行异常处理,并在检测出当前异常事件为有效异常事件时,上报当前异常事件,并停止所述被调试任务的运行;所述异常事件至少包括断点异常事件和单步异常事件。
4.如权利要求3所述的方法,其特征在于,所述断点异常事件中断点的设置方式包括:
所述调试器获取断点设置的内存地址,若为用户地址空间断点,直接将内存指令替换为断点指令;若为内核地址空间断点,待所述被调试任务被调度时,将内存指令替换为断点指令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原内存指令。
5.如权利要求2所述的方法,其特征在于,
所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,检测是否存在未处理的信号消息,若是,获取待处理信号消息的信号值,上报信号处理事件,并基于获取的所述信号值得到所关心的信号消息时,停止所述被调试任务。
6.一种调试器,其特征在于,包括:
调试开启模块,用于建立调试关系,运行被调试任务,所述被调试任务运行在内核态或用户态;
任务运行控制模块,用于在判断出需要停止所述被调试任务时,在所述被调试任务中设置停止标志位,停止所述被调试任务的运行;
任务访问模块,用于在所述任务运行控制模块停止运行所述被调试任务时,进行任务访问,所述任务访问类型包括访问所述被调试任务的内存信息和/或寄存器信息;
其中,所述任务访问模块对于因中断或异常停止的被调试任务,从内核堆栈上获取寄存器信息;对于非中断或非异常停止的内核态被调试任务,以及停止在用户地址空间的用户态被调试任务,通过调用ptrace系统调用,在thread_struct结构体中访问寄存器信息;
所述任务访问模块在所述被调试任务为内核态任务时,直接对内核地址空间进行内存信息访问;在所述被调试任务为用户态任务时,调用ptrace系统调用对用户地址空间进行内存信息访问。
7.如权利要求6所述的调试器,其特征在于,所述任务运行控制模块判断所述被调试任务是否停止的判断条件包括:
所述调试器接收到上层发送的停止指令;或者,所述调试器在调试所述被调试任务时发生异常事件;或者,所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信号消息。
8.如权利要求7所述的调试器,其特征在于,所述调试器还包括:
异常处理模块,用于调用相应的异常处理函数进行异常处理,并在检测出当前异常事件为有效异常事件时,上报当前异常事件,并触发所述任务运行控制模块,停止所述被调试任务的运行;所述异常事件至少包括断点异常事件和单步异常事件。
9.如权利要求6或8所述的调试器,其特征在于,所述调试器还包括:
断点设置模块,用于获取断点设置的内存地址,若为用户地址空间断点,直接将内存指令替换为断点指令;若为内核地址空间断点,待所述被调试任务被调度时,将内存指令替换为断点指令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原内存指令。
10.如权利要求7所述的调试器,其特征在于,所述调试器还包括:
信号处理模块,用于在用户态被调试任务从内核地址空间切换到用户地址空间时,检测是否存在未处理的信号消息,若是,获取待处理信号消息的信号值,上报信号处理事件,并基于获取的所述信号值得到所关心的信号消息时,触发所述任务运行控制模块,停止所述被调试任务。
CN201010243471.7A 2010-08-03 2010-08-03 一种调试器及其调试方法 Active CN102346708B (zh)

Priority Applications (2)

Application Number Priority Date Filing Date Title
CN201010243471.7A CN102346708B (zh) 2010-08-03 2010-08-03 一种调试器及其调试方法
PCT/CN2011/071015 WO2012016438A1 (zh) 2010-08-03 2011-02-16 一种调试器及其调试方法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201010243471.7A CN102346708B (zh) 2010-08-03 2010-08-03 一种调试器及其调试方法

Publications (2)

Publication Number Publication Date
CN102346708A CN102346708A (zh) 2012-02-08
CN102346708B true CN102346708B (zh) 2014-07-16

Family

ID=45545403

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201010243471.7A Active CN102346708B (zh) 2010-08-03 2010-08-03 一种调试器及其调试方法

Country Status (2)

Country Link
CN (1) CN102346708B (zh)
WO (1) WO2012016438A1 (zh)

Families Citing this family (25)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US8914776B2 (en) * 2012-05-17 2014-12-16 Microsoft Corporation Assisting development tools through inserted code statements
CN104461806A (zh) * 2013-09-16 2015-03-25 中兴通讯股份有限公司 一种数据断点监控方法、装置及调试器
CN104932972B (zh) * 2014-03-19 2018-10-09 北京娜迦信息科技发展有限公司 一种反动态调试应用程序的方法及装置
CN105630664B (zh) * 2014-11-06 2020-03-13 中兴通讯股份有限公司 一种反向调试方法、装置及调试器
CN104536886A (zh) * 2014-12-23 2015-04-22 浪潮电子信息产业股份有限公司 一种选择内核进行调试的方法
CN105354136B (zh) 2015-09-25 2018-06-15 华为技术有限公司 一种调试方法、多核处理器和调试设备
CN105224454B (zh) * 2015-09-25 2018-06-05 华为技术有限公司 一种调试方法、多核处理器和调试设备
CN105760305A (zh) * 2016-03-09 2016-07-13 上海博达数据通信有限公司 一种linux下的系统实时性监控方法
CN106227671B (zh) * 2016-08-05 2018-10-26 网易(杭州)网络有限公司 程序运行性能分析方法及装置
US10785848B2 (en) * 2016-09-29 2020-09-22 Signify Holding B.V. Lighting system commissioning
CN106970877A (zh) * 2017-03-15 2017-07-21 杭州中天微系统有限公司 控制调试请求的装置及数据处理器
CN109144844B (zh) 2017-06-27 2023-01-31 阿里巴巴集团控股有限公司 追踪方法、装置、设备和机器可读介质
CN109308213B (zh) * 2017-07-27 2021-10-01 南京南瑞继保电气有限公司 基于改进任务调度机制的多任务断点调试方法
US10846211B2 (en) 2018-03-21 2020-11-24 Microsoft Technology Licensing, Llc Testing kernel mode computer code by executing the computer code in user mode
CN112231198B (zh) * 2019-07-15 2024-04-12 腾讯科技(深圳)有限公司 一种恶意进程调试方法、装置、电子设备及介质
CN110502325B (zh) * 2019-08-12 2023-06-02 北京和利时系统工程有限公司 一种任务运行方法及装置、计算机可读存储介质
CN112416695B (zh) * 2019-08-20 2023-03-28 北京东土科技股份有限公司 一种全局变量监控方法、装置、设备及存储介质
CN110955598B (zh) * 2019-11-20 2024-02-27 杭州迪普科技股份有限公司 一种内核态程序的断点处理方法及装置
CN111062061B (zh) * 2019-12-10 2023-01-24 厦门市美亚柏科信息股份有限公司 一种用于ios系统的安全防护方法和系统
CN111459827A (zh) * 2020-04-07 2020-07-28 长沙景嘉微电子股份有限公司 一种跨平台调试shell的实现方法、装置和计算机
CN111639312B (zh) * 2020-06-02 2023-04-14 腾讯科技(成都)有限公司 反调试方法、装置、存储介质及电子装置
CN112711527B (zh) * 2020-12-16 2024-02-06 北京科银京成技术有限公司 一种实时进程的调试方法、装置、目标机和存储介质
CN112799816B (zh) * 2021-02-01 2023-03-31 安徽芯纪元科技有限公司 一种嵌入式操作系统的多任务程序指定任务调试方法
CN114035855B (zh) * 2021-09-30 2023-10-27 鸣芯信息科技(上海)有限公司 固件的调试方法、装置、终端及存储介质
CN114253837B (zh) * 2021-11-22 2023-03-24 杭州加速科技有限公司 一种ate测试机程序的多线程调试方法、系统及测试机台

Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN1779652A (zh) * 2004-11-24 2006-05-31 中兴通讯股份有限公司 一种调试操作系统内核态程序的方法及装置
CN101504626A (zh) * 2009-03-06 2009-08-12 中兴通讯股份有限公司 一种调试控制实现方法及系统
CN101685420A (zh) * 2008-09-24 2010-03-31 中兴通讯股份有限公司 多线程调试方法和装置

Family Cites Families (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US7996722B2 (en) * 2009-01-02 2011-08-09 International Business Machines Corporation Method for debugging a hang condition in a process without affecting the process state

Patent Citations (3)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN1779652A (zh) * 2004-11-24 2006-05-31 中兴通讯股份有限公司 一种调试操作系统内核态程序的方法及装置
CN101685420A (zh) * 2008-09-24 2010-03-31 中兴通讯股份有限公司 多线程调试方法和装置
CN101504626A (zh) * 2009-03-06 2009-08-12 中兴通讯股份有限公司 一种调试控制实现方法及系统

Also Published As

Publication number Publication date
CN102346708A (zh) 2012-02-08
WO2012016438A1 (zh) 2012-02-09

Similar Documents

Publication Publication Date Title
CN102346708B (zh) 一种调试器及其调试方法
WO2021057057A1 (zh) 操作系统级程序的目标码覆盖率测试方法、系统及介质
CN100555218C (zh) 用于改善片上仿真系统中高级语言的仿真速度的装置和方法
US6708326B1 (en) Method, system and program product comprising breakpoint handling mechanism for debugging and/or monitoring a computer instruction sequence
JP5905904B2 (ja) デバッグ例外生成の制御
KR101019209B1 (ko) 임베디드 소프트웨어의 인터페이스 자동 추출 장치 및 그방법
CN101122880A (zh) 内嵌调试器的嵌入式系统及嵌入式系统调试方法
JP5905911B2 (ja) シングルステップ実行を用いる診断コード
CN105718374A (zh) 一种热点模块指令跟踪的方法及系统
KR20070109432A (ko) 커널 인지 디버깅 장치 및 방법
US7765526B2 (en) Management of watchpoints in debuggers
CN104932972B (zh) 一种反动态调试应用程序的方法及装置
US7788543B2 (en) Methods and systems for generating and storing computer program execution trace data
CN102207913B (zh) 嵌入式系统中写保护的控制方法和装置
US7823019B2 (en) Debug circuitry
US7890935B2 (en) Thread-specific presentation of breakpoints
CN105095079A (zh) 一种热点模块指令跟踪的方法及设备
CN101237350B (zh) 用于多任务环境单板机的全局变量异常改写定位方法
CN1329839C (zh) 一种计算机cpu抗干扰的设计方法
Prada-Rojas et al. Observation tools for debugging and performance analysis of embedded linux applications
TW201723813A (zh) 用於診斷執行串流指令的處理器之方法、設備、及系統
Smith et al. Comparison of approaches to use existing architectural features in embedded processors to achieve hardware-assisted test insertion
Majeed et al. Research Article Debugging Nondeterministic Failures in Linux Programs through Replay Analysis
Majeed et al. Debugging Nondeterministic Failures in Linux Programs through Replay Analysis
CN109947414A (zh) 一种基于Vxworks系统的动态钩子函数实现方法

Legal Events

Date Code Title Description
C06 Publication
PB01 Publication
C10 Entry into substantive examination
SE01 Entry into force of request for substantive examination
C14 Grant of patent or utility model
GR01 Patent grant