如何使用gdb在Linux中调试C程序

无论您是经验丰富的编码器,您开发的任何软件都无法完全免除错误。 因此,识别错误并修复它们是软件开发周期中最重要的任务之一。 虽然有许多方法可以识别错误(测试,自我评估代码等),但还有专门的软件 - 配置调试器 - 可以帮助您准确了解问题的位置,以便您可以轻松解决问题。

如果您是C / C ++程序员或使用Fortran和Modula-2编程语言开发软件,您将很高兴知道存在一个优秀的调试器 - 被称为GDB ,可让您轻松调试代码以了解错误和其他问题。 在本文中,我们将讨论GDB的基础知识,包括它提供的一些有用的功能/选项。

但在我们向前推进之前,值得一提的是,本文中介绍的所有说明以及示例都已在Ubuntu 14.04LTS上进行了测试。 本教程中使用的示例代码用C语言编写; 我们使用的命令行shell是bash(版本4.3.11); 而我们使用的GDB版本是7.7.1。

GDB调试器基础知识

按照外行人士的说法,GDB允许您在程序执行期间窥视程序,让您可以帮助确定问题在哪里。 我们将在下一节中通过一个工作示例来讨论GDB调试器的用法,但在此之前,我们将讨论一些可帮助您的基本要点。

首先,为了成功地使用像GDB这样的调试器,你必须编译你的程序,使编译器也产生调试器所需的调试信息。 例如,在gcc编译器的情况下,我们将在本教程的后面将使用我们来编译示例C程序,您需要在编译代码时使用-g命令行选项。

要了解gcc编译器的手册页面中关于这个命令行选项的内容,请点击此处

下一步是确保您的系统上安装了GDB。 如果不是这样,而且您使用的是基于Debian的系统(如Ubuntu),则可以使用以下命令轻松安装该工具:

sudo apt-get install gdb

在任何其他发行版上安装,请到这里

现在,一旦编译好程序,就可以进行调试,GDB在系统上就可以使用以下命令在调试模式下执行程序:

gdb [prog-executable-name]

虽然这将启动GDB调试器,但您的程序可执行文件此时不会启动。 这是您可以定义调试相关设置的时间。 例如,您可以定义一个断点,告知GDB在特定行号或函数上暂停程序执行。

继续,要实际启动您的程序,您必须执行以下gdb命令:

run

这里值得一提的是,如果你的程序需要一些命令行参数来传递给它,你可以在这里指定它们。 例如:

run [arguments]

GDB提供了许多有用的命令,在调试时派上用场。 我们将在下一节的例子中讨论其中的一些。

GDB使用示例

现在我们有一个关于GDB及其用法的基本思想。 所以让我们举个例子来应用那里的知识。 以下是一个示例代码:

#include <stdio.h>

int main()
{
int out = 0, tot = 0, cnt = 0;
int val[] = {5, 54, 76, 91, 35, 27, 45, 15, 99, 0};

while(cnt < 10)
{
out = val[cnt];
tot = tot + 0xffffffff/out;
cnt++;
}

printf("\n Total = [%d]\n", tot);
return 0;
}

所以基本上,这个代码是什么,它选择'val'数组中包含的每一个值,把它分配给'out'整数,然后通过对变量的前一个值和'0xffffffff /出来“。

这里的问题是当代码运行时会产生以下错误:

$ ./gdb-test 
Floating point exception (core dumped)

所以,要调试代码,第一步是使用-g编译程序。 这是命令:

gcc -g -Wall gdb-test.c -o gdb-test

接下来,让我们运行GDB,让它知道我们要调试哪个可执行文件。 这是命令:

gdb ./gdb-test 

现在,我得到的错误是“浮点异常”,并且大多数人可能已经知道,这是由n%x,当x为0时引起的。因此,考虑到这一点,我将一个断点放在行号11,正在进行分裂。 这是通过以下方式完成的:

(gdb) break 11

请注意'(gdb)'是调试器的提示,我刚刚写了'break'命令。

现在,我请GDB开始执行程序:

run

所以,当断点被第一次击中时,这是GDB在输出中显示的:

Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb)

如上面的输出所示,调试器显示了放置断点的行。 现在,我们来打印“out”的当前值。 这可以通过以下方式进行:

(gdb) print out
$1 = 5
(gdb)

您可以看到打印了值“5”。 所以,事情现在很好。 我要求调试器继续执行程序,直到下一个断点,可以使用'c'命令完成。

c  

我一直在做这项工作,直到我看到“出”的价值为零。

...
...
...
Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb) print out
$2 = 99
(gdb) c
Continuing.

Breakpoint 1, main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;
(gdb) print out
$3 = 0
(gdb)

现在,为了确认这是确切的问题,我这次使用GDB的'(或'step')命令而不是'c'。 原因是,我只想要第11行,程序执行暂停,执行,看看是否发生崩溃。

发生了什么事

(gdb) s

Program received signal SIGFPE, Arithmetic exception.
0x080484aa in main () at gdb-test.c:11
11 tot = tot + 0xffffffff/out;

是的,如上面突出显示的输出所证实的,这是抛出异常的地方。 当我再次尝试运行's'命令时,最终确认:

(gdb) s 

Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.

所以这样,您可以使用GDB调试程序。

结论

我们刚刚在这里划伤了表面,因为GDB提供了很多功能供用户探索和使用。 通过GDB的手册页,了解更多关于该工具的信息,并在代码中调试某些东西时尝试使用它。 调试器有一点与之相关的学习曲线,但值得我们努力工作。

赞(52) 打赏
未经允许不得转载:优客志 » 系统运维
分享到:

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏