📅  最后修改于: 2023-12-03 15:30:53.112000             🧑  作者: Mango
GDB是一个功能强大的调试工具,可以帮助程序员识别和修复程序中的错误。在本文中,我们将介绍GDB的用法和一些常见的调试示例。
GDB可以在命令行界面中使用。启动GDB后,可以使用以下命令进行常见操作:
run
:运行程序,如果需要输入参数可以在后面添加。break
:在代码中设置断点,以便在特定位置停止。step
:逐行执行程序。next
:逐行执行程序,但不进入函数。print
:打印变量的值。continue
:继续执行程序直到下一个断点或程序结束。quit
:退出GDB。下面是一个导致程序崩溃的简单C程序:
#include <stdio.h>
#include <stdlib.h>
int main() {
char *ptr = NULL;
printf("%c", *ptr);
return 0;
}
该程序中没有对指针进行初始化,因此在尝试访问ptr
指向的内存位置时会导致崩溃。
使用GDB来查找此错误。首先,要编译程序时需要添加-g
选项来生成可调试的二进制文件:
gcc -g example.c -o example
然后,使用GDB启动程序:
gdb example
使用run
命令运行程序。当程序崩溃时,GDB会停止并显示一个错误消息。使用backtrace
命令查看堆栈跟踪:
(gdb) run
Starting program: /path/to/example
Program received signal SIGSEGV, Segmentation fault.
0x00005555555546c2 in main () at example.c:6
6 printf("%c", *ptr);
(gdb) backtrace
#0 0x00005555555546c2 in main () at example.c:6
这里显示了崩溃发生在main
函数的第6行。使用print
命令查看指针变量ptr
的值:
(gdb) print ptr
$1 = 0x0
由于ptr
的值为0x0
,因此尝试访问该地址中的内容会导致崩溃。修复这个问题,只需要在使用指针之前将其初始化即可。
这是一个无限循环的C程序:
#include <stdio.h>
int main() {
int i = 0;
while (i < 10) {
printf("i = %d\n", i);
}
return 0;
}
由于i
的值始终小于10,循环永远不会结束。使用GDB来查找这个问题。
首先,按上述方式编译并运行程序。程序将永远不会停止。使用Ctrl + C
组合键停止程序,并使用backtrace
命令查看程序停止时的堆栈:
(gdb) backtrace
#0 0x00005555555546c2 in main () at example.c:6
这里,GDB告诉我们程序停在了main
函数的第6行,也就是循环的开始。使用next
命令单步执行程序,看看何时停止:
(gdb) next
i = 0
7 printf("i = %d\n", i);
(gdb) next
i = 0
7 printf("i = %d\n", i);
(gdb) next
i = 0
7 printf("i = %d\n", i);
可以看到,程序无限循环打印相同的值。使用print
命令查看i
的值:
(gdb) print i
$1 = 0
由于i
的值没有变化,因此循环永远不会结束。将循环条件更改为i <= 10
,然后重新编译并运行程序即可解决此问题。