GDB是GNU开源组织发布的一个强大的UNIX下调试程序工具。
GDB通过系统调用 ptrace 来接管一个进程的执行。ptrace 系统调用提供了一种 *** 使得父进程可以观察和控制其它进程的执行gdb命令行指定源码,检查和改变其核心映像以及寄存器。它主要用来实现断点调试和系统调用跟踪。
运行gdb运行并调试一个新进程
运行 gdbgdb命令行指定源码,通过命令行或 file 命令指定目标程序。
输入 run 命令, gdb 执行下面的操作gdb命令行指定源码:
通过 fork() 系统调用创建一个新进程在新创建的子进程中执行操作:ptrace(PTRACE_TRACEME, 0, 0, 0)在子进程中通过 execv() 系统调用加载用户指定的可执行文件attach 并调试一个已经运行的进程
用户确定需要进行调试的进程 PID
运行 gdb,输入 attach <pid>,gdb 将对指定进程执行操作:ptrace(PTRACE_ATTACH, pid, 0, 0)
远程调试目标机上新创建的进程
gdb 运行在调试机上,gdbserver 运行在目标机上,两者之间的通信数据格式由 gdb 远程串行协议(Remote Serial Protocol)定义
RSP 协议数据的基本格式为: $..........#xx
gdbserver 的启动方式相当于运行并调试一个新创建的进程
gdb 基本操作break -- b
break 当不带参数时,在所选栈帧中执行的下一条指令处设置断点。break <function> 在函数体入口处打断点。break <line> 在当前源码文件指定行的开始处打断点。break -N break +N 在当前源码行前面或后面的 N 行开始处打断点,N 为正整数。break <filename:line> 在源码文件 filename 的 line 行处打断点。break <filename:function> 在源码文件 filename 的 function 函数入口处打断点。break <address> 在程序指令的地址处打断点。break ... if <cond> 设置条件断点,... 代表上述参数之一(或无参数),cond 为条件表达式,仅在 cond 值非零时停住程序。info
info breakpoints -- i b 查看断点,观察点和捕获点的列表。info breakpoints [list…]info break [list…]list… 用来指定若干个断点的编号(可省略),可以是 2, 1-3, 2 5 等。info display 打印自动显示的表达式列表,每个表达式都带有项目编号,但不显示其值。info reg 显示当前寄存器信息。info threads 打印出所有线程的信息,包含 Thread ID、Target ID 和 Frame。info frame 打印出指定栈帧的详细信息。info proc 查看 proc 里的进程信息。disable -- dis
禁用断点,参数使用空格分隔。不带参数时禁用所有断点。
disable [breakpoints] [list…] breakpoints 是 disable 的子命令(可省略),list… 同 info breakpoints 中的描述。enable
启用断点,参数使用空格分隔。不带参数时启用所有断点。
enable [breakpoints] [list…] 启用指定的断点(或所有定义的断点)。enable [breakpoints] once list… 临时启用指定的断点。GDB 在停止您的程序后立即禁用这些断点。enable [breakpoints] delete list… 使指定的断点启用一次,然后删除。一旦您的程序停止,GDB 就会删除这些断点。等效于用 tbreak 设置的断点。breakpoints 同 disable 中的描述。
clear
在指定行或函数处清除断点。参数可以是行号,函数名称或 * 跟一个地址。
clear 当不带参数时,清除所选栈帧在执行的源码行中的所有断点。clear <function>, clear <filename:function> 删除在命名函数的入口处设置的任何断点。clear <line>, clear <filename:line> 删除在指定的文件指定的行号的代码中设置的任何断点。clear <address> 清除指定程序指令的地址处的断点。delete -- d
删除断点。参数使用空格分隔。不带参数时删除所有断点。
delete [breakpoints] [list…]tbreak
设置临时断点。参数形式同 break 一样。当第一次命中时被删除。
watch
为表达式设置观察点。每当一个表达式的值改变时,观察点就会停止执行您的程序。
watch [-l|-location] <expr> 如果给出了 -l 或者 -location,则它会对 expr 求值并观察它所指向的内存。另外 rwatch 表示在访问时停止,awatch 表示在访问和改变时都停止。
step -- s
单步执行程序,直到到达不同的源码行。
step [N] 参数 N 表示执行 N 次(或由于另一个原因直到程序停止)。reverse-step
反向步进程序,直到到达另一个源码行的开头。
reverse-step [N] 参数 N 表示执行 N 次(或由于另一个原因直到程序停止)。next -- n
单步执行程序,执行完子程序调用。
next [N]与 step 不同,如果当前的源代码行调用子程序,则此命令不会进入子程序,而是继续执行,将其视为单个源代码行。
reverse-next
反向步进程序,执行完子程序调用。
reverse-next [N]如果要执行的源代码行调用子程序,则此命令不会进入子程序,调用被视为一个指令。
return
您可以使用 return 命令取消函数调用的执行。如果你给出一个表达式参数,它的值被用作函数的返回值。
return <expression> 将 expression 的值作为函数的返回值并使函数直接返回。finish -- fin
执行直到选定的栈帧返回。
finishuntil -- u
执行程序直到大于当前栈帧或当前栈帧中的指定位置(与 break 命令相同的参数)的源码行。此命令常用于通过一个循环,以避免单步执行。
until <location> 继续运行程序,直到达到指定的位置,或者当前栈帧返回。continue -- c
在信号或断点之后,继续运行被调试的程序。
continue [N]如果从断点开始,可以使用数字 N 作为参数,这意味着将该断点的忽略计数设置为 N - 1(以便断点在第 N 次到达之前不会中断)。
print -- p
求表达式 expr 的值并打印。可访问的变量是所选栈帧的词法环境,以及范围为全局或整个文件的所有变量。
print [expr]print /f [expr] 通过指定 /f 来选择不同的打印格式,其中 f 是一个指定格式的字母x
检查内存。
x/nfu <addr>x <addr>n, f, 和 u 都是可选参数,用于指定要显示的内存以及如何格式化。addr 是要开始显示内存的地址的表达式。n 重复次数(默认值是 1),指定要显示多少个单位(由 u 指定)的内存值。f 显示格式(初始默认值是 x),显示格式是 print('x','d','u','o','t','a','c','f','s') 使用的格式之一,再加 i(机器指令)。u 单位大小,b 表示单字节,h 表示双字节,w 表示四字节,g 表示八字节。display
每次程序停止时打印表达式 expr 的值。
display <expr>display/fmt <expr>display/fmt <addr>fmt 用于指定显示格式。对于格式 i 或 s,或者包括单位大小或单位数量,将表达式 addr 添加为每次程序停止时要检查的内存地址。
disassemble -- disas
反汇编命令。
disas <func> 反汇编指定函数disas <addr> 反汇编某地址所在函数disas <begin_addr> <end_addr> 反汇编从开始地址到结束地址的部分undisplay
取消某些表达式在程序停止时自动显示。参数是表达式的编号(使用 info display 查询编号)。不带参数表示取消所有自动显示表达式。
disable display
禁用某些表达式在程序停止时自动显示。禁用的显示项目被再次启用。参数是表达式的编号(使用 info display 查询编号)。不带参数表示禁用所有自动显示表达式。
enable display
启用某些表达式在程序停止时自动显示。参数是重新显示的表达式的编号(使用 info display 查询编号)。不带参数表示启用所有自动显示表达式。
help -- h
打印命令列表。
help <class> 您可以获取该类中各个命令的列表。help <command> 显示如何使用该命令的简述。attach
挂接到 GDB 之外的进程或文件。将进程 ID 或设备文件作为参数。
attach <process-id>run -- r
启动被调试的程序。可以直接指定参数,也可以用 set args 设置(启动所需的)参数。还允许使用 >, <, 或 >> 进行输入和输出重定向。
甚至可以运行一个脚本,如:
run `python2 -c 'print "A"*100'`backtrace -- bt
打印整个栈的回溯。
bt 打印整个栈的回溯,每个栈帧一行。bt n 类似于上,但只打印最内层的 n 个栈帧。bt -n 类似于上,但只打印最外层的 n 个栈帧。bt full n 类似于 bt n,还打印局部变量的值。注意:使用 gdb 调试时,会自动关闭 ASLR,所以可能每次看到的栈地址都不变。
ptype
打印类型 TYPE 的定义。
ptype[/FLAGS] TYPE-NAME | EXPRESSION参数可以是由 typedef 定义的类型名, 或者 struct STRUCT-TAG 或者 class CLASS-NAME 或者 union UNION-TAG 或者 enum ENUM-TAG。
set follow-fork-mode
当程序 fork 出一个子进程的时候,gdb 默认会追踪父进程(set follow-fork-mode parent),但也可以使用命令 set follow-fork-mode child 让其追踪子进程。
另外,如果想要同时追踪父进程和子进程,可以使用命令 set detach-on-fork off(默认为on),这样就可以同时调试父子进程,在调试其中一个进程时,另一个进程被挂起。如果想让父子进程同时运行,可以使用 set schedule-multiple on(默认为off)。
但如果程序是使用 exec 来启动了一个新的程序,可以使用 set follow-exec-mode new(默认为same) 来新建一个 inferior 给新程序,而父进程的 inferior 仍然保留。
thread apply all bt
打印出所有线程的堆栈信息。
generate-core-file
将调试中的进程生成内核转储文件。
directory -- dir
设置查找源文件的路径。
或者使用 gdb 的 -d 参数,例如:
gdb a.out -d /search/code/相关文章
本站已关闭游客评论,请登录或者注册后再评论吧~