一、编译生成可调试的执行程序
- example: test.c
下面展示一些内联代码片
。
// An highlighted block
#include <stdlib.h>
#include <stdio.h>
int main() {
int i;
int array[7] = {1, 2, 3, 4, 5, 6, 7};
printf("Hi April ! \n");
for(i=0; i<sizeof(array); i++) {
printf("%d ", array[i]);
}
printf("\n");
printf("Bye April \n");
return 0;
}
- 执行 gcc test.c -o test -g / gcc test.c -og test
- 执行 ll 看到除了生成执行文件 test 外,还生成了调试文件 g
总用量 56
drwxrwxr-x 3 gaochzh gaochzh 4096 12月 8 15:30 ./
drwxrwxrwx 10 gaochzh gaochzh 4096 12月 8 14:38 ../
-rwxrwxr-x 1 gaochzh gaochzh 16784 12月 8 15:07 g*
-rwxrwxr-x 1 gaochzh gaochzh 19344 12月 8 14:55 test*
-rw-rw-r-- 1 gaochzh gaochzh 214 12月 8 15:34 test.c
drwxrwxr-x 2 gaochzh gaochzh 4096 12月 8 15:30 .vscode/
二、进入调试模式
gdb -tui test -quiet
- -tui : 可以在运行的同时显示代码,也可以不带此参数,进入 gdb 后,输入 focus / layout (未生效)
- -quiet / -q / -silent : 取消启动 GDB 调试器时打印的介绍信息和版权信息
三、基本的操作指令
3.1、显示代码
- list / l :
- 显示test.c中的main函数附近的代码:
(gdb)list test.c:main (gdb)l test.c:main
- 显示main函数附近的代码:
(gdb)list main (gdb)l main
- 显示test.c中的第3到10行的代码:
(gdb)list test.c:3,10 (gdb)l test.c:3,10
- 显示第3到10行的代码:
(gdb)list 3, 10 (gdb)l list 3, 10
- ps: 如已使用了参数: -tui 或者执行了: focus 上述操作仍有效。
- 显示test.c中的main函数附近的代码:
3.2、设置断点
-
以行号设置断点
(gdb)break 7 (gdb)b 7
-
以函数名设置断点
(gdb)break function_name (gdb)b function_name
-
以条件表达式设置断点
(gdb)break 7 if i==99 (gdb)b 7 if i==99
-
以表达式设置断点的方法
(gdb)watch i==99 这个命令必须在变量 i 被定义之后才会成功运行。可以在变量 i 被定义的后一行设置中断,然后使用 run 命令运行程序,程序暂停后就可以使用 watch i==99 设置断点了。
-
查看当前设置的断点信息
(gdb)info breakpoints
-
使中断失效(断点仍然存在)或有效
(gdb)info breakpoints (gdb)disable b_id //使中断失效,b_id 为中断编号 (gdb)info breakpoints (gdb)enable b_id //使中断有效,b_id 为中断编号 (gdb)info breakpoints
-
删除断点
clear : 删除程序中所有的断点 clear 行号 : 删除这行的断点 clear 函数名 : 删除该函数的断点 delete b_id1 b_id2 ... : 删除指定编号的断点
3.3、运行程序
- 单步执行
(gdb)next (gdb)n
- 执行被调试的程序,其会自动在第一个断点处暂停执行
(gdb) run (gdb) r
- 继续执行被调试的程序。当程序在某一断点处停止运行后,使用该指令可以继续执行,直至遇到下一个断点或者程序结束
(gdb) continue (gdb) c
3.4、查看和设置变量值
-
print
- 命令格式
(gdb)print ××× (gdb)p ××
- 操作符
- @ 是一个和数组有关的操作符
(gdb)print array@len array 为数组的其实地址,len 为需要打印的长度(可以缺省),如 (gdb)print array[1]@2 // 打印数组 array 第二,第三的元素 (gdb)print array // 打印数组 array 所有元素
- :: 指定一个在文件或是一个函数中的变量
(gdb)print file::variable // 打印文件 file 中的全局变量 variable (gdb)print function::variable // 打印函数 function 中的局部变量 variable ps: 如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量。 ps: 如果程序编译时开启了优化选项,在用GDB调试被优化过的程序时,可能会发生某些变量不能访问,或是取值错误码的情况,需要在编译程序时关闭编译优化。可以使用“-gstabs” 选项来解决这个问题。
- 格式输出
- /x 以十六进制的形式打印出整数
- /d 以有符号、十进制的形式打印出整数
- /u 以无符号、十进制的形式打印出整数
- /o 以八进制的形式打印出整数
- /t 以二进制的形式打印出整数
- /c 以字符形式打印变量或表达式的值
- /f 以浮点数的形式打印变量或表达式的值
(gdb)print/x i // 以十六进制的形式打印变量 i
- 命令格式
-
whatis 命令:显示某个变量或表达式值的数据类型
(gdb)whatis i // type = int 需要在变量 i 初始化后裁可以查看
-
display 命令:
-
与print 命令一样,display 命令也用于调试阶段查看某个变量或表达式的值,区别是:使用 display 命令查看变量或表达式的值,每当程序暂停执行(如单步执行)时,GDB 调试器都会自动帮我们打印出来,而 print 命令则不会。也就是说,使用 1 次 print 命令只能查看 1 次某个变量或表达式的值,而同样使用 1 次 display 命令,每次程序暂停执行时都会自动打印出目标变量或表达式的值。因此,当我们想频繁查看某个变量或表达式的值从而观察它的变化情况时,使用 display 命令可以一劳永逸。
-
命令格式
(gdb) display expr (gdb) display/fmt expr ps: display 命令和 /fmt 之间不要留有空格。以 /x 为例,应写为 (gdb)display/x expr。
expr 表示要查看的目标变量或表达式;参数 fmt 用于指定输出变量或表达式的格式:
- /x 以十六进制的形式打印出整数
- /d 以有符号、十进制的形式打印出整数
- /u 以无符号、十进制的形式打印出整数
- /o 以八进制的形式打印出整数
- /t 以二进制的形式打印出整数
- /f 以浮点数的形式打印变量或表达式的值
- /c 以字符形式打印变量或表达式的值
-
对于使用 display 命令查看的目标变量或表达式,都会被记录在一张列表(称为自动显示列表)中。通过执行info dispaly命令,可以打印出这张表:
(gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: y /t result 1: y num
- Num 列为各变量或表达式的编号,GDB 调试器为每个变量或表达式都分配有唯一的编号;
- Enb 列表示当前各个变量(表达式)是处于激活状态还是禁用状态,如果处于激活状态(用 y 表示),则每次程序停止执行,该变量的值都会被打印出来;反之,如果处于禁用状态(用 n 表示),则该变量(表达式)的值不会被打印。
- Expression 列:表示查看的变量或表达式。
-
删除
(gdb) undisplay num... (gdb) delete display num... ps: 参数 num... 表示目标变量或表达式的编号,编号的个数可以是多个。 如: (gdb) undisplay 1 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: y /t result
-
禁用和激活
(gdb) disable display num... (gdb) enable display num... ps: 参数 num... 表示要激活的变量或表达式的编号,编号的个数可以是多个,表示一次性激活多个变量或表达式。如: (gdb) disable display 2 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: n /t result (gdb) enable display 2 (gdb) info display Auto-display expressions now in effect: Num Enb Expression 2: y /t result
-