使用 GDB 调试 Linux程序


最近开始做Linux下编程,GDB是必须要会的。在网上找了一篇比较详细的文章。
Linux 的大部分特色源自于 shell 的 GNU 调试器,也称作 gdb。gdb 可以让您查看程序的内部结构、打印变量值、设置断点,以及单步调试源代码。它是功能极其强大的工具,适用于修复程序代码中的问题。在本文中,我将尝试说明 gdb 有多棒,多实用。

编译

开始调试之前,必须用程序中的调试信息编译要调试的程序。这样,gdb 才能够调试所使用的变量、代码行和函数。如果要进行编译,请在 gcc(或 g++)下使用额外的 -g选项来编译程序:

gcc -g eg.c -o eg
运行 gdb

在 shell 中,可以使用 gdb 命令并指定程序名作为参数来运行 gdb,例如 gdb eg;或者在 gdb 中,可以使用 file 命令来装入要调试的程序,例如 file eg。这两种方式都假设您是在包含程序的目录中执行命令。装入程序之后,可以用 gdb 命令 un 来启动程序。

调试会话示例

如果一切正常,程序将执行到结束,此时 gdb 将重新获得控制。但如果有错误将会怎么样?这种情况下,gdb 会获得控制并中断程序,从而可以让您检查所有事物的状态,如果运气好的话,可以找出原因。为了引发这种情况,我们将使用一个示例程序:

代码示例 eg1.c

#include
int wib(int no1, int no2)
{
int result, diff;
diff = no1 - no2;
result = no1 / diff;
return result;
}
int main(int argc, char *argv[])
{
int value, div, result, i, total;
value = 10;
div = 6;
total = 0;
for(i = 0; i < 10; i++)
{
result = wib(value, div);
total += result;
div++;
value--;
}
printf("%d wibed by %d equals %dn", value, div, total);
return 0;
}
这个程序将运行 10 次 for 循环,使用 wib() 函数计算出累积值,最后打印出结果。
在您喜欢的文本编辑器中输入这个程序(要保持相同的行距),保存为 eg1.c,使用 gcc -g eg1.c -o eg1 进行编译,并用 gdb eg1 启动 gdb。使用 un 运行程序可能会产生以下消息:
Program received signal SIGFPE, Arithmetic exception.
0x80483ea in wib (no1=8, no2=8) at eg1.c:7
7 result = no1 / diff;
(gdb)
gdb 指出在程序第 7 行发生一个算术异常,通常它会打印这一行以及 wib() 函数的自变量值。要查看第 7 行前后的源代码,请使用 list 命令,它通常会打印 10 行。再次输入 list(或者按回车重复上一条命令)将列出程序的下 10 行。从 gdb 消息中可以看出,第 7 行中的除法运算出了错,程序在这一行中将变量 "no1" 除以 "diff"。要查看变量的值,使用 gdb print 命令并指定变量名。输入 print no1 和 print diff,可以相应看到 "no1" 和 "diff" 的值,结果如下:
(gdb) print no1
$5 = 8
(gdb) print diff
$2 = 0
gdb 指出 "no1" 等于 8,"diff" 等于 0。根据这些值和第 7 行中的语句,我们可以推断出算术异常是由除数为 0 的除法运算造成的。清单显示了第 6 行计算的变量 "diff",我们可以打印 "diff" 表达式(使用 print no1 - no2 命令),来重新估计这个变量。gdb 告诉我们 wib 函数的这两个自变量都等于 8,于是我们要检查调用 wib() 函数的 main() 函数,以查看这是在什么时候发生的。在允许程序自然终止的同时,我们使用 continue 命令告诉 gdb 继续执行。
(gdb) continue
Continuing.
Program terminated with signal SIGFPE, Arithmetic exception.
The program no longer exists.

  • 1
  • 2
  • 下一页

相关内容