GDB常用命令及调试过程
简介
GNU Debugger(GDB)是GNU项目的一部分,是一个功能强大且灵活的调试工具,广泛应用于调试C、C++、Fortran和其他编程语言的程序。GDB允许开发者检查和修改程序的运行状态,从而帮助识别和修复错误。
常用命令
启动和运行控制
启动GDB
gdb program_name
运行程序
run:运行程序,简写为r。
(gdb) run
(gdb) r
继续执行
continue:继续执行程序,简写为c。
(gdb) continue
(gdb) c
单步执行
step:单步执行一行代码,进入函数调用,简写为s。
(gdb) step
(gdb) s
next:单步执行一行代码,跳过函数调用,简写为n。
(gdb) next
(gdb) n
运行到当前函数结束
finish:运行到当前函数结束,简写为fin。
(gdb) finish
(gdb) fin
跳到下一条指令
jump:跳到指定的代码行。
(gdb) jump 42
设置断点
设置断点
break:在指定位置设置断点,简写为b。
(gdb) break main
(gdb) b main
(gdb) break file.c:10
(gdb) b file.c:10
删除断点
delete:删除断点,简写为d。
(gdb) delete 1
(gdb) d 1
禁用断点
disable:禁用断点,简写为dis。
(gdb) disable 1
(gdb) dis 1
启用断点
enable:启用断点,简写为ena。
(gdb) enable 1
(gdb) ena 1
条件断点
condition:为断点设置条件。
(gdb) condition 1 x == 5
检查和修改变量
打印变量
print:打印变量的值,简写为p。
(gdb) print x
(gdb) p x
显示变量
display:在每次停止时显示变量的值,简写为disp。
(gdb) display x
(gdb) disp x
查看局部变量
info locals:显示当前堆栈帧中的所有局部变量。
(gdb) info locals
查看全局变量
info variables:显示所有全局变量。
(gdb) info variables
设置变量
set:设置变量的值。
(gdb) set var x = 10
堆栈操作
查看调用堆栈
backtrace:显示当前调用堆栈,简写为bt。
(gdb) backtrace
(gdb) bt
切换到指定堆栈帧
frame:切换到指定堆栈帧,简写为f。
(gdb) frame 1
(gdb) f 1
返回调用者帧
up:移动到上一帧。
(gdb) up
前往被调用者帧
down:移动到下一帧。
(gdb) down
其他常用命令
查看断点信息
info breakpoints:显示所有断点信息,简写为info b。
(gdb) info breakpoints
(gdb) info b
查看线程信息
info threads:显示所有线程信息。
(gdb) info threads
切换线程
thread:切换到指定线程。
(gdb) thread 2
退出GDB
quit:退出GDB,简写为q。
(gdb) quit
(gdb) q
加载符号文件
file:加载符号文件。
(gdb) file program_name
加载核心文件
core:加载核心文件。
(gdb) core corefile
调试共享库
sharedlibrary:加载和调试共享库。
(gdb) sharedlibrary libname
远程调试
设置远程目标
target remote:连接到远程目标。
(gdb) target remote hostname:port
示例
创建一个文件 example.c,内容如下:
#include <stdio.h>
void print_array(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
}
int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
int main() {
int arr[5] = {1, 2, 3, 4, 5};
print_array(arr, 5);
int num = 5;
int result = factorial(num);
printf("Factorial of %d is %d\n", num, result);
return 0;
}
编译文件,注意加上-g:
gcc -g example.c -o example
完整的GDB调试过程:
$ gdb example
GNU gdb (GDB) 9.2
...
Reading symbols from example...
(gdb) break main
Breakpoint 1 at 0x1149: file example.c, line 15.
(gdb) break print_array
Breakpoint 2 at 0x112d: file example.c, line 5.
(gdb) run
Starting program: /path/to/example
Breakpoint 1, main () at example.c:15
15 print_array(arr, 5);
(gdb) step
print_array (arr=0x7fffffffe530, size=5) at example.c:5
5 for (int i = 0; i < size; i++) {
(gdb) next
6 printf("arr[%d] = %d\n", i, arr[i]);
(gdb) print arr
$1 = (int *) 0x7fffffffe530
(gdb) display arr
1: arr = (int *) 0x7fffffffe530
(gdb) continue
Continuing.
Breakpoint 2, print_array (arr=0x7fffffffe530, size=5) at example.c:6
6 printf("arr[%d] = %d\n", i, arr[i]);
(gdb) break factorial
Breakpoint 3 at 0x114d: file example.c, line 10.
(gdb) continue
Continuing.
arr[0] = 1
arr[1] = 2
arr[2] = 3
arr[3] = 4
arr[4] = 5
Factorial of 5 is 120
Breakpoint 3, factorial (n=5) at example.c:10
10 if (n <= 1) return 1;
(gdb) backtrace
#0 factorial (n=5) at example.c:10
#1 0x0000000000401159 in main () at example.c:19
(gdb) frame 1
#1 0x0000000000401159 in main () at example.c:19
19 int result = factorial(num);
(gdb) print n
$2 = 5
(gdb) finish
Run till exit from #0 factorial (n=5) at example.c:10
Factorial of 5 is 120
main () at example.c:21
21 return 0;
(gdb) print result
$3 = 120
(gdb) set var result = 120
(gdb) continue
Continuing.
[Inferior 1 (process 12345) exited normally]
(gdb) quit