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

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

Info

Publication number
WO2012016438A1
WO2012016438A1 PCT/CN2011/071015 CN2011071015W WO2012016438A1 WO 2012016438 A1 WO2012016438 A1 WO 2012016438A1 CN 2011071015 W CN2011071015 W CN 2011071015W WO 2012016438 A1 WO2012016438 A1 WO 2012016438A1
Authority
WO
WIPO (PCT)
Prior art keywords
task
debugged
debugger
kernel
breakpoint
Prior art date
Application number
PCT/CN2011/071015
Other languages
English (en)
French (fr)
Inventor
吴春江
Original Assignee
中兴通讯股份有限公司
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 中兴通讯股份有限公司 filed Critical 中兴通讯股份有限公司
Publication of WO2012016438A1 publication Critical patent/WO2012016438A1/zh

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

Definitions

  • the present invention relates to computer technology, and in particular, to a debugger and a debugging method thereof. Background technique
  • a standard service is provided that enables user-mode programs to control the underlying hardware and services (such as control of file systems), which are called system calls.
  • the bridge connecting user-mode programs and system calls is called a library function.
  • a program When a program needs to make a system call, it first calls the corresponding library function, finds the system call table and the corresponding system call number through the library function, and then puts the relevant parameters into the register related to the system call, and then calls Soft interrupt.
  • This interrupt is like a window that allows the user-mode program to access the kernel mode, allowing the library function to pass parameters and system call numbers to the kernel, and finally the kernel completes the execution of the system call.
  • User mode programs and library functions are run in the user address space, while system calls are run in the kernel address space.
  • the debugger is a tool used to help developers analyze and locate program failures.
  • the current debugger can be divided into a kernel-level debugger and a user-mode debugger. Kernel-level debuggers can track and debug tasks running in kernel mode. The user mode debugger can only track and debug tasks running in user mode.
  • the UNIX-like operating system already provides a complete mechanism for tracking and debugging user-space tasks, namely the ptrace system call.
  • the ptrace system call provides a way for the parent process to monitor and control other processes. It can change the register and memory information in the child process, enabling tracepoint debugging and system call tracking.
  • Most of the existing user mode debuggers use the ptrace system call for trace debugging.
  • the ptrace system call can track and debug the running of the child process, the ptrace system call can only track and debug the user address space of the task being debugged, up to the level of the library function, and cannot be tracked into the kernel address space through the library function. .
  • the kernel-level debugger runs in kernel mode and is capable of tracing and debugging kernel tasks. Take WindRiver's Vxworks (an embedded real-time operating system) as an example, it provides a shell debugger, which is a kernel-level debugger. At present, the kernel-level debuggers are only debugged for kernel tasks, and cannot debug user-mode tasks, and cannot be debugged into the kernel address space from the user address space.
  • the present invention provides a debugger and a debugging method thereof, which are used to solve the problem that the debugger in the prior art cannot track and debug the user address space and the kernel address space at the same time.
  • a debugging method includes: after the debug relationship is established, the debugger runs the debugged task, and the debugged task runs in a kernel state or a user state; the debugger determines whether to stop the debugged task, and if so, in the Setting a stop flag bit in the debug task to stop the task access after the running of the debugged task; the task access type includes accessing memory information and/or register information of the debugged task; wherein the modulator is A debugged task that interrupts or aborts, accessing register information from the kernel stack.
  • the determining condition that the debugger determines whether the debugged task is stopped includes: the debugger receives a stop instruction sent by an upper layer; or the debugger generates an abnormal event when debugging the debugged task; or The debugger captures the signal message of interest when the user mode is switched from the kernel address space to the user address space by the debug task.
  • the process of the exception event occurring when the debugger debugs the debugged task includes: the debugger invoking a corresponding exception handling function to perform exception processing, and reporting the current abnormal event when detecting that the current abnormal event is a valid abnormal event And stop the running of the task being debugged.
  • the abnormal event includes a breakpoint abnormal event
  • the breakpoint abnormal event interrupt point is set by: the debugger obtains a memory address set by the breakpoint, and if the user address space breakpoint, directly replaces the memory instruction with a break Point instruction; if it is a kernel address space breakpoint, when the debugged task is scheduled, replace the memory instruction with a breakpoint instruction, and when the debugged task completes scheduling, the breakpoint instruction in the kernel address space is Restore to the original memory instruction.
  • the debugger captures the signal message of interest when the user mode is switched from the kernel address space to the user address space by the debugging task, including: detecting whether there is an unprocessed signal message, and if yes, acquiring a signal value of the to-be-processed signal message, reporting The signal is processed, and the debugged task is stopped when the signal message of interest is obtained based on the acquired signal value.
  • a debugger including:
  • the debugging startup module is configured to establish a debugging relationship, run the debugged task, and the debugged task runs in a kernel state or a user state;
  • a task operation control module configured to: when it is determined that the debugged task needs to be stopped, setting a stop flag bit in the debugged task, and stopping the running of the debugged task;
  • a task access module configured to perform task access when the task execution control module stops running the debugged task, where the task access type includes accessing memory information and/or register information of the debugged task;
  • the task access module obtains register information from the kernel stack for debugged tasks that are interrupted or stopped abnormally.
  • the determining condition that the task running control module determines whether the debugged task is stopped includes: the debugger receiving a stop instruction sent by an upper layer; or the debugger generating an abnormal event when debugging the debugged task; or The debugger captures a signal message of interest when the user mode is switched from the kernel address space to the user address space by the debug task.
  • the debugger further includes: an exception processing module, configured to invoke a corresponding exception processing function for exception processing, and when detecting that the current abnormal event is a valid abnormal event, reporting the current abnormal event, and triggering the task running control module, Stop the running of the debugged task.
  • an exception processing module configured to invoke a corresponding exception processing function for exception processing, and when detecting that the current abnormal event is a valid abnormal event, reporting the current abnormal event, and triggering the task running control module, Stop the running of the debugged task.
  • the debugger further includes: a breakpoint setting module, configured to obtain a memory address set by the breakpoint, and if the user address space breakpoint, directly replace the memory instruction with a breakpoint instruction; if the kernel address space breakpoint, the standby When the debug task is scheduled, the memory instruction is replaced with a breakpoint instruction, and when the debug task completes the scheduling, the breakpoint instruction in the kernel address space is restored to the original memory instruction.
  • a breakpoint setting module configured to obtain a memory address set by the breakpoint, and if the user address space breakpoint, directly replace the memory instruction with a breakpoint instruction
  • the kernel address space breakpoint if the kernel address space breakpoint, the standby
  • the debugger further includes: a signal processing module, configured to detect whether an unprocessed signal message exists when the user mode is switched from the kernel address space to the user address space by the debugging task, and if yes, obtain a signal value of the to-be-processed signal message, When the signal processing event is reported, and the signal message of interest is obtained based on the obtained signal value, the task operation control module is triggered to stop the debugged task.
  • a signal processing module configured to detect whether an unprocessed signal message exists when the user mode is switched from the kernel address space to the user address space by the debugging task, and if yes, obtain a signal value of the to-be-processed signal message, When the signal processing event is reported, and the signal message of interest is obtained based on the obtained signal value, the task operation control module is triggered to stop the debugged task.
  • the debugging method and the debugger provided by the invention overcome the problems that the existing debuggers cannot simultaneously support the debugging function of the user address space and the kernel address space, and achieve the ability to debug the task in the user address space and the kernel address.
  • the operation of the space is for tracking and debugging purposes.
  • FIG. 1 is a schematic flow chart of a debugging method provided by the present invention
  • FIG. 2 is a schematic structural diagram of a debugger provided by the present invention.
  • FIG. 3 is a structural diagram of a debugger according to an embodiment of the present invention.
  • FIG. 5 is a flowchart of running a debugger recovery debug task according to the present invention.
  • FIG. 6 is a flowchart of a memory of a debugger accessing a debugged task in the present invention
  • FIG. 7 is a flow chart of a debugger accessing a debugged task register in the present invention.
  • FIG. 8 is a flow chart of a debugger breakpoint setting in the present invention.
  • FIG. 9 is a flowchart of a debugger breakpoint exception processing in the present invention.
  • FIG. 10 is a flowchart of a single step abnormality processing of a debugger in the present invention
  • Figure 11 is a flow chart showing the processing of the debugger signal in the present invention. detailed description
  • the present invention provides a debugger and a debugging method thereof.
  • the debugger implements the purpose of tracking and debugging the running of the debugger in the user address space and the kernel address space.
  • the debugger that supports two-state debugging not only supports debugging of user-mode tasks, but also supports debugging of kernel-state tasks; the debugger that supports two-state debugging is a kernel-level debugger.
  • FIG. 1 a flow chart of a debugging method provided by the present invention, the method specifically includes:
  • Step 101 After the debug relationship is established, the debugger runs the debugged task, and the debugged task runs in an internal state or a user state.
  • Step 102 The debugger determines whether to stop the debugged task. If yes, set a stop flag in the debugged task to stop the running of the debugged task.
  • the determining condition that the debugger determines whether the debugged task is stopped includes:
  • the debugger receives a stop instruction sent by an upper layer; or, the debugger generates an abnormal event when debugging the debugged task; or, the debugger is switched from a kernel address space to a user address by a debugger in a user state. In the space, the signal message of interest is captured.
  • the process of the exception event occurring when the debugger debugs the debugged task includes: the debugger calls a corresponding exception handling function to perform exception processing, and when detecting that the current abnormal event is a valid abnormal event, ⁇ the current abnormal event, and stop the running of the debugged task; the abnormal event includes at least a breakpoint abnormal event and a single-step abnormal event.
  • the setting manner of the interruption point of the breakpoint abnormal event includes:
  • the debugger obtains a memory address set by a breakpoint, and if it is a user address space breakpoint, directly replaces the memory instruction with a breakpoint instruction; if it is a kernel address space breakpoint, when the debugged task is scheduled, the memory is The instruction is replaced with a breakpoint instruction, and when the debugged task completes scheduling, the breakpoint instruction in the kernel address space is restored to the original memory instruction.
  • the debugger detects whether there is an unprocessed signal message when the user mode is switched from the kernel address space to the user address space by the debugging task, and if yes, acquires a signal value of the to-be-processed signal message, reports a signal processing event, and The debugged task is stopped when the signal signal of interest is obtained based on the acquired signal value.
  • the debugger searches for a pre-configured signal list according to the acquired signal value, and determines whether the signal message corresponding to the signal value is a signal message of interest according to the information recorded in the signal list.
  • the table is configured by the user according to specific needs.
  • Step 103 The debugger performs task access after the debugged task stops running, where the task access type includes accessing memory information and/or register information of the debugged task; wherein the modulator is for interrupt or abnormality
  • the stopped debug task accesses the register information from the kernel stack.
  • the debugger resumes the running of the debugged task; wherein the recovery mode is to delete the stop flag bit set in the debugged task.
  • the present invention provides a debugger, and the debugger includes:
  • the debugging startup module 210 is configured to establish a debugging relationship, run the debugged task, and the debugged task runs in a kernel state or a user state;
  • the task operation control module 220 is configured to: when it is determined that the debugged task needs to be stopped, setting a stop flag bit in the debugged task, and stopping the running of the debugged task;
  • the task access module 230 is configured to perform task access when the task execution control module 220 stops running the debugged task; the task access type includes accessing memory information and/or register information of the debugged task; Register information access, task access module 230 obtains register information from the kernel stack for debugged tasks that are interrupted or stopped abnormally; for kernel states that are non-interrupted or abnormally stopped, debugged tasks, and user states that are stopped in the user address space are The debug task obtains register information in the thread_struct structure by calling the ptrace system call.
  • the task accessing module 230 directly accesses the memory address space of the kernel address space when the debugged task is a kernel state task; when the debugged task is a user state task, the ptrace is invoked.
  • the system call accesses memory information to the user address space.
  • the determining condition that the task running control module 220 determines whether the debugged task is stopped includes: receiving a stop instruction sent by the upper layer; or generating an abnormal event when debugging the debugged task; or, the user state is debugged from the task When the kernel address space is switched to the user address space, the signal message of interest is captured.
  • the debugger provided by the present invention further includes:
  • the exception handling module 240 is configured to invoke a corresponding exception handling function to perform exception processing, and when detecting that the current abnormal event is a valid abnormal event, report the current abnormal event, and trigger the task running control module 220 to stop the debugging.
  • the operation of the task includes: a breakpoint exception event and a single-step exception event; a breakpoint setting module 250, configured to obtain a memory address set by the breakpoint, and if the user address space breakpoint, directly replace the memory instruction with Breakpoint instruction; if it is a kernel address space breakpoint, when the debugged task is scheduled, replace the memory instruction with a breakpoint instruction, and when the debugged task completes scheduling, breakpoints in the kernel address space The instruction is restored to the original instruction;
  • the signal processing module 260 is configured to detect whether an unprocessed signal message exists when the user state is switched from the kernel address space to the user address space by the debugging task, and if yes, obtain a signal value of the to-be-processed signal message, and report the signal processing event. And triggering the task operation when the signal signal of interest is obtained based on the obtained signal value
  • the row control module 220 stops the debugged task.
  • FIG. 1 A preferred embodiment of the present invention will now be described with reference to the accompanying drawings in which: FIG.
  • a debugger provided by the present invention includes: a debug open module 300, a task run control module 310, a memory access control module 320, a register access control module 330, a breakpoint setting module 340, an exception processing module 350, Signal processing module 360; specific:
  • the debugging startup module 300 is configured to establish a debugging relationship, run the debugged task, and the debugged task runs in a kernel state or a user state;
  • the debug open module 300 establishes a debug relationship by performing an attach operation.
  • the attach debug task is the first operation of the debugger that supports the two-state debug.
  • the attach debug task operation is performed in addition to executing the ptrace attribute of the set debug task.
  • the debugger also needs to call the kertsk_inner_suspend_tsk( ) interface to stop the running of the debugged task.
  • the ptrace_attach( ) function interface in the linux/kernel/ptrace.c file.
  • the detach debug task is the last operation of the debugger that supports two-state debugging.
  • the debugger that supports two-state debugging uses the sys_ptrace( ) function interface to perform the PTRACE DETACH operation.
  • the detach debug task also needs to call the kertsk_inner_resume_tsk() interface to resume the running of the debugged task.
  • What needs to be modified is the trace_detach( ) function interface in the linux/kernel/ptrace.c file.
  • the key pseudo code is as follows:
  • the task running control module 310 controls the running of the debugged task, and is the basis for the debugger to implement various debugging functions, and is used to set a stop flag in the corresponding debugged task when determining that the debugged task needs to be stopped. It is called to stop the corresponding task being debugged.
  • the task operation control module 310 controls whether the debugged task can be scheduled by the kernel by setting the stop flag bit, thereby achieving the purpose of controlling the running of the debugged task.
  • FIG. 4 specifically includes:
  • Step 401 starting the current process
  • Step 402 the task operation control module 310 sets a stop flag bit in the corresponding debug task; Step 403, it is determined whether the debugged task is running on the CPU, and if so, step 404 is performed; otherwise, step 410 is performed;
  • Step 404 The CPU stops the currently running debugged task, and reselects a task for scheduling.
  • Step 405 The kernel schedules to the debugged task;
  • Step 406 Detect whether a stop flag is set, and if yes, go to step 407; otherwise, go to step 409; Step 407, delete the debugged task from the task queue;
  • Step 408 reselect a task scheduling, and perform step 412;
  • Step 409 executing the debugged task related code, performing step 412;
  • Step 410 Determine whether the task to be debugged is in the task queue, and if yes, execute step 411; otherwise, execute step 405;
  • Step 411 the task to be debugged is deleted from the task queue, step 405 is performed;
  • Step 412 ending the current process.
  • the task running control module 310 is further configured to cancel the stop flag set in the corresponding debugged task after the access of the upper layer instruction or the task is completed, so that the corresponding debugged task is reawakened and accepted.
  • the basic process for restoring the task being debugged includes:
  • Step 501 starting the current process
  • Step 502 Delete the debugged task stop flag bit.
  • Step 503 waking up the debugged task
  • Step 504 The kernel is scheduled to be debugged.
  • Step 505 it is determined whether the stop flag is set, if yes, go to step 507; otherwise, go to step 506;
  • Step 506 execute the debugged task related code, perform step 509;
  • Step 507 Delete the debugged task from the task queue.
  • Step 508 Reselect a task schedule
  • Step 509 ending the current process.
  • the improvement of the above-mentioned task operation control module 310 from the Linux system is mainly reflected in the following aspects: (1) Defining the stop flag of the debugged task
  • Tsk->state TASK STOPPED; /*Set the task stop state */
  • the boost port is retries the task task interface kertsk_inner_resume_tsk( ) with the key pseudo-code as follows:
  • Next pick— next_task(rq, prev); /*Select the next scheduled task */
  • Next->state TASK STOP; /*Set the task stop status*/ Deactivate_task(rq, next, 1); /* is removed from the task queue */
  • the memory access control module 320 is configured to acquire a memory address to be accessed after the debugged task stops running, and invoke a ptrace system call to perform a memory access operation when the memory address is a user state address; the memory address is a kernel When the address is in the state, the memory access operation is directly performed.
  • the memory access of the debugger of the present invention to the debugged task is mainly divided into a memory access of the user address space and a memory access of the kernel address space.
  • the debugger that supports two-state debugging is a kernel-level debugger that runs in the kernel address space, the debugger that supports two-state debugging can directly read and write the kernel address space of the task being debugged, without any need to do anything. Address translation operation.
  • the debugger that supports two-state debugging accesses the user address space of the task being debugged, since the user-mode address is a virtual address, address translation is required to access it.
  • the debugger that supports the two-state debugging can perform the PTRACE PEEKTEXT or PTRACE_POKETEXT operation by calling the ptrace system call to implement the read and write operations on the user address space of the debugged task.
  • the memory access control module 320 performs a memory access process for the debugged task, including: Step 601: Start the current process;
  • Step 602 Obtain a memory address to be accessed.
  • Step 603 determining whether the memory address to be accessed is a user mode address, and if so, executing step 605; otherwise, performing step 604;
  • Step 604 directly read and write the kernel address space, step 607;
  • Step 605 calling a ptrace system call
  • Step 606 Perform a PTRACE PEEKTEXT or PTRACE POKETEXT operation to perform a read and write operation on the user address space.
  • Step 607 ending the current process.
  • the debugger supporting the two-state debugging calls the sys_ptrace() function interface, and executes
  • *addr *buf; /* directly modify the value of the target address */ else ⁇ / * read memory * /
  • the register access control module 330 is configured to obtain the debugged task information after the debugged task stops running, and access the register information of the debugged task from the kernel stack if the debugged task is a kernel-state task and is interrupted or abnormally stopped; Otherwise, the register access is performed by calling the ptrace system call; if the debug task is a user mode task, when the debug task is stopped in the user address space, the register access is performed by calling the ptrace system call; In the kernel address space (when the user mode is interrupted or abnormal by the debug task), the register information of the debugged task is accessed from the kernel stack.
  • the register access control module 330 accesses the register information of the debugged task on the kernel stack, records the stack frame information when the debug task is interrupted or abnormal, according to the stack frame information and the pt_regs structure information of the corresponding CPU type.
  • the memory value of the pt_regs structure size is accessed from the corresponding position on the kernel stack, and the memory value corresponds to the register information when the debug task is interrupted or abnormal.
  • the debugger of the present invention has two main types of register accesses to the debugged task, one is register access to the kernel state being debugged, and the other is register access to the user state being debugged.
  • both the user-mode task and the kernel-mode task correspond to a task_struct structure in the kernel, which is used to save some information related to the task.
  • task_struct structure there is also a thread_struct structure for holding register information related to the task.
  • the kernel When a kernel-mode task is scheduled, the kernel saves some of the main register information (including: instruction registers, stack registers, general-purpose registers, return address registers, and parameter registers) to the thread_struct structure. In the body. When an interrupt or exception occurs in a kernel-mode task, the kernel saves all register information for the kernel-mode task to the kernel stack.
  • main register information including: instruction registers, stack registers, general-purpose registers, return address registers, and parameter registers
  • the debugger that supports the two-state debugging accesses the register of the kernel-mode debug task, it first determines whether the kernel state is interrupted or abnormal by the debug task. If the kernel state is interrupted or abnormal by the debug task, the debugger is from the kernel stack. Access to the register information of the debugged task; if the debug task is scheduled, you can use the ptrace system call to execute the PTRACE PEEKUSER or PTRACE POKEUSER operation to implement register access to the kernel-mode debug task.
  • the debugger supporting the two-state debug For register access of the user mode being debugged, the debugger supporting the two-state debug first determines the address space in which the user mode is stopped by the debug task. If the user mode is stopped in the user address space by the debugging task, the kernel will save some main register information to the thread_struct structure.
  • the debugger that supports the two-state debugging can execute the PTRACE PEEKUSER or PTRACE_POKEUSER operation through the ptrace system.
  • the kernel will save all the register information of the debug task to On the kernel stack, the debugger that supports two-state debugging can access the register information of the user-mode debug task from the kernel stack.
  • the debugger that supports the two-state debugging accesses the register flow of the debugged task, as shown in FIG. 7, and includes the following steps: Step 701: Start the current process;
  • Step 702 Obtain information about the debugged task.
  • Step 703 determine whether it is a kernel state is debugged, if yes, go to step 704, otherwise, go to step 709;
  • Step 704 determining whether the task to be debugged is interrupted or abnormal, if yes, go to step 707; otherwise, go to step 705;
  • Step 705 calling a ptrace system call
  • Step 706 after performing a PTRACE PEEKUSER or PTRACE POKEUSER operation, after performing a register access, performing step 714;
  • Step 707 Acquire a stack frame address.
  • Step 708 accessing the memory value of the pt_regs structure size from the corresponding position on the kernel stack, step 714 is performed; step 709, determining whether the debugged task is stopped in the user address space, and if so, executing step 710; otherwise, executing step 712;
  • Step 710 calling a ptrace system call
  • Step 711 after performing a PTRACE PEEKUSER or PTRACE POKEUSER operation, after performing a register access, performing step 714;
  • Step 712 Obtain a stack frame address.
  • Step 713 accessing the memory value of the pt_regs structure size from the corresponding position on the kernel stack, and executing step 714; Step 714, ending the current process.
  • the debugger supporting the two-state debugging calls the sys_ptrace() function interface, and performs the PTRACE PEEKUSR or PTRACE_POKEUSR operation to implement register access to the debugged task.
  • Register accesses are mainly divided into register accesses for kernel-mode debug tasks and register access for user-mode debug tasks. Each type can be divided into two types: access from the stack and access from the register structure. What needs to be modified is the getreg( ) and putreg( ) function interfaces in the linux/arch/i386/kernel/ptrace.c file.
  • the key pseudo-codes are as follows:
  • Retval get_reg_from_stack(child, regno); /* Get the letter from the stack
  • Kernel state is being debugged */ if(!IS_INTER UPTED(child)) ⁇ /* scheduling */
  • Retval get_usr_reg(child, regno); /*Get the register letter from the register structure
  • Retval get_reg_from_stack(child, regno); /* Get the letter from the stack
  • Kernel state is being debugged */ if(!IS_INTER UPTED(child)) ⁇ /* scheduling */
  • the breakpoint setting module 340 obtains the memory address set by the breakpoint. If the breakpoint is a user address space breakpoint, directly modify the user address space memory, and replace the memory instruction with a breakpoint instruction; The breakpoint is a kernel address space breakpoint. When the debugged task is scheduled, the kernel address space memory is modified, and the memory instruction is replaced with a breakpoint instruction; and when the debugged task is dispatched by the kernel to the CPU, the kernel address space is The breakpoint instruction is restored to the original memory instruction.
  • the debugger usually sets breakpoints by replacing instructions in memory with breakpoint instructions.
  • a breakpoint exception is stopped and the debugger is up.
  • the debugger can view the information of the debugged task. After the debug task resumes running, the debugger restores the original command back.
  • breakpoint settings of debuggers that support two-state debugging are mainly divided into two types, one is the breakpoint setting of the user address space, and the other is the breakpoint setting of the kernel address space.
  • breakpoints in the user's address space are not encountered by other tasks.
  • the kernel address space of the debugged task is shared with other tasks. If a breakpoint is set in the kernel address space, it may be encountered by other tasks, resulting in an illegal breakpoint exception. Therefore, when setting a breakpoint for a debugger that supports two-state debugging, if the breakpoint is a breakpoint in the user's address space, you can directly modify the memory of the user's address space and replace the memory instruction with a breakpoint instruction.
  • the breakpoint is a breakpoint in the kernel address space
  • the memory in the kernel address space is modified only when the debugged task is dispatched into the CPU by the kernel, and the memory instruction is replaced with a breakpoint instruction; when the debugged task is dispatched by the kernel to the CPU , restores the breakpoint instruction in the kernel address space to the original instruction.
  • the breakpoint setting process of the debugger that supports two-state debugging includes the following steps:
  • Step 801 starting the current process
  • Step 802 Obtain a memory address set by a breakpoint.
  • Step 803 determining whether it is a user address space breakpoint, and if so, executing step 804; otherwise, performing step 805;
  • Step 804 directly modify the user address space memory, replace the memory instruction with a breakpoint instruction, and perform step 807;
  • Step 805 determine whether the debugged task is scheduled, and if yes, execute step 806; otherwise, execute step 807;
  • Step 806 modify Kernel address space memory, replace the memory instruction with a breakpoint instruction, go to step 807; Step 807, end the current flow.
  • the exception handling module 350 is configured to: when an queried task is scheduled, if an exception event occurs, the exception handling function is invoked based on the exception type, the exception handling is performed, the current exception event is raised, and the current abnormal event is a valid event.
  • the control module 310 is triggered to stop the running of the debugged task.
  • Debuggers that support two-state debugging involve exception handling mainly divided into breakpoint exception handling and single-step exception handling.
  • a user-mode task when a user-mode task encounters a breakpoint instruction, it stops the breakpoint exception handling and sends a SIGTRAP signal to the debugger.
  • a kernel mode task When a kernel mode task encounters a breakpoint instruction, it also enters the breakpoint exception handler to perform related processing operations.
  • the ptrace system call has also provided the ability to perform single-step operations on the task being debugged.
  • Ptrace(PTRACE_SINGLESTEP, 7) causes the kernel to block each instruction of the debugged task before it is executed, then sends a signal to the debugger and gives control to the debugger.
  • the debugger that supports two-state debugging is a kernel-level debugger, processing of signals is not supported. And whether the user mode is debugged or the kernel mode is debugged, when the debug task runs to encounter a breakpoint instruction or a single-step operation, it will enter the kernel's breakpoint exception handler or single-step exception handler. Therefore, the processing of the interrupted point operation of the debugged task can be realized by modifying the kernel's breakpoint exception handling function.
  • the debugger that supports the two-state debug needs to perform the operations of reporting the breakpoint hit event and stopping the debug task, in addition to performing the related operations of the exception handler.
  • the flow is shown in Figures 9 and 10.
  • the debugger breakpoint exception handling process for supporting two-state debugging includes:
  • Step 901 starting the current process
  • Step 902 the task being debugged is interrupted; Step 903, entering a breakpoint exception processing function of the kernel;
  • Step 904 breakpoint hit related processing
  • Step 905 Determine whether it is a valid breakpoint. If yes, go to step 906. Otherwise, go to step 910; Step 906, go to the breakpoint hit event;
  • Step 907 Delete a breakpoint in the kernel address space.
  • Step 908 setting a stop flag of the task to be debugged
  • Step 909 Delete the debugged task from the task running queue.
  • Step 910 ending the current process.
  • the breakpoint setting of the debugger supporting the two-state debugging is actually modifying the instruction in the memory into a breakpoint instruction, and the operation flow belongs to the memory access category, and the modification method can support the two-state debugging.
  • the debugger's code calls the relevant interface of the memory access to set the breakpoint instruction.
  • the user mode is debugged or the kernel mode is debugged, when a breakpoint instruction is encountered, it will enter the kernel's breakpoint exception handler.
  • the debugger that supports two-state debugging needs to perform the operations of reporting the breakpoint hit event and stopping the running of the debugged task in addition to the related operations of the breakpoint exception handling.
  • What needs to be modified is the do_trap() function interface in the linux/arch/i386/kemel/traps.c file.
  • the key pseudo code is as follows:
  • Static void kprobes do_trap(int trapnr, int signr, char *str, int vm86,
  • TF MASK; /*Set the single step flag */
  • the debugger single-step exception handling process for supporting two-state debugging includes:
  • Step 1001 Start a current process
  • Step 1002 Calling the ptrace system call to set a single step flag of the debugged task
  • Step 1003 Enter a single-step exception handling function of the kernel
  • Step 1004 single step abnormal correlation processing; In step 1005, it is determined whether it is a valid single step. If yes, step 1006 is performed; otherwise, step 1009 is performed; step 1006, step 4; single step abnormal event;
  • Step 1007 Set a stop flag of the task to be debugged
  • Step 1008 the debug task is deleted from the task run queue, and step 1009 is performed;
  • Step 1009 ending the current process.
  • the debugger that supports two-state debugging can call the sys_ptraceO function interface and perform the PTRACE_SINGLESTEP operation to implement the single-step operation of the debugged task.
  • the following aspects of the kernel need to be modified.
  • the debugger that supports the two-state debug needs to perform the operations of reporting the single-step exception event and stopping the running of the debug task, in addition to performing the related operations of the single-step exception processing.
  • the do_debug() function interface in the linux/arch/i386/kemel/traps.c file.
  • the key pseudo-codes are as follows:
  • Kertsk inner— suspend— task(current); /* Stop running the debug task*/ return; /*Return from single step exception*/ Else if (current->kertask_special flags & DBG_STEP_OVER) ⁇ /*cross breakpoint operation*/
  • the signal processing module 360 is configured to: when the user mode is debugged from the kernel address space to the user address space, if the signal queue of the user state being debugged is not empty, the signal processing function is called, and the signal queue is to be processed one by one.
  • the signal, the upper 4 ⁇ signal processing event, and the signal value corresponding to the signal is determined as the signal message of interest, triggering the task operation control module 310 to stop the operation of the corresponding debug task; if it is determined that the signal message is not concerned, Do the processing to get the next signal.
  • the debugger that supports two-state debugging is a kernel-level debugger, although there is a parent-child relationship relationship with the user-mode debugged task, the signal reported by the user-mode debug task is not processed. Therefore, the debugger that supports two-state debugging must correct the signal processing function in the kernel in order to obtain the state in which the user state is processed by the debug task signal.
  • the debugger supporting the two-state debugging first obtains the signal value to be processed by the user state to be debugged, and then searches for the relevant settings in the pre-configured signal list according to the signal value, and determines the user state to be debugged by the task.
  • the processing flow specifically includes stopping the running of the debugged task, or the current signal is a signal that is not concerned, and is not processed.
  • the debugger signal processing flow that supports two-state debugging includes the following steps:
  • Step 1101 starting the current process
  • Step 1102 The user mode is switched from the kernel address space to the user address space by the debugging task
  • Step 1103 determining whether there is an unprocessed signal, and if yes, performing step 1104; otherwise, performing step 1107;
  • Step 1104 Acquire a signal value to be processed.
  • Step 1105 the upper 4 ⁇ signal processing event
  • Step 1106 Determine, according to the signal list setting, a processing procedure of the user state being debugged
  • Step 1107 ending the current process.
  • the debugger supporting the two-state debugging first obtains the signal value to be processed by the user state being debugged, and then determines the processing flow of the user state by the debug task according to the relevant settings in the signal list. What needs to be modified is the get_signal_to_deliver( ) function interface in the linux/kemel/signa file.
  • the key pseudo code is as follows:
  • the debugging method and the debugger provided by the invention overcome the problems that the existing debuggers cannot simultaneously support the debugging function of the user address space and the kernel address space, and can achieve the user address space and the kernel address of the debugged program.
  • the operation of the space is for tracking and debugging purposes.

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调试器就属于内核级调试器。 而目前已有的内核级调试器只针对内核任务进行调 试, 不能对用户态任务进行调试, 更不能从用户地址空间跟踪调试进内核地址空间。
在目前已有的各种调试器中,还没有实现能够同时对用户地址空间和内核地址空间 进行调试的功能。 发明内容
有鉴于此, 本发明提供一种调试器及其调试方法, 用以解决现有技术中的调试器不 能同时对用户地址空间和内核地址空间进行跟踪调试的问题。
为解决上述技术问题, 本发明的技术方案是这样实现的:
一种调试方法, 包括: 调试器在调试关系建立后, 运行被调试任务, 所述被调试任 务运行在内核态或用户态; 调试器判断是否停止所述被调试任务, 若是, 在所述被调试 任务中设置停止标志位, 停止所述被调试任务的运行后进行任务访问; 所述任务访问类 型包括访问所述被调试任务的内存信息和 /或寄存器信息;其中,所述调制器对于因中断 或异常停止的被调试任务, 从内核堆栈上访问寄存器信息。
所述调试器判断所述被调试任务是否停止的判断条件包括: 所述调试器接收到上层 发送的停止指令; 或者, 所述调试器在调试所述被调试任务时发生异常事件; 或者, 所 述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关心的信 号消息。
所述调试器调试所述被调试任务时发生异常事件的处理过程包括: 所述调试器调用 相应的异常处理函数进行异常处理, 并在检测出当前异常事件为有效异常事件时, 上报 当前异常事件, 并停止所述被调试任务的运行。
所述异常事件包括断点异常事件, 所述断点异常事件中断点的设置方式包括: 所述 调试器获取断点设置的内存地址, 若为用户地址空间断点, 直接将内存指令替换为断点 指令; 若为内核地址空间断点, 待所述被调试任务被调度时, 将内存指令替换为断点指 令,并在所述被调试任务完成调度时,将内核地址空间中的断点指令恢复成原内存指令。
所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时,捕获到关 心的信号消息包括: 检测是否存在未处理的信号消息, 若是, 获取待处理信号消息的信 号值, 上报信号处理事件, 并基于获取的所述信号值得到所关心的信号消息时, 停止所 述被调试任务。
一种调试器, 包括:
调试开启模块, 用于建立调试关系, 运行被调试任务, 所述被调试任务运行在内核 态或用户态;
任务运行控制模块, 用于在判断出需要停止所述被调试任务时, 在所述被调试任务 中设置停止标志位, 停止所述被调试任务的运行;
任务访问模块, 用于在所述任务运行控制模块停止运行所述被调试任务时, 进行任 务访问,所述任务访问类型包括访问所述被调试任务的内存信息和 /或寄存器信息;其中, 所述任务访问模块对于因中断或异常停止的被调试任务, 从内核堆栈上获取寄存器信 息。 所述任务运行控制模块判断所述被调试任务是否停止的判断条件包括: 所述调试器 接收到上层发送的停止指令;或者,所述调试器在调试所述被调试任务时发生异常事件; 或者, 所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间时, 捕获到 关心的信号消息。
所述调试器还包括: 异常处理模块, 用于调用相应的异常处理函数进行异常处理, 并在检测出当前异常事件为有效异常事件时, 上报当前异常事件, 并触发所述任务运行 控制模块, 停止所述被调试任务的运行。
所述调试器还包括: 断点设置模块, 用于获取断点设置的内存地址, 若为用户地址 空间断点, 直接将内存指令替换为断点指令; 若为内核地址空间断点, 待所述被调试任 务被调度时, 将内存指令替换为断点指令, 并在所述被调试任务完成调度时, 将内核地 址空间中的断点指令恢复成原内存指令。
所述调试器还包括: 信号处理模块, 用于在用户态被调试任务从内核地址空间切换 到用户地址空间时, 检测是否存在未处理的信号消息, 若是, 获取待处理信号消息的信 号值, 上报信号处理事件, 并基于获取的所述信号值得到所关心的信号消息时, 触发所 述任务运行控制模块, 停止所述被调试任务。
与现有技术相比, 本发明有益效果如下:
本发明提供的调试方法和调试器,克服了现有的各种调试器不能同时支持对用户地 址空间和内核地址空间进行调试功能的问题, 达到了能够对被调试任务在用户地址空间 和内核地址空间的运行进行跟踪和调试的目的。 附图说明
为了更清楚地说明本发明实施例或现有技术中的技术方案, 下面将对实施例或现有 技术描述中所需要使用的附图作一筒单地介绍, 显而易见地, 下面描述中的附图仅仅是 本发明的一些实施例,对于本领域普通技术人员来讲,在不付出创造性劳动性的前提下, 还可以根据这些附图获得其他的附图。
图 1为本发明提供的一种调试方法流程示意图;
图 2为本发明提供的一种调试器的结构示意图;
图 3为本发明实施例提供的一种调试器的结构图;
图 4为本发明中调试器停止被调试任务运行流程图;
图 5为本发明中调试器恢复被调试任务运行流程图;
图 6为本发明中调试器访问被调试任务内存流程图;
图 7为本发明中调试器访问被调试任务寄存器流程图;
图 8为本发明中调试器断点设置流程图;
图 9为本发明中调试器断点异常处理流程图;
图 10为本发明中调试器单步异常处理流程图; 图 11为本发明中调试器信号处理流程图。 具体实施方式
下面将结合本发明实施例中的附图, 对本发明实施例中的技术方案进行清楚、 完整 地描述, 显然, 所描述的实施例仅仅是本发明一部分实施例, 而不是全部的实施例。 基 于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有 其他实施例, 都属于本发明保护的范围。
为了解决现有技术中存在的各种调试器不能够同时支持对用户地址空间和内核地 址空间进行跟踪调试的问题, 本发明提供一种调试器及其调试方法。 该调试器实现了对 被调试程序在用户地址空间和内核地址空间的运行进行跟踪和调试的目的。该支持双态 调试的调试器不仅支持对用户态任务的调试, 同时也支持对内核态任务的调试; 所述支 持双态调试的调试器是一种内核级调试器。
如图 1所示, 为本发明提供的一种调试方法流程图, 该方法具体包括:
步骤 101、 调试器在调试关系建立后, 运行被调试任务, 所述被调试任务运行在内 核态或用户态。
步骤 102、 调试器判断是否停止所述被调试任务, 若是, 在所述被调试任务中设置 停止标志位, 停止所述被调试任务的运行。
该步骤中, 所述调试器判断所述被调试任务是否停止的判断条件包括:
所述调试器接收到上层发送的停止指令; 或者, 所述调试器在调试所述被调试任务 时发生异常事件; 或者, 所述调试器在用户态被调试任务从内核地址空间切换到用户地 址空间时, 捕获到关心的信号消息。
其中, 所述调试器调试所述被调试任务时发生异常事件的处理过程包括: 所述调试器调用相应的异常处理函数进行异常处理, 并在检测出当前异常事件为有 效异常事件时, 上 ·ί艮当前异常事件, 并停止所述被调试任务的运行; 所述异常事件至少 包括断点异常事件和单步异常事件。
其中, 所述断点异常事件中断点的设置方式包括:
所述调试器获取断点设置的内存地址, 若为用户地址空间断点, 直接将内存指令替 换为断点指令; 若为内核地址空间断点, 待所述被调试任务被调度时, 将内存指令替换 为断点指令, 并在所述被调试任务完成调度时, 将内核地址空间中的断点指令恢复成原 内存指令。
进一步的, 所述调试器在用户态被调试任务从内核地址空间切换到用户地址空间 时, 检测是否存在未处理的信号消息, 若是, 获取待处理信号消息的信号值, 上报信号 处理事件, 并基于获取的所述信号值得到所关心的信号消息时, 停止所述被调试任务。
其中, 所述调试器根据获取的信号值, 查找预先配置的信号列表, 根据信号列表中 记录的信息, 判断该信号值所对应的信号消息是否为所关心的信号消息。 其中, 信号列 表是用户根据具体需求所配置的。
步骤 103、 调试器在所述被调试任务停止运行后进行任务访问, 所述任务访问类型 包括访问所述被调试任务的内存信息和 /或寄存器信息;其中,所述调制器对于因中断或 异常停止的被调试任务, 从内核堆栈上访问寄存器信息。
进一步的, 调试器在进行任务访问后, 恢复被调试任务的运行; 其中, 恢复方式为 将所述被调试任务中设置的停止标志位删除。
如图 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文件中的 trace_detach( )函数接口 , 其关键伪代码如下所示:
static inline void _ trace_detach(struct task—struct * child, unsigned int data) { _ptrace_unlink(child); /*取消被调试关系 */
kertsk inner resume tsk (child); /*†灰复被调试任务运行 */
任务运行控制模块 310, 控制被调试任务的运行, 是调试器实现各种调试功能的基 础, 用于在判断出需要停止被调试任务时, 在相应的被调试任务中设置停止标志位, 使 得对应被调试任务被停止调用。
任务运行控制模块 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 {
#defme KERTSK SUSPEND 0x100 /*定义停止标志掩码值 */
int kertask— special— flags; /*标志位成员变量 */
( 2 )定义停止被调试任务运行接口
在 linux/kemel/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/kemel/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) { rese lect— 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_KER EL_SPACE(child)) { /*停止在用户地址空间 retval = get_usr_reg(child, regno); /*从寄存器结构体上获取寄存器信
else { /*停止在内核地址空间 */
retval = get_reg_from_stack(child, regno); /*从堆栈上获取哥存器信
/*内核态被调试任务 */ if(!IS_INTER UPTED(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_KER EL_SPACE(child)) { /*停止在用户地址空间 put_usr_reg(child, regno, value); /*从寄存器结构体上修改寄存器信
Figure imgf000015_0001
else { /*停止在内核地址空间 */
put_reg_to_stack(child, regno, value); /*从堆栈上修改寄存器信息 */
/*内核态被调试任务 */ if(!IS_INTER UPTED(child)) { /*发生调度 */
put_usr_reg(child, regno, value); /*从寄存器结构体上修改寄存器信
/*发生中断或者异常 */
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、 上 4艮断点命中事件;
步骤 907、 删除内核地址空间中的断点;
步骤 908、 设置被调试任务的停止标志位;
步骤 909、 将被调试任务从任务运行队列中删除;
步骤 910、 结束当前流程。
根据图 9所述的流程, 支持双态调试的调试器的断点设置实际上是将内存中的指令 修改为断点指令, 其操作流程属于内存访问范畴, 修改方法可以是在支持双态调试的调 试器的代码中调用内存访问的相关接口进行断点指令的设置。
不论是用户态被调试任务还是内核态被调试任务, 当遇到断点指令时, 都会进入到 内核的断点异常处理函数。 在内核的断点异常处理函数中, 支持双态调试的调试器除了 执行断点异常处理的相关操作外,还需要执行上报断点命中事件和停止被调试任务运行 的操作。 需要修改的是 linux/arch/i386/kemel/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、 上 4艮单步异常事件;
步骤 1007、 设置被调试任务的停止标志位;
步骤 1008、 将被调试任务从任务运行队列中删除, 执行步骤 1009;
步骤 1009、 结束当前流程。
根据图 10的流程,对于单步异常处理,支持双态调试的调试器可以调用 sys_ptraceO 函数接口, 执行 PTRACE— SINGLESTEP操作, 实现被调试任务的单步操作。 为了实现 这一功能, 需要对内核实现以下几方面的修改。
( 1 )设置单步标志
由于支持双态调试的调试器采用设置停止标志位的方式来控制被调试任务的运行, 因此, 在设置被调试任务的单步标志后, 还需要取消停止标志位, 恢复被调试任务的运 行。 需要修改的是 linux/arch/i386/kemel/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/kemel/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, 用于在用户态被调试任务从内核地址空间切换到用户地址空间 时, 若用户态被调试任务的信号队列不为空, 则调用信号处理函数, 逐一获取信号队列 中待处理信号,上 4艮信号处理事件,并根据信号对应的信号值判定为关心的信号消息时, 触发任务运行控制模块 310, 停止相应被调试任务的运行; 若判定为不关心的信号消息 时, 不做处理, 获取下一个信号。
在类 UNIX操作系统中, 当用户态被调试任务从内核地址空间切换到用户地址空间 时, 需要判断用户态被调试任务的信号队列是否为空。 如果存在未处理的信号, 需要对 信号队列中的信号进行提取并进行相应的处理, 同时上报给父进程。
由于支持双态调试的调试器是一种内核级调试器, 虽然同用户态被调试任务存在父 子进程关系, 但对用户态被调试任务上报的信号不会进行处理。 因此, 支持双态调试的 调试器要想获取用户态被调试任务信号处理的状态, 就必须对内核中信号处理函数进行 相应的爹改。
当用户态被调试任务从内核地址空间切换到用户地址空间时,如果存在未处理的信 号, 就会进入内核的信号处理函数。 在该函数中, 支持双态调试的调试器首先获取用户 态被调试任务待处理的信号值, 再根据该信号值在预先配置的信号列表中查找相关设 置, 决定用户态被调试任务对该信号的处理流程, 该处理流程具体包括停止被调试任务 的运行, 或者当前信号为不关心的信号, 不做处理。
支持双态调试的调试器信号处理流程, 如图 11所示, 包括以下步骤:
步骤 1101、 开始当前流程;
步骤 1102、 用户态被调试任务从内核地址空间切换到用户地址空间;
步骤 1103、 判断是否存在未处理的信号, 若是, 执行步骤 1104; 否则, 执行步骤 1107;
步骤 1104、 获取待处理信号值;
步骤 1105、 上 4艮信号处理事件;
步骤 1106、 根据信号列表设置决定用户态被调试任务处理流程;
步骤 1107、 结束当前流程。
根据图 11 所述的流程, 当用户态被调试任务从内核地址空间切换到用户地址空间 时, 如果存在未处理的信号, 就会进入内核的信号处理函数。 在该函数中, 支持双态调 试的调试器首先获取用户态被调试任务待处理的信号值, 再根据信号列表中的相关设 置, 决定用户态被调试任务对该信号的处理流程。 需要修改的是 linux/kemel/signa 文 件中的 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 == HA DL SIG STOP) { /*信号处理需要停止被调试任务 */
kertsk_inner_suspend_task(current); /*停止被调试任务运行 */ else if (ret == HA DLE SIG ACT) { /*执行信号处理函数 */
do sig action(signr); /*根据信号值, 执行信号处理函数 */
本发明提供的调试方法和调试器,克服了现有的各种调试器不能同时支持对用户地 址空间和内核地址空间进行调试功能的问题, 达到了能够对被调试程序在用户地址空间 和内核地址空间的运行进行跟踪和调试的目的。
显然,本领域的技术人员可以对本发明进行各种改动和变型而不脱离本发明的精神 和范围。 这样, 倘若本发明的这些修改和变型属于本发明权利要求及其等同技术的范围 之内, 则本发明也意图包含这些改动和变型在内。

Claims

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

Applications Claiming Priority (2)

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

Publications (1)

Publication Number Publication Date
WO2012016438A1 true WO2012016438A1 (zh) 2012-02-09

Family

ID=45545403

Family Applications (1)

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

Country Status (2)

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

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN106970877A (zh) * 2017-03-15 2017-07-21 杭州中天微系统有限公司 控制调试请求的装置及数据处理器
US11507413B2 (en) 2017-06-27 2022-11-22 Alibaba Group Holding Limited Tracking method, apparatus, device, and machine-readable medium

Families Citing this family (23)

* 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 网易(杭州)网络有限公司 程序运行性能分析方法及装置
CN109792825B (zh) * 2016-09-29 2022-04-19 昕诺飞控股有限公司 电池供电照明控制组件、照明系统和调试照明系统的方法
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 (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN1779652A (zh) * 2004-11-24 2006-05-31 中兴通讯股份有限公司 一种调试操作系统内核态程序的方法及装置
US20100174946A1 (en) * 2009-01-02 2010-07-08 International Business Machines Corporation Method for Debugging a Hang Condition in a Process Without Affecting the Process State

Family Cites Families (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN101685420B (zh) * 2008-09-24 2013-06-12 中兴通讯股份有限公司 多线程调试方法和装置
CN101504626B (zh) * 2009-03-06 2012-06-06 中兴通讯股份有限公司 一种调试控制实现方法及系统

Patent Citations (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN1779652A (zh) * 2004-11-24 2006-05-31 中兴通讯股份有限公司 一种调试操作系统内核态程序的方法及装置
US20100174946A1 (en) * 2009-01-02 2010-07-08 International Business Machines Corporation Method for Debugging a Hang Condition in a Process Without Affecting the Process State

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN106970877A (zh) * 2017-03-15 2017-07-21 杭州中天微系统有限公司 控制调试请求的装置及数据处理器
US11507413B2 (en) 2017-06-27 2022-11-22 Alibaba Group Holding Limited Tracking method, apparatus, device, and machine-readable medium

Also Published As

Publication number Publication date
CN102346708A (zh) 2012-02-08
CN102346708B (zh) 2014-07-16

Similar Documents

Publication Publication Date Title
WO2012016438A1 (zh) 一种调试器及其调试方法
US6948094B2 (en) Method of correcting a machine check error
US10761966B2 (en) Generating program analysis data for analysing the operation of a computer program
JP3965142B2 (ja) コンピュータ・プログラムをデバックするための方法、システムおよびソフトウェア・プロダクト
US9268666B2 (en) System and method for debugging of computer programs
US8370841B2 (en) Optimizing deterministic event record and replay operations
US8090989B2 (en) System and method for bi-directional debugging of computer
US7992042B2 (en) Debug support device, and program for directing computer to perform debugging method
US7191445B2 (en) Method using embedded real-time analysis components with corresponding real-time operating system software objects
JP5905904B2 (ja) デバッグ例外生成の制御
US20070079177A1 (en) Process monitoring and diagnosis apparatus, systems, and methods
KR20070109432A (ko) 커널 인지 디버깅 장치 및 방법
US7765526B2 (en) Management of watchpoints in debuggers
JP5905911B2 (ja) シングルステップ実行を用いる診断コード
US7793160B1 (en) Systems and methods for tracing errors
WO2013155822A1 (zh) 一种实现经过性数据断点的方法、装置及系统
EP2600252B1 (en) System and method for debugging of computer programs
JP2006039763A (ja) ゲストosデバッグ支援方法及び仮想計算機マネージャ
Maeng et al. Rt-replayer: a record-replay architecture for embedded real-time software debugging
Carnà et al. Strategies and software support for the management of hardware performance counters
JP2000181748A (ja) マルチメモリ空間プログラムのデバッグシステムおよびそのデバッグ方法
Mistry et al. Imitate: Recording multi-threaded programs for trace analysis and deterministic replay
Kriegel Bounding error detection latencies for replicated execution
Yoon et al. Software Black Box: OS-based Full System Replay: OS-based Full System Replay
CN117707969A (zh) 一种基于ARMv8的操作系统调测系统

Legal Events

Date Code Title Description
121 Ep: the epo has been informed by wipo that ep was designated in this application

Ref document number: 11814022

Country of ref document: EP

Kind code of ref document: A1

NENP Non-entry into the national phase

Ref country code: DE

122 Ep: pct application non-entry in european phase

Ref document number: 11814022

Country of ref document: EP

Kind code of ref document: A1