无论您是经验丰富的编码器,您开发的任何软件都无法完全免除错误。 因此,识别错误并修复它们是软件开发周期中最重要的任务之一。 虽然有许多方法可以识别错误(测试,自我评估代码等),但还有专门的软件 - 配置调试器 - 可以帮助您准确了解问题的位置,以便您可以轻松解决问题。
如果您是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的手册页,了解更多关于该工具的信息,并在代码中调试某些东西时尝试使用它。 调试器有一点与之相关的学习曲线,但值得我们努力工作。