在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),那么你就可以使用以下命令轻松安装该工具:
- 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-test
- Floating 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:
- 1111 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:
- 1111 tot = tot + 0xffffffff/out;
是的,如上输出的第一行内容所示,这就是抛出异常的地方。当我再次尝试运行 s 命令时,问题最终也得到了确认:
- (gdb) s
- Program terminated with signal SIGFPE, Arithmetic exception.
- The program no longer exists.
通过这种方式,你就可以使用 GDB 调试你的程序。
总结
GDB 提供了很多功能供用户研究和使用,在这里,我们仅仅只介绍了很少一部分内容。通过 GDB 的手册页可以进一步了解这个工具,当你在调试代码的时候,尝试使用一下它。GDB 调试器有一定的学习难度,但是它很值得你下功夫学习。
在Linux中如何使用gdb调试C程序相关推荐
- Linux下如何用GDB调试c++程序 [版本2]
文章转自:http://www.cnblogs.com/iyjhabc/p/3163649.html 版权归原作者. 使用gdb可以在命令行方便地调试,并且能以命令程序的方式调试源代码. 常用命令简写 ...
- [Linux 高并发服务器]GDB调试
[Linux 高并发服务器]GDB调试 [Linux 高并发服务器]GDB调试 [Linux 高并发服务器]GDB调试 GDB是什么 预先准备 基本命令 例子 进入和退出gdb 获取帮助 查看文件代码 ...
- Linux课程---11、Linux中软件安装和调试
Linux课程---11.Linux中软件安装和调试 一.总结 一句话总结: 启动过程:1.安装软件,2.修改配置文件,3.启动服务 查看过程:4.查看进程,5.查看端口 关闭过程:6.关闭软件,7. ...
- 通过vscode进行嵌入式linux arm开发板gdb调试
下载和安装vscode, 下载 vscode for windows 地址: Visual Studio Code - Code Editing. Redefined 安装 "remote ...
- 使用 GDB 调试多进程程序
使用 GDB 调试多进程程序 来源 https://www.ibm.com/developerworks/cn/linux/l-cn-gdbmp/index.html GDB 是 linux 系统上常 ...
- android程序启动之后 eclipse ndk-gdb 连接,Eclipse+CDT+GDB调试android-NDK程序(补足六个汉字).docx...
Eclipse+CDT+GDB调试android NDK程序 Eclipse+CDT+gdb调试android ndk程序 先介绍一下开发环境,在这个环境下,up主保证是没有问题的. ubuntu 1 ...
- GDB调试多线程程序
(1)gdb ./program运行程序 (2)程序挂掉 (3)info thread查看程序挂掉瞬间所有运行线程执行到的位置: 此时,可以粗略看到哪些线程执行出现了问题(线程号前面带*的表示当前线程 ...
- [Golang]搭建gdb调试go程序
搭建gdb调试go程序 前言 gdb安装 更新brew 查看是否存在gdb镜像 安装gdb go build编译 gdb执行 gdb命令 gdb调试 问题整理 参考 前言 学会使用gdb进行golan ...
- linux中启动 java -jar 后台运行程序
ps -ef | grep java 查询java 端口占用 linux中启动 java -jar 后台运行程序 直接用java -jar xxx.jar,当退出或关闭shell时,程序就会停止掉. ...
最新文章
- Centos-安装Docker并使用Docker安装mysql遇到的问题以及解决方法
- 既之前的基础,先写个简单的PHP 与数据库 的数据交流
- web service方法进行全文检索_SpringMVC(Web应用)配置教程终章项目实战
- php中调行高代码_单元格行高怎么设置
- 预防鼻炎以及空气污染对策
- pmp每日三题(2022年2月21日)
- java runtime类 heap_Java 进阶(一) JVM运行时内存模型
- 1核1g服务器php,虚拟主机1核1g什么意思
- Exp 8 Web基础
- C语言操作符详解 隐式类型转换 (整型提升 算数转换)
- 微信无法连接到服务器怎么诊断网络【微信高级教程3】
- 老饼教你深入浅出理解-《牛顿法求极值》
- 计算机毕业设计-网上购书系统【代码讲解+安装调试+文档指导】
- 1148:连续出现的字符
- 英特尔收购Barefoot背后的逻辑
- winvnc出现错误时,删除以下注册表
- 【程序员才懂的梗】全程高能 爆笑硬核 你中了几个 | 程序员的日常 搞笑瞬间
- 360全景拍摄为什么要使用鱼眼镜头,与超广角镜头区别?
- Android 6.0运行时权限管理
- 四羧基锌酞菁(ZnC4Pc),Zn-taPc 酞菁类化合物,齐岳生物供应酞菁材料
热门文章
- 一个软件,internal version 和external version, 安装有问题
- PHP中获取CHECKBOX提交的内容及checkbox全选
- 孤读Paper——《Deep Snake for Real-Time Instance Segmentation》
- office2003 office2007同时安装 配置问题的解决
- iphoneX 订单生成器 - 装 b 神器 - 生成虚拟 iphoneX 订单,满足你装 b 的愿望
- 4 构建Mysql+heartbeat+DRBD+LVS集群应用系统系列之Lvs为Mysql-slave做负载均衡
- leetcode371
- (二)开源IT资产管理系统--OCS(win)客户端代理安装
- 问题六十一:三次b样条(b-spline)曲线的控制点和曲线形状的对应——以回旋体的“基本曲线”为例
- NLP情感分析笔记(一):Baseline