GDB是如何实现的,对于这个问题,在面试中也遇到过一次,我真的不懂,只能整理一下文章和资料
当我们启动gdb程序之后,会执行下面的操作:
- :通过fork()系统调用创建一个新的进程。
- :在新的子进程中在执行下述操作:ptrace(PTRACE_TRACEME,0,0,0);
- :在子进程中通过execv()系统调用加载用于执行的可执行文件
NAME
ptrace - process trace
SYNOPSIS
#include <sys/ptrace.h>
long ptrace(enum __ptrace_request request, pid_t pid,
void *addr, void *data);
DESCRIPTION
The ptrace() system call provides a means by which a parent process may observe and control the execution of another process,
and examine and change its core image and registers. It is primarily used to implement breakpoint debugging and system call
tracing.
The parent can initiate a trace by calling fork(2) and having the resulting child do a PTRACE_TRACEME, followed (typically) by
an exec(3). Alternatively, the parent may commence trace of an existing process using PTRACE_ATTACH.
While being traced, the child will stop each time a signal is delivered, even if the signal is being ignored. (The exception is
SIGKILL, which has its usual effect.) The parent will be notified at its next wait(2) and may inspect and modify the child pro-
cess while it is stopped. The parent then causes the child to continue, optionally ignoring the delivered signal (or even
delivering a different signal instead).
When the parent is finished tracing, it can terminate the child with PTRACE_KILL or cause it to continue executing in a normal,
untraced mode via PTRACE_DETACH.
The value of request determines the action to be performed
attatch动作
- gdb发给正在运行的程序一个SIGSTOP的信号,让他变成自己的子进程进行调试。
- 不可忽略或捕捉的信号—SIGSTOP和SIGKILL
Linux下SIGSTOP的特殊特征和实现 -雾琰-ChinaUnix博客blog.chinaunix.net/uid-30126070-id-5076211.html
gdb程序是父进程,被调试程序是子进程,子进程的所有信号都被父进程gdb来接管,并且父进程gdb可查看、修改子进程的内部信息,包括:堆栈、寄存器等。
SIGSTOP 进程停止 不能被忽略、处理和阻塞
断点功能:
- 断点的功能就是在指定的位置插入断点指令,使目标程序运行到该处时产生SIGTRAP信号,该信号被gdb铺获,通过断点地址的匹配确定是否名字断点。
- 断点的实现原理,就是在指定的位置插入断点指令,当被调试的程序运行到断点的时候,产生SIGTRAP信号。该信号被gdb捕获并进行断点命中判定,当gdb判断出这次SIGTRAP是断点命中之后就会转入等待用户输入进行下一步处理,否则继续。
- 断点的设置原理: 在程序中设置断点,就是先将该位置的原来的指令保存,然后向该位置写入int 3。当执行到int 3的时候,发生软中断,内核会给子进程发出SIGTRAP信号,当然这个信号会被转发给父进程。然后用保存的指令替换int3,等待恢复运行。
- 断点命中判定:gdb把所有的断点位置都存放在一个链表中,命中判定即把被调试程序当前停止的位置和链表中的断点位置进行比较,看是断点产生的信号,还是无关信号。
- 条件断点的判定:原理同3),只是恢复断点处的指令后,再多加一步条件判断。若表达式为真,则触发断点。由于需要判断一次,因此加入条件断点后,不管有没有触发到条件断点,都会影响性能。在x86平台,某些硬件支持硬件断点,在条件断点处不插入int 3,而是插入一个其他指令,当程序走到这个地址的时候,不发出int 3信号,而是先去比较一下特定寄存器和某个地址的内容,再决定是否发送int 3。因此,当你的断点的位置会被程序频繁地“路过”时,尽量使用硬件断点,会对提高性能有帮助
Ptrace 跟踪进程分析_小熊猫_新浪博客blog.sina.com.cn/s/blog_694f2ae70101amh6.html
ptrace**(PTRACE_TRACEME,** 0**,** NULL, NULL);
ptrace**(**PTRACE_PEEKUSER) // Reads a word at offset addr in the child’s USER area, which holds the registers and other information about the process
ptrace**(PTRACE_CONT,child,NULL,NULL);Restarts the stopped child process.**
最后没看明白 信号 动作关系。