GDB基本操作

GDB的命令操作十分强大,下面将介绍一些常用命令。使用-tui选项可以将代码显示在一个漂亮的交互式窗口中;通过命令layout split可以同时显示源代码窗口和汇编指令窗口;命令layout reg则显示寄存器窗口。

? break - b

break:不带参数时,在所选栈帧中执行的下一条指令处下断点;

break <function>:在函数体入口处下断点;

break <line>:在当前源码文件指定行的开始处下断点;

break -N break +N:在当前源码行前面或后面的N行开始处下断点,N为正整数;

break <file:line>:在源码文件file的line行处下断点;

break <file:function>:在源码文件file的 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的子命令(可省略)。

? enable

enable [breakpoints] [list…]:启用指定的断点(或所有定义的断点);

enable [breakpoints] once list…:临时启用断点。这些断点在停止程序后会被禁用;

enable [breakpoints] delete list…:指定的断点启用一次,然后删除。一旦程序停止,GDB就会删除这些断点,等效于用tbreak命令设置的临时断点。

? clear

clear:清除指定行或函数处的断点。参数可以是行号,函数名称或*address。不带参数时,清除所选栈帧在源码中的所有断点;

clear <function>, clear <file:function>:清除file的function入口处设置的任何断点;

clear <line>, clear <file:line>:清除file的line代码中设置的任何断点;

clear <address>:清除程序指令地址处的断点。

? delete - d

delete [breakpoints] [list…]:删除断点,不带参数时删除所有断点。

? watch

watch [-l|-location] <expr>:对expr设置观察点。每当表达式的值改变时,程序就会停止;另外,rwatch命令用于在访问时停止,awatch命令用于在访问和改变时都停止。

? step - s

step [N]:单步步进,参数N表示执行N次(或直到程序停止)。另外,reverse-step [N]用于反向步进。

? next - n

next [N]:单步步过。与step不同,当调用子程序时,此命令不会进入子程序,而是将其视为单个源代码行执行。everse-next [N]用于反向步过。

? return

return <expr>:取消函数调用的执行。将expr作为函数返回值并使函数直接返回。

? finish - fin

finish:执行程序直到指定的栈帧返回。

? until - u

until <location>:执行程序直到大于当前栈帧或当前栈帧中的指定位置的源码行。此命令常用于快速通过一个循环,以避免单步执行。

? continue - c

continue [N]:在信号或断点之后,继续运行被调试程序。如果从断点开始,可以使用数字N作为参数,这意味着将该断点的忽略计数设置为N-1(以便断点在第N次到达之前不会中断)。

? print - p

print [expr]:求表达式expr的值并打印。可访问的变量是所选栈帧,以及范围为全局或整个文件的所有变量;

print /f [expr]:通过指定/f来选择不同的打印格式,其中f是一个指定格式的字母。

? x

x/nfu <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表示八字节。

? disassemble - disas

disas <func> 反汇编指定函数;

disas /r <addr> 反汇编某地址所在函数,/r显示机器码;

disas <begin_addr> <end_addr> 反汇编从开始地址到结束地址的部分。

? display

display/fmt <expr> | <addr>:每次程序停止时打印表达式expr或者内存地址addr的值。fmt用于指定显示格式。相对应的,undisplay用于取消打印。

? help - h

help <class>:获取该类中各个命令的列表;

help <command>:获取某命令的帮助信息。

? attach

attach <pid>:attach到GDB以外的进程或文件。将进程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,所以每次看到的栈地址都不变。

? set follow-fork-mode

当程序复刻一个子进程的时候,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/。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容