gdb常用命令

Endless_daydream Lv4

基本调试

命令行运行

1
gdb ./xx.out

启动对可执行文件xx.out的调试

命令 功能 命令完整形式
h [cmd] 查看相应gdb命令的帮助信息,可以使用简写。 help
r 进入调试后,程序不会直接开始运行,使用run指令开始运行指定的程序 run
q 退出调试。 quit
k 杀死正在运行的程序,但不退出调试。可以用r重新启动程序。 kill

源码

命令 功能 命令完整形式
l 打印几行源码,反复执行会继续向下打印。 list

断点

命令 功能 命令完整形式
b 打断点,跟数字表示行号,跟名字表示函数名。 breakpoint
i b 显示已经打的断点。每个断点有一个编号。 info breakpoint
cl 清除断点,跟数字表示行号,跟名字表示函数名。不加参数表示清除所有。 clear
d 清除断点,一个参数指定断点号,两个参数为断点号范围,不加参数表示清除所有。 delete
en / dis 启用/暂时禁用断点,指定方式同d,不清除断点。 enable / disable

如果不打断点,启动后程序会不停运行直到结束。

运行

命令 功能 命令完整形式
n 单步执行一行代码,如果是函数调用不会进入 next
s 单步执行一行代码,会进入函数内部 step
c 继续运行直到下一次中断,或程序结束 continue
fin 继续运行直到当前函数结束 finish
u 运行到当前循环结束 until
bt 查看当前堆栈,多用于查看异常处 breaktrace

汇编

命令 功能 命令完整形式
disas 打印汇编代码,对应list指令 disassemble
ni 单步执行一行汇编(instruction),如果这一行是函数调用不会进入。对应n nexti
si 单步执行一行汇编(instruction),会进入函数调用。对应s stepi

查看

速览表:

命令 功能 命令完整形式
p i 查看源码中的变量 print i
p &i 查看变量地址 print &i
disp i 类似p,但不是一次性的,每次暂停时都会打印 display i
i r rax / p $rax 查看寄存器 info registers rax / print $rax
x/2xh $rsi 查看内存 x/2xh $rsi

print命令有丰富的用法,具体见help print

x命令格式控制

1
x/nfu addr

nfu为格式控制,可选省略。

n为数字,表示查看的内存单元个数,默认为1。一个内存单元长度由u指定。f为输出格式控制符。

命令x和/中间可以没有空格。

f:

字符 进制
x 16
o 8
b 2
d (default) 10 有符号
u 10 无符号
s 字符串,碰到\0停下
c 字符格式

u:

字符 字节
b 单字节
h 双字
w 四字
g 八字

例:

1
x/4xw $rbp

以16进制显示4个4字节数,起始地址为%rbp(栈底寄存器)。注意显示的不是寄存器的内容,而是用寄存器的值寻址的内存里的结果。

注:

  • 不指定内存地址addr,会从上次显示结束的地方开始。
  • 不指定格式会沿用上一次指定的格式,gdb打开时默认格式是/1xw,即16进制显示1个4字节。

修改

在程序执行中临时修改变量/寄存器的值,改变结果/控制流。

set var VAR = EXP

命令 功能 命令完整形式
set var i = 5 设置变量 set variable VAR = EXP
p i = 5 设置变量同时回显 print i = 5
set var $rax=3 设置寄存器

通用魔法:

  • 修改eax寄存器,改变返回值
  • 修改pc / rip寄存器,改变控制流

多窗口

命令 功能 命令完整形式
la sr 显示源代码窗口。分屏成两个窗口 layout src
la a 显示汇编窗口。分屏成两个窗口 layout asm
la r 显示寄存器窗口。如果已经显示了源码或汇编,会分出第三个窗口而不是覆盖 layout regs
la sp 显示源代码和汇编窗口 layout split
Ctrl-x a 退出所有窗口,回到单独的命令行
ref / Ctrl-L 刷新屏幕,当窗口显示乱掉的时候用 refresh

焦点

命令 功能 命令完整形式
fs n / p 聚焦到下一个/上一个窗口 focus next/prev
Ctrl-x o 聚焦到下一个窗口
fs [window name] 聚焦到指定名字的窗口 focus
upd 定位到源码中正在运行的位置,用于翻页后回来 update

合法的窗口名字有a(sm),r(egs),status(即命令行),src

注:

  • 当焦点不在命令行窗口时,可以通过方向键来浏览所在窗口的内容,page up和page down翻页。

  • 键盘输入仍然输入到命令行。此时如果要翻阅历史命令,用快捷键Ctrl-p和Ctrl-n替代上下键。

进阶

命令 功能 命令完整形式
apr [cmd] 模糊查找命令 apropos
cd 类似shell的cd,改变工作目录 cd
pw 类似shell,打印当前工作目录 pwd
set args xxx 指定运行时向程序传入的参数 set args xxx
show args 查看设置的参数 show=info set

无源码调试

只有-g生成的可执行文件。

命令 功能 命令完整形式
i locals 查看函数局部变量名
pt VAR 查看变量名所属类型的定义 ptype VAR
wha EXP 查看表达式类型,相比ptype的输出更简单 whatis EXP

停止点

命令 功能 命令完整形式
wa VAR 一旦VAR的值有变化就暂停 watch VAR

条件中断

watchpoint

catchpoint

栈帧

多线程

gdbinit

gdb启动时会运行~/.gdbinit文件,在这里可以用gdb命令写一些个人习惯的调试配置,类似这样:

1
2
3
4
5
6
7
set args input.txt # 设置输入参数

# 修改/自定义命令
define n
next
refresh
end

如果在某个可执行文件的工作目录处建.gdbinit,gdb不会直接运行它,而是出于安全考虑弹出类似的警告:

warning: File “xxx/.gdbinit” auto-loading has been declined by your `auto-load safe-path’ set to “$debugdir:$datadir/auto-load”.
To enable execution of this file add
add-auto-load-safe-path xxx/.gdbinit
line to your configuration file “/.config/gdb/gdbinit”.
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file “
/.config/gdb/gdbinit”.
For more information about this security protection see the
“Auto-loading safe path” section in the GDB manual. E.g., run from the shell:
info “(gdb)Auto-loading safe path”

可以在~/.config/gdb/gdbinit文件(如果没有就新建一个)中将shell工作目录. 加入信任的目录来解决。

1
add-auto-load-safe-path ./

hook

参考资料:

gdb cheatsheet

  • Title: gdb常用命令
  • Author: Endless_daydream
  • Created at : 2024-03-22 10:28:15
  • Updated at : 2024-04-06 23:58:07
  • Link: https://endless_daydream.gitee.io/2024/03/22/cpp/gdb/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments