调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提供了设置断点, 单步跟踪等的图形界面, 使调试起来直观易用. 但Linux用户可能要生闷气了 O:-) : 难道我们Linux程序员就只能使用原始的调试方法, 在代码中加入printf信息吗?难道Linux下就没有好的C语言调试工具吗?

当然不是了. GNU早就组织开发了一套C语言编译器(Gcc)和调试工具(Gdb). Gdb虽然没有图形化的友好界面, 但是它强大的功能也足以与微软的VC工具相媲美, 给Linux程序员带来了福音. 下面通过一个简单的例子, 演示一下Gdb的使用流程:

示例文件 demo.c 的源代码如下:

#include <stdio.h>

int sum(int, int);

    int
main()
{
    int result;
    int a = 1, b = 2;
    result = sum(a, b);
    printf("%d + %d = %d\n", a, b, result);
    return 0;
}

    int
sum(int a, int b)
{
    return a + b;
}

编译源文件, 生成可执行文件

$ gcc -g -Wall -o demo demo.c

虽然这段程序没有错误, 但调试完全正确的程序可以更加了解Gdb的使用流程. 接下来就启动Gdb进行调试.

注意:

  • Gdb进行调试的是可执行文件, 而不是”.c”源文件, 因此, 需要先通过Gcc编译生成可执行文件才能用Gdb进行调试.
  • 一定要加上选项”-g”, 这样编译出的可执行代码中才包含调试信息, 否则Gdb无法载入该可执行文件.
  • 不能使用 -O2选项对可执行文件进行优化, 因为优化之后可执行文件里的符号表信息将被删除, 这样Gdb就无法找到使可执行文件与源文件之间的关联了, 也就不能调试了.

(1) 启动Gdb

$ gdb demo
GNU gdb (GDB) 7.0-debian
Copyright (C) 2009 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/wangsheng/tmp/demo/gdb/demo...done.

可以看出, 在Gdb的启动画面中指出了Gdb的版本号, 使用的库文件等头信息, 接下来就进入了由”(gdb)”开头的命令行界面了.

(2) 查看源文件

在Gdb中键入”l”(list的缩写)可以查看所载入的文件, 如下所示:

(gdb) l
1       #include
2
3       int sum(int, int);
4
5           int
6       main()
7       {
8           int result;
9           int a = 1, b = 2;
10          result = sum(a, b);
(gdb) l
11          printf("%d + %d = %d\n", a, b, result);
12          return 0;
13      }
14
15          int
16      sum(int a, int b)
17      {
18          return a + b;
19      }
(gdb) l
Line number 20 out of range; demo.c has 19 lines.

可以看出, Gdb列出的源代码中明确地给出了对应的行号, 这样就可以大大地方便代码的定位.

(3) 设置断点

设置断点是调试程序中一个非常重要的手段, 它可以使程序到一定位置暂停运行. 因此,可以在该位置方便地查看变量的值, 堆栈情况等, 从而找出代码的症结所在.

在Gdb中设置断点非常简单, 只需在”b”后加入对应的行号即可(这是最常用的方式). 如下所示:

(gdb) b 9
Breakpoint 2 at 0x4004f4: file demo.c, line 9.

注意: 该断点的作用是当程序运行到第 9 行时暂停(第 8 行执行完毕, 第 9 行未执行)

(4) 查看断点信息

(gdb) info b
Num     Type           Disp Enb Address            What
2       breakpoint     keep y   0x00000000004004f4 in main at demo.c:9

(5) 运行代码

接下来就可运行代码了, Gdb默认从首行开始运行代码, 可键入”r”(run的缩写)即可. 若想从程序中指定的行开始运行, 可在r后面加上行号.

(gdb) r
Starting program: /home/wangsheng/tmp/demo/gdb/demo

Breakpoint 2, main () at demo.c:9
9           int a = 1, b = 2;

可以看到程序运行到断点处就停止了.

(6) 查看变量值

键入p(print的缩写)+变量名即可查看该变量在此时的值

(gdb) p a
$1 = 1
(gdb) p b
$2 = 2
(gdb) p result
$3 = 32767

注意: 这里之所以result是一个莫名其妙的值, 是因为声明result是没有初始化, 其值是不固定的。

(7) 单步执行

单步运行可以使用n(next的缩写)或者s(step的缩写), 它们之间的区别在于: 若有函数调用的时候, s会进入该函数而n不会. 因此, s就类似于VC等工具中的”step in”, n就类似于VC等工具中的”step over”.

如果使用n命令显示如下:

(gdb) n
10          result = sum(a, b);

下面使用 s 命令,跟踪进入 sum 函数:

(gdb) s
sum (a=1, b=2) at demo.c:18
18          return a + b;

可以看出执行 s 命令时进入了sum函数内部, 如果用 n 命令则跳过函数的调用部分

(8) 恢复程序运行

在查看变量值以及堆栈之后, 就可以使用命令c(continue)恢复程序的正常运行了. 这时, 它会把剩余还未执行的程序执行完, 并显示剩余程序的执行结果.

(gdb) c
Continuing.
1 + 2 = 3

Program exited normally.

可以看出, 程序在运行完后退出, 之后程序处于”停止状态”.

说明: 在Gdb中, 程序的运行状态有”运行”,”暂停”和”停止”3种. 其中”暂停”状态是程序遇到了断点或者观察点, 程序暂时停止运行, 而此时函数的地址, 函数参数, 函数内的局部变量都会被压入”栈(Stack)中. 故在这种状态下可以查看函数的变量值等各种属性. 但在函数处于”停止”状态之后, “栈”就会自动撤销, 它也就无法查看各种信息了

关于Gdb的更多命令, 你可以在启用Gdb后, 输入help命令查看.

Linux下C语言的调试 - gdb的更多相关文章

  1. Linux下C语言的调试--转

    调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提 ...

  2. Linux下C语言的调试

    调试是每个程序员都会面临的问题. 如何提高程序员的调试效率, 更好更快地定位程序中的问题从而加快程序开发的进度, 是大家共同面对的问题. 可能Windows用户顺口就会说出:用VC呗 :-) , 它提 ...

  3. [转] linux下的c/c++调试器gdb

    PS:1. 断点C++类函数,用b 命名空间::类名::方法名 2. 编译参数一定要加-g,才可断点调试 http://www.cnblogs.com/xd502djj/archive/2012/08 ...

  4. linux下的c/c++调试器gdb

    Reference:  http://www.cnblogs.com/xd502djj/archive/2012/08/30/2663960.html linux下的c/c++调试器gdb gdbLi ...

  5. linux 下C语言学习路线

    UNIX/Linux下C语言的学习路线.一.工具篇“公欲善其事,必先利其器”.编程是一门实践性很强的工作,在你以后的学习或工作中,你将常常会与以下工具打交道, 下面列出学习C语言编程常常用到的软件和工 ...

  6. Linux基础与Linux下C语言编程基础

    Linux基础 1 Linux命令 如果使用GUI,Linux和Windows没有什么区别.Linux学习应用的一个特点是通过命令行进行使用. 登录Linux后,我们就可以在#或$符后面去输入命令,有 ...

  7. LINUX下C语言编程基础

    实验二 Linux下C语言编程基础 一.实验目的 1. 熟悉Linux系统下的开发环境 2. 熟悉vi的基本操作 3. 熟悉gcc编译器的基本原理 4. 熟练使用gcc编译器的常用选项 5 .熟练使用 ...

  8. Unix和Linux下C语言学习指南

    转自:http://www.linuxdiyf.com/viewarticle.php?id=174074 Unix和Linux下C语言学习指南 引言 尽管 C 语言问世已近 30 年,但它的魅力仍未 ...

  9. Linux下C语言编程基础学习记录

    VIM的基本使用  LINUX下C语言编程 用gcc命令编译运行C语言文件 预处理阶段:将*.c文件转化为*.i预处理过的C程序. 编译阶段:将*.i文件编译为汇编代码*.s文件. 汇编阶段:将*.s ...

随机推荐

  1. Python logging 模块和使用经验

    记录下常用的一些东西,每次用总是查文档有点小麻烦. py2.7 日志应该是生产应用的重要生命线,谁都不应该掉以轻心 有益原则 级别分离 日志系统通常有下面几种级别,看情况是使用 FATAL - 导致程 ...

  2. 在做自动化测试之前你需要知道的,转自:http://www.cnblogs.com/fnng/p/3653793.html

    什么是自动化测? 做测试好几年了,真正学习和实践自动化测试一年,自我感觉这一个年中收获许多.一直想动笔写一篇文章分享自动化测试实践中的一些经验.终于决定花点时间来做这件事儿. 首先理清自动化测试的概念 ...

  3. 微信开发获取地理位置实例(java,非常详细,附工程源码)

    在本篇博客之前,博主已经写了4篇关于微信相关文章,其中三篇是本文基础: 1.微信开发之入门教程,该文章详细讲解了企业号体验号免费申请与一些必要的配置,以及如何调用微信接口. 2.微信开发之通过代理调试 ...

  4. Cocos2D与SpriteBuilder的问题在哪提问

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 我们知道Cocos2D的教程中文版的非常少,注意我没有说Coc ...

  5. Effective C++ ——实现

    条款26:尽可能延后变量定义式的出现时间 当你定义一个变量的时候就要保证这个变量能够在程序中使用到,不要定义无意义的变量,这样就要求我们最好是在变量使用到的时候才做定义,因为如果一个变量定义了却不使用 ...

  6. ERP各个模块的缩写

    财务系统模块: Oracle 总帐管理(GL) Oracle 应付帐管理(AP) Oracle 固定资产管理(FA) Oracle 应收帐管理(AR) Oracle 现金管理(CE) Oracle 项 ...

  7. python学习资料整理

    [1] The Python Tutorial [2] Numpy Quick Start Tutorial [3] Python-OpenCV [4] http://www.learnpython. ...

  8. sql中InnoDB和MyISAM的区别

    InnoDB和MyISAM是许多人在使用MySQL时最常用的两个表类型 1,MyISAM类型的表强调的是性能,其执行数度比InnoDB类型更快,但是不提供事务支持等高级处理,往往被认为只适合小项目:而 ...

  9. android自定义View-继承

    介绍anroid通过继承系统的控件自定义view 方法是通过对OnDraw()方法进行复写来实现的 举例继承TextView 在textView的背景加上矩形的效果 代码实现 testView的代码 ...

  10. HTML5中 HTML列表/块/布局 韩俊强的博客

    从简单到复杂HTML5详解:每日更新关注:http://weibo.com/hanjunqiang  新浪微博! 1.HTML列表 1.有序 2.无序 3.有序star属性 4.有序无序列表 代码: ...