Linux之gdb调试器——“撕破现象看本质”
2018-02-09 09:20
253 查看
一,gdb简介
gdb可以对源文件“预处理、编译、汇编、链接”后生成的可执行文件进行调试。以以下程序(test.c)为例:#include<stdio.h> int get_sum(int n) { int sum=0,i; for(i=0;i<n;++i) sum+=i; return sum; } int main() { int i=100,result; result=get_sum(i); printf("1+2+……+%d=%d\n",i,result); return 0; }
在vim中,切换到末行模式,输入
set nu或
set number即可显示代码行号。
二,启动和退出gdb
使用gcc编译器编译test.c,需要使用-g选项以产生gdb调试所需的符号信息。[shell]$gcc -g test.c -o test//生成可执行文件
根据我们的数学知识,1+2+……+100=5500,也就是说,这个结果不是我们想要的。那到底是什么原因呢?在我们编译的时候,编译器并没有报错,也没有给出任何的警告信息,这表明我们的代码并没有语法错误,那么,我们的程序肯定出现了逻辑上的错误。
那么,现在就到了gdb大显身手的时候了!!!
我们将可执行文件test载入gdb调试器中:
[shell]$gdb test//载入test
启动gdb时,同时会出现一段版权说明,然后是gdb的提示符(gdb)。使用-q选项可以关闭版权说明。
当然,也可以直接进入gdb,再使用file命令载入文件:
使用quit命令即可退出gdb。
若程序正在调试过程中退出,则会出现提示:
输入“y”即可。
三,显示、查找源程序代码
list命令用于列出程序的源代码,(gdb)list //从行1开始,执行命令每次显示10行代码
(gdb)list 5,10 //显示行5到行10的代码
(gdb)list get_sum //列出函数get_sum周围的代码
(gdb)list test.c:5,10
//在调试多个文件时,显示某个文件某些行的代码
在调试时,仍然可以使用shell命令:
[shell]$shell ls
search和forward都可以用来从当前行向后查找第一个匹配的字符串。
reverse-search用来从当前行向前查找第一个匹配的字符。
四,执行程序和获得帮助
在载入可执行文件test后,使用run命令可以执行该程序:使用help可以查看帮助文档:
(gdb)help list//查看list的帮助信息
(gdb)help all//查看gdb所以命令的帮助信息
五,设置和管理断点
在调试程序时,我们很希望能在程序运行的过程中实时的“监视”各个变量的值。但程序执行的过程是“一步”就完成的或时间相当快,因此,我们就需要在任何我们想要的“监视”的地方设置断点。以此,程序在运行时就会停在这些断点处,我们可以”监视“各个变量、函数、表达式的值。在gdb调试器中,设置断点的命令为break:
1,以行号设置断点
(gdb)break 8
Breakpoint 1 //断点编号:断点1
0x400544 //断点所在内存地址
file test.c line 8 //表示断点所处的位置(哪个文件哪一行)
执行run命令,程序会停止在第8行,也就是我们设置的Breakpoint 1处。
2,以函数名设置断点
同样是使用break命令,我们可以在某个函数处设置断点:
(gdb)break get_sum //在函数get_sum处设置断点
执行run命令:
正如我们所料,程序停在了函数get_sum处。
3,以条件、表达式设置断点
以“条件”设置断点
(gdb)break 行号或函数名 if 条件
(gdb)break 8 if i==99
由图,程序停在了行8
sum+=i处。使用
print i用来查看此时i的值,结果显示i=99。
还有break还可以在某个表达式设置断点。
watch 条件表达式
(gdb)watch i==99
反馈信息提示我们”此时尚未定义变量i”,所以创建失败。为了解决这个问题,我们需要在i被定义后设置一个断点,当程序停留在此段点时,就可以以表达式
i==99设置断点了。
首先,我们使用
(gdb)break 6
在行6处设置一个断点,因为此时i已被定义。
之后,运行命令
(gdb)run,
程序暂停在行6。这是我们设置断点的好时候!
(gdb)watch i==99
,在表达式
i==99处成功设置了断点。
(gdb)continue
程序执行直到
i==99为止。使用
print i监视I的值,显然,i=99。
print sum监视sum的值sum的值为4851
这时,让继续运行
sum+=i,之后sum的值变为4950,再继续下去,程序执行结束。此时,程序的逻辑性错误已经很明显——100没有被加上。
相关文章推荐
- Linux下调试器 GDB和工程管理器MAKE 应用详解!
- 【Linux学习】GDB调试器基本命令必知必会(一)
- Linux gdb调试器用法全面解析
- linux 下安装gdb调试器
- 【Linux学习】GDB调试器基本命令必知必会(一)
- linux gdb调试器
- linux基础2——gdb调试器
- linux 环境下GDB调试器基本用法
- Linux教程 - Linux - GDB调试器使用手册(七)
- linux下gdb调试器使用学习-03
- gdb命令_Linux gdb 命令用法详解:功能强大的程序调试器
- linux下的c/c++调试器gdb
- linux编程器GCC及调试器GDB
- 【linux GDB】linux下GDB调试器_学习笔记_003
- 嵌入式Linux开发工具之调试器gdb
- linux下的c/c++调试器gdb
- Linux gdb符号调试器
- Linux下调试器GDB、makefile的使用
- Linux下调试器 GDB和工程管理器MAKE 应用详解!
- GNU/linux gdb调试器的使用 及 makefile编译多个目标