如果你是 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),那么你就可以使用以下命令轻松安装该工具:

sudo apt-get install gdb

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

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

gdb [可执行程序的名称]

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

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

run

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

run [参数]

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

GDB 调试器用例

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

#include

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 变量,然后将tot 之前的值与0xffffffff/out的结果值累加,赋值给 tot 变量。

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

$ ./gdb-testFloating point exception (core dumped)

因此,要调试这段代码,第一步是使用

-g

选项编译程序。命令如下:

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

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

gdb ./gdb-test

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

(gdb)&;break 11

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

现在,让 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

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

...

...

...

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 的s (或 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 调试你的程序。

本文地址:http://www.linuxprobe.com/linux-gdb-c.html

linux c代码调试工具,在 Linux 中调试 C 程序的福音——gdb相关推荐

  1. 怎么在eclipse中调试java程序?

    怎么在eclipse中调试java程序?关于这个问题我已经回答过很多次,但许多朋友可能还没有理解,本篇文章再来详细为大家解答一下怎么在eclipse中调试java程序?等相关问题,希望对大家有所帮助. ...

  2. 在VS中调试C#程序,如何查看内存、寄存器、反汇编

    在VS2005中调试C#程序时,有时你会想查看C#代码的汇编代码.内存情况.寄存器情况. 想查看反汇编代码,可在代码窗口中点右键->选择"转到反汇编"即可.在汇编代码窗口中, ...

  3. lldb 调试php,linux系统下如何在vscode中调试C++代码

    本篇博客以一个简单的hello world程序,介绍在vscode中调试C++代码的配置过程. 1. 安装编译器 vscode是一个轻量的代码编辑器,并不具备代码编译功能,代码编译需要交给编译器完成. ...

  4. linux静态代码检查工具,linux下splint检测C语言代码质量

    在linux下并没有pclint,可以使用splint代替.splint使用一.splint介绍splint是一个静态检查C语言程序安全弱点和编写错误的工具.splint会进行多种常规检查,包括未使 ...

  5. Visual studio 中调试ASP程序、Javascript 代码 - 刘稻博客

    2019独角兽企业重金招聘Python工程师标准>>> PS: 1.在调试asp时,要先附加进程(附加到:自动:与具体调试网站对应的 dllhost.exe 或 w3wp.exe . ...

  6. Linux内核代码宏定义,Linux Kernel源代码中与段有关的重要宏定义

    __init, __initdata等属性标志,是要把这种属性的代码放入目标文件的.init.text节,数据放入.init.data节──这一过程是通过编译内核时为相关目标平台提供了xxx.lds链 ...

  7. linux acpi 代码,ACPI简介 Linux

    ACPI – the Advanced Configuration & Power Interface. ACPI是OS,BIOS和硬件之间的抽象层.它允许OS和平台独立的发展,比如新的OS可 ...

  8. linux 进程代码,怎样从Linux终端管理进程:10个你必须知道的命令

    Linux终端有一系列有用的命令.它们可以显示正在运行的进程.杀死进程和改变进程的优先级.本文列举了一些经典传统的命令和一些有用新颖的命令.本文提到的命令会实现某个单一功能.它们可以结合起来--这也是 ...

  9. linux使用quercus在tomcat环境中运行php程序

    1.webapps下创建web项目edu 2.从http://quercus.caucho.com/下载quercus-4.0.39.war wget caucho.com/download/quer ...

最新文章

  1. poj 3740 Easy Finding
  2. php 类加载其它类,php 类自动载入的方法
  3. 剑指Offer(Java实现)重建二叉树
  4. 实验一 OpenGL初识
  5. Tensorflow2.0与Tensorflow1.0的理解
  6. OpenCASCADE绘制测试线束:几何命令之曲线和曲面修改
  7. NiftyNet开源平台使用
  8. 推荐第三方Oracle客户端查询工具
  9. webapp文本编辑器_Project Student:维护Webapp(可编辑)
  10. Spring3:类型安全依赖项注入
  11. 信道分配 以太网
  12. NSAssert与assert断言
  13. matlab norm函数使用_matlab中norm函数的用法(图)
  14. 一元一次方程用计算机怎么解,一元一次方程怎么解 [解一元一次方程的基本步骤]...
  15. Git过程中遇到Enter passphrase for key '/c/Users/XXX/.ssh/id_rsa':
  16. 百度西雅图开设AI实验室 总裁张亚勤称AI是时代变革之能
  17. su [user] 和 su - [user]的区别
  18. 危险的外围设备:Windows和Linux系统的计算机内部安全隐患研究
  19. 涂鸦智能 ① tuya-wifi-mcu-sdk-arduino-library 简单剖析
  20. WiFi信号覆盖面积小?如何扩大Wifi信号覆盖范围?

热门文章

  1. 移动端web页面自适应和rem
  2. SBT管理java项目
  3. Java float型数据判断是否相等
  4. Wine QQ2012 笔记
  5. Dotnet程序集自动生成版本号
  6. 381. O(1) 时间插入、删除和获取随机元素 - 允许重复
  7. python uwsgi_uwsgi的多站点配置
  8. TIOBE 7月编程语言排行:各大城市程序员的工资状况又又又涨了
  9. oracle 查询时间点数据_ORACLE中查询时间点前后一分钟的数据
  10. mysql连接自己的ip地址_mysql 连接字符串 远程连接用IP地址 而非只是localhost时