现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

gdb的工作原理

2016-07-17 22:47 工业·编程 ⁄ 共 1481字 ⁄ 字号 暂无评论

一、gdb简介

gdb:GNU debugger

UNIX及UNIX-like下一个强大的命令行的调试工具

gdb调试的整体架构如下图所示:

gdb调试的整体架构

可以发现gdb调试不管是本地调试还是远程调试,都是基于ptrace系统调用来实现的

二、ptrace

ptrace系统调用的原型:

long ptrace(enum __ptrace_request request, pid_t pid,void *addr,void *data);

ptrace系统调用提供了一种方法,让父进程可以观察和控制其它进程的执行,检查和改变其核心映像及寄存器。主要用来实现断点调试和系统调用跟踪

可通过man手册查看具体使用:man ptrace

request参数的主要选项:

PTRACE_TRACEME:由子进程调用,表示本进程将被其父进程跟踪,交付给这个进程的所有信号,即使信号是忽略处理的(除SIGKILL之外),都将使其停止,父进程将通过wait()获知这一情况。

PTRACE_ATTACH: attach到一个指定的进程,使其成为当前进程跟踪的子进程,而子进程的行为等同于它进行了一次PTRACE_TRACEME操作。但是,需要注意的是,虽然当前进程成为被跟踪进程的父进程,但是子进程使用getppid()的到的仍将是其原始父进程的pid。

这下子gdb的attach功能也就明朗了。当你在gdb中使用attach命令来跟踪一个指定进程/线程的时候,gdb就自动成为改进程的父进程,而被跟踪的进程则使用了一次PTRACE_TRACEME,gdb也就顺理成章的接管了这个进程。

PTRACE_CONT:继续运行之前停止的子进程。可同时向子进程交付指定的信号。

三、gdb三种调试方式

1)attach并调试一个已经运行的进程:

确定需要进行调试的进程id

运行gdb,输入attch pid,如:gdb 12345。gdb将对指定进行执行如下操作:ptrace(PTRACE_ATTACH,pid,0,0)

2)运行并调试一个新的进程

运行gdb,通过命令行参数或file指定目标调试程序,如gdb ./test

输入run命令,gdb执行下述操作:

通过fork()系统调用创建一个新进程

在新创建的子进程中调用ptrace(PTRACE_TRACEME,0,0,0)

在子进程中通过execv()系统调用加载用户指定的可执行文件

3)远程调试目标主机上新创建的进程

gdb运行在调试机,gdbserver运行在目标机,通过二者之间定义的数据格式进行通信

四、gdb调试的基础—信号

gdb调试的实现都是建立在信号的基础上的,在使用参数为PTRACE_TRACEME或PTRACE_ATTACH的ptrace系统调用建立调试关系后,交付给目标程序的任何信号首先都会被gdb截获。

因此gdb可以先行对信号进行相应处理,并根据信号的属性决定是否要将信号交付给目标程序。

1、设置断点:

信号是实现断点的基础,当用breakpoint 设置一个断点后,gdb会在=找到该位置对应的具体地址,然后向该地址写入断点指令INT3,即0xCC。

目标程序运行到这条指令时,就会触发SIGTRAP信号,gdb会首先捕获到这个信号。然后根据目标程序当前停止的位置在gdb维护的断点链表中查询,若存在,则可判定为命中断点。

gdb暂停目标程序运行的方法是想起发送SIGSTOP信号。

2、next单步调试:

next指令可以实现单步调试,即每次只执行一行语句。一行语句可能对应多条及其指令,当执行next指令时,gdb会计算下一条语句对应的第一条指令的地址,然后控制目标程序走到该位置停止。

给我留言

留言无头像?