GDB(GNU Debugger) 是一款开源调试工具,支持多种编程语言(如 C、C++、Python 等),主要用于在程序运行时检查其状态,包括变量值、内存布局、调用堆栈等。它可以帮助开发者定位逻辑错误、内存泄漏、段错误等问题。
Linux:大多数发行版自带 GDB,可通过包管理器安装:
sudo apt update
sudo apt install gdb
Windows:可以通过 MinGW 或 Cygwin 安装 GDB。
macOS:使用 Homebrew 安装:
brew install gdb
为了使用 GDB 调试,编译时需加入 -g
选项,保留调试信息(如变量名、源代码行号等)。
gcc -g program.c -o program
启动 GDB 并加载可执行文件:
gdb ./program
进入 GDB 交互界面后,可以输入命令进行调试。
list
(或 l
):显示当前代码。list main
:显示 main
函数附近的代码。list 10
:显示第 10 行附近的代码。break main
:在 main
函数入口设置断点。break 20
:在第 20 行设置断点。break filename.c:line
:在指定文件的指定行设置断点。run
(或 r
):启动程序,遇到断点会暂停。next
(或 n
):执行下一行代码,不进入函数内部。step
(或 s
):执行下一行代码,进入函数内部。finish
:执行完当前函数并暂停。print x
(或 p x
):打印变量 x
的值。print /x x
:以十六进制打印变量 x
。display x
:每次暂停时自动显示 x
的值。set variable x = 10
:在程序运行时修改变量 x
的值为 10。backtrace
(或 bt
):显示当前调用栈,查看函数调用顺序。frame n
:切换到第 n
个栈帧(用于查看局部变量)。continue
(或 c
):继续执行程序,直到遇到下一个断点或程序结束。quit
(或 q
):退出 GDB。在特定条件下触发断点:
break 20 if x > 10
当 x > 10
时,程序会在第 20 行暂停。
监控变量值的变化:
watch x
当变量 x
的值被修改时,程序会暂停。
info threads
:查看所有线程。thread n
:切换到第 n
个线程。break foo thread 2
:在线程 2 中设置断点。当程序崩溃时,系统会生成 Core 文件(需提前设置允许生成 Core 文件):
ulimit -c unlimited
使用 GDB 分析 Core 文件:
gdb ./program core
在 GDB 中使用 bt
查看崩溃时的调用栈。
disassemble
(或 dis
):显示当前函数的汇编代码。x/8xb &x
:以十六进制查看变量 x
的内存布局。编写 .gdbinit
文件,定义调试时自动执行的命令。例如:
# .gdbinit
break main
run
swap.c
#include <stdio.h>
void swap(int *p1, int *p2) {
int *p = p1;
p1 = p2;
p2 = p;
}
int main() {
int a = 10, b = 20;
printf("Before swap: a = %d, b = %d\n", a, b);
swap(&a, &b);
printf("After swap: a = %d, b = %d\n", a, b);
return 0;
}
gcc -g swap.c -o swap
gdb ./swap
查看源代码:
(gdb) list
设置断点:
(gdb) break main
(gdb) break swap
运行程序:
(gdb) run
单步执行:
(gdb) step
查看变量值:
(gdb) print a
(gdb) print b
发现逻辑错误:
swap
函数中,变量 p1
和 p2
的值交换了,但 a
和 b
的值未改变。void
swap(int *p1, int *p2)
{
int tmp = *p1;
*p1 = *p2;
*p2 = tmp;
}
重新编译并调试:
gcc -g swap.c -o swap
gdb ./swap
bt
查看崩溃时的调用栈。watch
监控变量值变化。step
单步执行循环体。watch
监控内存分配与释放。GDB 是 Linux 环境下调试 C 程序的强大工具,掌握其基本命令和高级技巧可以显著提升调试效率。通过实践以下步骤,开发者可以快速定位并修复代码中的问题:
-g
参数。break
设置断点。run
启动程序。step
和 next
单步执行。print
和 watch
监控变量。bt
查看调用栈。通过不断实践和探索 GDB 的高级功能(如条件断点、观察点、多线程调试),可以更高效地调试复杂程序,提升代码质量和开发效率。