linux技巧--调试工具GDB

1.简介

在编译程序生成可执行文件之后,就进入了程序的调试环节。在程序中可能会有很多错 误需要进行调试。Linux 系统中包含了 GNU 调试程序 GDB(GNU DeBugger),它是一个用 来调试 C 和 C++ 程序的调试器。GDB 的高级特性会使得搜索错误更加高效。可以使程序 开发者在程序运行时观察程序的内部结构和内存的使用情况。使用 GDB 的优点还在于 GDB 支持嵌入式软件的交叉编译开发模式。当运行 GDB 的 Linux 平台通过串行端口连接到目标 板时,GDB 可以对运行在目标板上的应用程序进行调试

2.功能

  1. 启动程序,设置所有能影响程序运行的参数和环境。
  2. 能够让程序在指定断点处停止。
  3. 能够在程序停止时检查所有参数的情况。
  4. 能够根据指定条件改变程序的运行。
  5. 动态监视程序中的变量的值。
  6. 可以单步执行代码,观察程序的运行状态.

3.相关指令

需要注意的是,GDB 调试的是可执行文件,而不是源程序。如果想让 GDB 调试编译后 生成可执行文件,则在使用 GDB 工具调试程序之前必须使用带有-g 或-GDB 编译选项的 GCC 命令来编译源程序。下面是 GDB 的一些基本命令。

  • file:装入想要调试的可执行文件。
  • kill :终止正在调试的程序。
  • list :列出产生执行文件的源代码的一部分。
  • next :执行一行源代码,但不进入函数内部。
  • step :执行一行源代码,而且进入函数内部。
  • run :执行当前被调试的程序。
  • quit :终止。
  • gdbwatch:监视一个变量的值,而不管它何时被改变。
  • break :在代码里设置断点, 这将使程序执行到这里时被挂起。
  • make:不退出 GDB 就可以重新产生可执行文件。
  • Shell :不离开 GDB 就执行 UNIX Shell 命令。

GDB 可以运行在许多模式下,这些模式是 GDB 运行时在命令行作为选项指定的。下面 是对这些模式的详细介绍。

  • -nx 或-n:不执行任何初始化文件中的命令。一般情况下,在这个文件中的命令会将 所有的命令行参数传给 GDB 后执行。
  • -quiet 或-q:安静模式。不输出介绍和版本信息。
  • -batch:批处理模式。当批处理命令文件中的所有命令都被执行后,GDB 将返回状态 0。如果执行过程出错,将返回非 0。
  • -cd DIRECTORY:把 DIRECTORY 作为 GDB 的工作目录,这时工作目录不再是当 前目录。
  • -b BIT/S:为远程调试设置串口波特率。
  • tty 设备名:使用其他设备作为程序的标准输入输出。

4.GDB使用实例

4.1.创建一个代码

vim test.c

4.2.添加代码到test.c中

#include <stdio.h>
#define S  10

int main() {
    int a[S], i, max, min;
    printf("Enter 10 integers:\n");
    for (i = 0; i < S; i++) {
        if (scanf("%d", &a[i]) != 1) {
            printf("Invalid input. Please enter an integer.\n");
            while (getchar() != '\n'); // 清除输入缓冲区直到遇到换行符
            return 1;
        }
    }
    max = min = a[0];
    for (i = 1; i < S; i++) {
        if (max < a[i]) max = a[i];
        if (min > a[i]) min = a[i];
    }
    printf("Maximum value is %d\n", max);
    printf("Minimum value is %d\n", min);
    return 0;
}

4.3.编译

gcc -g test.c  -o test

4.4.程序调试

4.4.1.进入 GDB

终端输入gdb

gdb

可以看出,在 GDB 的启动画面中指出了 GDB 的版本号和使用的库文件等信息。接着 就进入由“(gdb) ”开头的命令行界面。

4.4.2.加载程序

使用file命令是用来加载一个可执行文件或者一个核心转储文件以便进行调试

file test

4.4.3.查看文件

在 GDB 中键入‘l’(list )就可以查看所载入的文件

在一般情况下,源代码中的行号与用户书写程序中的行号是一致的,但有时由于用户的某 些编译选项会导致行号不一致的情况,因此,要查看在 GDB 中的行号。

4.4.4.设置断点

设置断点可以使程序到一定位置暂停它的运行。程序员在该位置处可以方便地查看变量 的值和堆栈情况等,从而找出代码的问题所在。在 GDB 中设置断点非常简单,只需要在 “b”后加入对应的行号即可(这是最常用的方式,另外还有其他设置断点的方式)

需要注意的是,在 GDB 中利用行号设置断点是指代码在运行到对应行之前暂停。

4.4.5.查看断点处的情况

在设置完断点之后,用户可以键入“info b”来查看设置断点的情况。在 GDB 中可以 设置多个断点

4.4.6.运行代码

接下来就可以运行代码了。GDB 默认从首行开始运行代码,键入“r” (run)即可,在 “r”后面加上行号即可从程序中指定行开始运行

4.4.7.单步调试

输入“step”命令,程序运行一步

4.4.8.查看变量值。

在程序停止运行之后,程序员需要查看断点处的相关变量值。在 GDB 中只需键入“p+ 变量值”即可

GDB 在显示变量值时都会在对应值之前加上“$N”标记,它是当前变量值的引用标记, 所以若想再次引用此变量,就可以直接写作“$N”,而无需写冗长的变量名。

4.4.9.观察变量

 在某一循环处,程序员往往希望能够观察一个变量的变化情况,这时就可以键入命令 watch 来观察变量的变化情况

在此处必须键入完整的命令“watch”,因为在 GDB 中有不少以‘w’开头的命令,如 “where”和“while”等。

4.4.10.退出 GDB

退出 GDB 只需使用指令“q” (quit )即可

4.5.GDB的帮助

在 GDB 输入“help”命令,显示的帮助信息

在“help”命令后面加上一个命令名称,可以显示这个命令的帮助信息。例如,输入 “help list”

4.6.设置/删除断点

GDB 中丰富的断点设置和删除命令,可以满足用户各个方面的需求。表 5-6 列出了 GDB 中常见的断点设置及删除命令

命 令 格 式作 用
Info b查看所设的断点
break+设置断点的行号或函数名用于在程序中的对应行设置断点
tbreak+行号或函数名设置临时断点,到达后被自动删除
break+filename+行号用于在指定文件的对应行设置断点
break+if+条件在条件成立时停止
clear+要清除断点的行号用于清除对应行的断点
delete+断点号删除指定断点,其断点号为“info b”中的第一栏。若缺省断点号,则删除所有断点
disable+断点号让所设断点暂时停止。如果要让多个编号处的断点停止,可将编号之间用空格隔开
awatch+表达式(变量)为表达式(变量)设置一个观察点,当表达式值有变化时停止程序
rwatch+表达式(变量)设置一个观察点,当表达式(变量)被程序读时,程序被暂停
watch+表达式(变量)同 awatch
enable+断点号激活被 disable 停止的断点
condition+断点号<条件表达式>修改对应断点的条件
ignore+断点号<n>

在程序执行中忽略对应断点 n 次

step单步恢复程序运行,且进入函数调用
next单步恢复程序运行,但不进入函数调用
finish运行程序,直到当前函数完成返回
c继续执行函数,直到函数结束或遇到新的断点

如果程序是多线程的话,可以定义断点是否在所有的线程上,或是在某个特定的线程上。 当程序被 GDB 停住时,所有的运行线程都会被停住。这样可方便用户查看运行程序的总 体情况。而在恢复程序运行时,所有的线程也会被恢复运行。

4.7.各种相关命令

4.7.1.数据相关命令

GDB 中有丰富的数据相关命令,可以使用户以各种形式显示所要查看的数据。GDB 中运行数据相关命令见表

命 令 格 式作 用
display+表达式用于显示表达式的值。使用该命令后,每当程序运行到断点处都会显示表达式的值
info display查看 display 设置的自动显示的信息
delete+display 编号用于删除一个要显示值的表达式
disable+display 编号使一个要显示的表达式暂时无效
enable+display 编号恢复要显示的表达式
undisplay+display 编号用于结束某个表达式值的显示
whatis+变量显示某个变量的数据类型
print(p)+变量或表达式用来打印变量或表达式的值
set+变量=变量值用来给变量赋值
x/<n/f/u> <addr>查看内存地址中的值。n、f、u 是可选参数。 n 是一个正整数,表示显示内存的长度;f 表示显示的格式;u 表示从当前地址往后请求 的字节数,如果不指定的话,GDB 默认是 4 个 Bytes

一般地,GDB 会根据变量的类型输出变量的值。但也可以自定义 GDB 的输出的格式。 其命令格式为:print/变量名+格式,其中格式有以下几种方式。

  • x:按十六进制格式显示变量。
  • d:按十进制格式显示变量。
  • u:按十六进制格式显示无符号整型。
  • o:按八进制格式显示变量。
  • t:按二进制格式显示变量。
  • a:按十六进制格式显示变量。
  • c:按字符格式显示变量。
  • f :按浮点数格式显示变量

4.7.2.调试运行环境相关命令

在 GDB 中控制程序的运行也是非常方便的。用户可以自行设定变量值和调用函数等, 其具体命令见表

命 令 格 式作 用
set args设置运行参数
show args查看运行参数
set width+数目设置GDB的行宽
cd dir进入dir目录
run程序开始执行
return<返回值>改变程序流程,直接结束当前函数,并将指定值返回
call+函数在当前位置执行所要运行的函数

4.7.3.堆栈相关命令

GDB 中也提供了多种堆栈相关命令,可以查看堆栈的情况和寄存器的情况等,其具体命令见表

命 令 格 式作 用
backtrace 或 bt显示函数调用的所有栈框架的踪迹和当前函数的参数值
frame

打印栈帧会打印出这些信息:

栈的层编号,

当前的函数名,

函数参数值,

函数所在文件及行号,

函数执行到的语句

info reg查看寄存器状态
info stack查看堆栈信息
up在堆栈中上移
down在堆栈中下移

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

甜航一直在

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值