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

无论多么有经验的程序员,开发的任何软件都不可能完全没有 bug。因此,排查及修复 bug 成为软件开发周期中最重要的任务之一。有许多办法可以排查 bug(测试、代码自审等等),但是还有一些专用软件(称为调试器)可以帮助准确定位问题的所在,以便进行修复。

如果你是 C/C++ 程序员,或者使用 Fortran 和 Modula-2 编程语言开发软件,那么你将会很乐意知道有这么一款优秀的调试器 - GDB - 可以帮你更轻松地调试代码 bug 以及其它问题。在这篇文章中,我们将讨论一下 GDB 调试器的基础知识,包括它提供的一些有用的功能/选项。

在我们开始之前,值得一提的是,文章中的所有说明和示例都已经在 Ubuntu 14.04 LTS 中测试过。教程中的示例代码都是 C 语言写的;使用的 shell 为 bash(4.3.11);GDB 版本为 7.7.1。

GDB 调试器基础

通俗的讲,GDB 可以让你看到程序在执行过程时的内部流程,并帮你明确问题的所在。我们将在下一节通过一个有效的示例来讨论 GDB 调试器的用法,但在此之前,我们先来探讨一些之后对你有帮助的基本要点。

首先,为了能够顺利使用类似 GDB 这样的调试器,你必须以指定的方式编译程序,让编译器产生调试器所需的调试信息。例如,在使用 gcc 编译器(我们将在本教程之后的章节用它来编译 C 程序示例)编译代码的时候,你需要使用 -g 命令行选项。

想要了解 gcc 编译器手册页中关于 -g 命令行选项相关的内容,请看这里。

下一步,确保在你的系统中已经安装 GDB 调试器。如果没有安装,而且你使用的是基于 Debian 的系统(如 Ubuntu),那么你就可以使用以下命令轻松安装该工具:


  1. sudo apt-get install gdb 

在其他发行版上的安装方法,请看这里。

现在,当你按照上述的方式编译完程序(gcc -g 命令行选项),同时也已经安装好 GDB 调试器,那么你就可以使用以下命令让程序在调试模式中运行:


  1. gdb [可执行程序的名称] 

这样做会初始化 GDB 调试器,但你的可执行程序此时还不会被启动。在这个时候你就可以定义调试相关的设置。例如,你可以在特定行或函数中设置一个断点让 GDB 在该行暂停程序的执行。

接着,为了启动你的程序,你必须输入执行以下 gdb 命令:


  1. run 

在这里,值得一提的是,如果你的程序需要一些命令行参数,那么你可以在这里指定这些参数。例如:


  1. run [参数] 

GDB 提供了很多有用的命令,在调试的时候总是能派的上用场。我们将在下一节讨论其中一部分命令。

GDB 调试器用例

现在我们对 GDB 及其用法有了基本的概念。因此,让我们举例来应用所学的知识。这是一段示例代码:


  1. #include 
  2.  
  3. int main()
  4. {
  5.  int out = 0, tot = 0, cnt = 0; 
  6. int val[] = {5, 54, 76, 91, 35, 27, 45, 15, 99, 0}; 
  7.  
  8. while(cnt < 10) 
  9. {
  10.  out = val[cnt]; 
  11. tot = tot + 0xffffffff/out; 
  12. cnt++; 
  13. }
  14.  
  15.  printf("\n Total = [%d]\n", tot); 
  16. return 0;

简单说明一下这段代码要做什么事。获取 val 数组中每一个值,将其赋值给 out 变量,然后将 tot 之前的值与 0xffffffff/out 的结果值累加,赋值给 tot 变量。

这里遇到的问题是,当执行这段代码编译后的可执行程序时,产生以下错误:


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

因此,要调试这段代码,第一步是使用 -g 选项编译程序。命令如下:


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

接着,让我们运行 GDB 调试器并指定要调试的可执行程序。命令如下:


  1. gdb ./gdb-test 

现在,我刚才得到的错误是 Floating point exception,大部分人可能已经知道,这是因为 n % x,当 x 为 0 时导致的错误。所以,考虑到这一点,我在 11 行代码除法运算的位置处添加了一个断点。如下:


  1. (gdb)&;break 11 

注意 (gdb) 是调试器的提示信息,我只输入了 break 11 命令。

现在,让 GDB 开始运行程序:


  1. run 

当断点第一次被命中时,GDB 显示如下输出:


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

正如你所看到的那样,调试器会显示断点所在的行代码。现在,让我们打印出此时 out 的值。如下:


  1. (gdb) 
  2. print out
  3. $1 = 5(gdb) 

如上所示,值 5 被打印出来了。这个时候一切都还是正常的。让调试器继续执行程序直到命中下一个断点,可以通过使用 c 命令来完成:


重复上述操作,直到 out 值变为 0 时。


  1. ...  
  2. ...  
  3. ...  
  4. Breakpoint 1, main () at gdb-test.c:11  
  5. 11 tot = tot + 0xffffffff/out;  
  6. (gdb) print out  
  7. $2 = 99  
  8. (gdb) c  
  9. Continuing. 
  10.  
  11. Breakpoint 1, main () at gdb-test.c:  
  12. 1111 tot = tot + 0xffffffff/out;  
  13. (gdb) print out  
  14. $3 = 0  
  15. (gdb) 

现在,为了进一步确认问题,我使用 GDB 的 s(或 step) 命令代替 c 命令。因为,我只想让当前程序在第 11 行之后暂停,再一步步执行,看看这个时候是否会发生崩溃。

以下是执行之后输出信息:


  1. (gdb) s 
  2.  
  3. Program received signal SIGFPE, Arithmetic exception.  
  4. 0x080484aa in main () at gdb-test.c:  
  5. 1111 tot = tot + 0xffffffff/out; 

是的,如上输出的第一行内容所示,这就是抛出异常的地方。当我再次尝试运行 s 命令时,问题最终也得到了确认:


  1. (gdb) s 
  2.  
  3. Program terminated with signal SIGFPE, Arithmetic exception.  
  4. The program no longer exists. 

通过这种方式,你就可以使用 GDB 调试你的程序。

总结

GDB 提供了很多功能供用户研究和使用,在这里,我们仅仅只介绍了很少一部分内容。通过 GDB 的手册页可以进一步了解这个工具,当你在调试代码的时候,尝试使用一下它。GDB 调试器有一定的学习难度,但是它很值得你下功夫学习。

本文作者:佚名

来源:51CTO

时间: 2024-08-04 12:34:34

在Linux中如何使用gdb调试C程序的相关文章

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

无论多么有经验的程序员,开发的任何软件都不可能完全没有 bug.因此,排查及修复 bug 成为软件开发周期中最重要的任务之一.有许多办法可以排查 bug(测试.代码自审等等),但是还有一些专用软件(称为调试器)可以帮助准确定位问题的所在,以便进行修复. 如果你是 C/C++ 程序员,或者使用 Fortran 和 Modula-2 编程语言开发软件,那么你将会很乐意知道有这么一款优秀的调试器 - GDB - 可以帮你更轻松地调试代码 bug 以及其它问题.在这篇文章中,我们将讨论一下 GDB 调试

如何使用GDB调试PHP程序_php实例

一般来说,GDB主要完成下面四个方面的功能: (1)启动你的程序,可以按照你的自定义的要求随心所欲的运行程序. (2)可让被调试的程序在你所指定的调置的断点处停住.(断点可以是条件表达式) (3)当程序被停住时,可以检查此时你的程序中所发生的事. (4)动态的改变你程序的执行环境. 1.简介 GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.如果你是在 UNIX平台下做软件,你会发现GDB这个调试工具有比VC.BCB的图形化调试器更强大的功能.同时GDB也具有例如ddd这样的图形化

用 gdb 调试 GCC 程序【转】

用 GDB 调试程序   原著:Rick McMullin 用 gdb 调试 GCC 程序 转自:http://blog.csdn.net/bonnshore/article/details/7955422     Linux 包含了一个叫 gdb 的 GNU 调试程序. gdb 是一个用来调试 C 和 C++ 程序的强力调试器. 它使你能在程序运行时观察程序的内部结构和内存的使用情况. 以下是 gdb 所提供的一些功能: 它使你能监视你程序中变量的值. 它使你能设置断点以使程序在指定的代码行上

比较全面的gdb调试命令

用GDB调试程序 GDB是一个强大的命令行调试工具.大家知道命令行的强大就是在于,其可以形成执行序列,形成脚本.UNIX下的软件全是命令行的,这给程序开发提代供了极大的便利,命令行软件的优势在于,它们可以非常容易的集成在一起,使用几个简单的已有工具的命令,就可以做出一个非常强大的功能. 于是UNIX下的软件比Windows下的软件更能有机地结合,各自发挥各自的长处,组合成更为强劲的功能.而Windows下的图形软件基本上是各自为营,互相不能调用,很不利于各种软件的相互集成.在这里并不是要和Win

《Linux C编程从入门到精通》一第2章 在Linux中编写C语言代码2.1 Linux中C语言程序开发流程和工具介绍

第2章 在Linux中编写C语言代码 Linux C编程从入门到精通 Linux作为一个操作系统,一项重要的功能就是要支持用户编程.传统的UNIX下的程序开发语言是C语言,C语言是一种平台适应性强.易于移植的语言.Linux是用C语言写成的.反过来,Linux又为C语言提供了很好的支持,C语言编译工具gcc.调试工具gdb属于最早开发出来的一批自由软件.因此Linux与C语言形成了完美的结合,为用户提供了一个强大的编程环境,本章将介绍在Linux中编写C语言程序的流程和具体方法. 2.1 Lin

《Linux C编程从入门到精通》——第 2 章 在Linux中编写C语言代码 2.1Linux中C语言程序开发流程和工具介绍

第 2 章 在Linux中编写C语言代码 Linux作为一个操作系统,一项重要的功能就是要支持用户编程.传统的UNIX下的程序开发语言是C语言,C语言是一种平台适应性强.易于移植的语言.Linux是用C语言写成的.反过来,Linux又为C语言提供了很好的支持,C语言编译工具gcc.调试工具gdb属于最早开发出来的一批自由软件.因此Linux与C语言形成了完美的结合,为用户提供了一个强大的编程环境,本章将介绍在Linux中编写C语言程序的流程和具体方法. 2.1 Linux中C语言程序开发流程和工

经典的GDB调试命令

导语 在你调试程序时,当程序被停住时,你可以使用print命令(简写命令为p),或是同义命令inspect来查看当前程序的运行数据.print命令的格式是: print print / 是表达式,是你所调试的程序的语言的表达式(GDB可以调试多种编程语言),是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x.   一.表达式 print和许多GDB的命令一样,可以接受一个表达式,GDB会根据当前的程序运行的数据来计算这个表达式,既然是表达式,那么就可以是当前程序运行中的cons

如何在Zend Studio中使用Zend Debugger调试PHP

在介绍完PHP5环境下Zend Debugger安装配置教程后,今天来说说如何在Zend Studio中使用Zend Debugger调试PHP程序,使用Zend Debugger还是比较方便,我使用的是Zend Studio7,Zend Studio7的Debug配置界面与早期的Zend Studio还是略有不同. 在使用Zend Debugger在Zend Studio中调试PHP之前,请先安装Zend Debugger,如果对Zend Studio的使用比较陌生,推荐先学习PHP开发工具Z

关于gdb调试报错问题!!!!

问题描述 关于gdb调试报错问题!!!! Program received signal SIGSEGV, Segmentation fault. 0x000000332dc81484 in strncat () from /lib64/libc.so.6 之前并没有这个错误,但是我改了几个字符串之后就报错了,求助,在线等 解决方案 非法操作,需要看具体代码才能定位 解决方案二: GDB调试死机问题gdb 调试多线程程序 问题集锦gdb调试怪问题