跳转到内容

GDB

GDB(GNU Debugger)是一个命令行调试工具,可用于调试使用各种编程语言编写的程序。它允许在被调试的代码中检查内存、控制代码的执行状态、检测代码特定部分的执行等。

Terminal window
gdb [选项] [可执行文件] [core文件]
参数 说明
可执行文件 需要调试的程序
core 文件 程序崩溃时生成的 core dump
命令 说明
gdb ./prog 启动时加载程序
gdb ./prog core 调试崩溃程序(core dump)
gdb -tui ./prog TUI 模式(图形化界面)

TUI 模式下程序输出可能导致界面错乱,可通过 refresh 手动刷新。

layout 命令可在终端中创建多窗口布局:

  • layout src:显示源代码窗口和命令行窗口
  • layout asm:显示汇编代码窗口和命令行窗口
  • layout split:上下分屏显示源代码和汇编代码
  • layout regs:在代码窗口下方显示寄存器窗口
命令 说明
break [LOCATION] 设置断点
info breakpoints 查看断点列表
delete <编号> 删除断点
disable <编号> 禁用断点
enable <编号> 启用断点

LOCATION 可以是函数名、行号、文件名:行号、地址等,还可附加条件表达式:

Terminal window
(gdb) break main # 在 main() 开头断点
(gdb) break *0x804000 # 在地址断点(反汇编时常用)
(gdb) break 123 # 在当前文件第 123 行断点
(gdb) break file.c:20 # 在 file.c 第 20 行断点
(gdb) break my_loop if i > 10 # 条件断点:当 i > 10 时触发

删除与启用/禁用示例:

Terminal window
(gdb) delete 1 # 删除断点 1
(gdb) delete # 删除所有断点
(gdb) delete 2-5 # 删除断点 2 到 5
(gdb) disable 2 # 禁用断点 2
(gdb) enable 2 # 启用断点 2
(gdb) enable delete 3 # 启用断点 3 并在触发后删除
命令 说明
run / r 启动程序(可带参数)
continue / c 继续运行直到下一个断点
step / s 单步进入函数(会进入被调用函数内部)
next / n 单步执行但不进入函数内部
finish 直接运行到当前函数结束(快速跳出函数)
Terminal window
(gdb) run arg1 arg2 # 带参数启动
(gdb) run # 不带参数启动
(gdb) continue
(gdb) step
(gdb) next
(gdb) finish
Terminal window
(gdb) print x # 打印变量值
(gdb) print array[10] # 打印数组元素
(gdb) print *ptr # 打印指针指向的值
(gdb) info registers # 查看所有寄存器的值
(gdb) p $eax # 查看特定寄存器

x/[n][f][u] address:检查内存

  • n:显示的单元数(可选,默认 1)
  • f:输出格式(x 十六进制、d 十进制、s 字符串、i 指令)
  • u:单元大小(b 字节、h 半字 2 字节、w 字 4 字节、g 双字 8 字节)
  • address:内存地址(变量名、指针值、表达式等)
Terminal window
(gdb) x/16xb &array # 查看数组前 16 字节(十六进制)
(gdb) x/10dw ptr # 查看 ptr 指向的 10 个 4 字节整数(十进制)
(gdb) x/s 0x8040000 # 查看地址处的字符串
(gdb) x/8i $pc # 查看当前指令附近的 8 条汇编指令

set {TYPE}<address> = <value>:直接修改内存

Terminal window
(gdb) set {int}0xffffd000 = 42 # 修改内存为整数 42
(gdb) set {char[5]}0x804000 = "ABCD" # 写入字符串
命令 说明
backtrace / bt 查看调用栈(崩溃时特别有用)
frame <编号> 切换到指定栈帧
Terminal window
(gdb) backtrace
(gdb) frame 2
Terminal window
(gdb) watch x # 当变量 x 被修改时暂停

编译带调试信息的程序并启动调试:

Terminal window
gcc -g -o prog prog.c
gdb ./prog

在 main 函数设置断点并运行:

Terminal window
(gdb) break main
(gdb) run
(gdb) next
(gdb) print x
(gdb) continue

调试崩溃程序:

Terminal window
gdb ./prog core
(gdb) backtrace
(gdb) frame 0
(gdb) print *ptr