gdb常用命令
基本调试
命令行运行
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 | set args input.txt # 设置输入参数 |
如果在某个可执行文件的工作目录处建.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”./.config/gdb/gdbinit”.
To completely disable this security protection add
set auto-load safe-path /
line to your configuration file “
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
参考资料:
- 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.