gdb是Linux下一款功能强大的C/C++程序的调试工具,本节将通过实例代码简单的介绍一下gdb的各项功能。
gdb简介
在程序开发的过程中,调试是不可避免的步骤之一,Linux下的GDB(GNU Debugger)是一个用来调试C\C++程序的功能强大的调试器,它能够在程序运行的过程中观察程序员的内部结构和内存的使用情况。程序员也可以使用gdb来跟踪程序中的错误,从而减少程序员的工作量。
一般来说GDB有以下功能:
- 设置断点(断点可以是表达式),使程序在指定的代码行上暂停执行,便于观察程序的内部结构和内存的使用情况。
- 单步执行程序,便于调试
- 查看程序中变量值的变化
- 动态改变程序的执行环境
- 分析奔溃程序产生的core文件。
gdb的使用非常简单,只需要在Linux的终端输入gdb即可,系统会自动启动gdb,并打印出gdb的相关信息:
你也可以在gdb后面给出文件名,直接指定想要调试的程序,gdb程序就会自动调用这个可执行文件进行调试。命令如下:
gdb filename
告诉gdb转入名为filename的可执行文件进行调试。
另外,为了使gdb正常工作,必须使程序在编译的时候包含调试信息,这需要在gcc编译时加上-g或者-ggdb选项。调试信息包好了程序中的每个变量的类型和在可执行文件中的地址映射以及源代码的行号。而gdb正是利用这些信息是源代码和机器码相关联。
GDB常用命令
gdb支持许多的命令,使用户能实现不同的功能,有简单的文件装入命令,有允许程序员检查所调用的堆栈内容的复杂命令,为了之后的讲解,下面就简单的列举一下gdb常用的命令:
命令 | 含义描述 |
file | 装入想要调试的可执行文件 |
run | 执行当前被调试的程序 |
kill | 终止当前别调试的程序 |
step | 执行一行源代码而且进入函数内部 |
next | 执行一行源代码但是不进入函数内部 |
break | 在代码里设置断点,这将是程序执行到这里时被挂起 |
打印表达式或变量的值,或打印内存中某一个变量开始的游荡连续地址区域的值,还可以用来对变量进行赋值 | |
display | 设置自动显示的表达式或变量,当程序停住或在单步跟踪时,这些变量就会自动显示其当前值 |
list | 列出产生执行文件的源代码的一部分 |
quit | 退出gdb |
watch | 使你能监视一个变量的值而不管它何时被改变 |
backtrace | 回溯跟踪 |
frame n | 定位到发生错误的代码段,n为backtrace命令的输出结果中的行号 |
examine | 查看内存地址中的值 |
jump | 使程序跳转执行 |
signal | 产生信号量 |
return | 签字函数返回 |
call | 强制调用函数 |
make | 使用户不退出gdb就可以重新产生可执行文件 |
shell | 使用户不退出gdb执行Linux的shell命令 |
注:用户可以在gdb下输入“help”命令来查看如何使用gdb,或者事在命令提示符下输入gdb h来得到一个关于gdb命令选项说明的简单列表
通常情况下,gdb的命令都可以采用简写的形式来方便用户操作。比如run可以写为“r”,next可以简写为“n”,backtrace可以简写为bt等。
gdb调试初步
接下来我们通过调试一个具体而简单的实例向大家简单的介绍gdb的使用
使用gcc编译simple.c,并且加上-ggdb调试选项
之后可以看到发生了一个错误信息,为了更快的发现错误的所在,我们使用gdb进行一个简单的调试。
当出现提示符(gdb)的时候,表示调试器已经做好了准备可以进行调试了。现在可以通过run命令来让程序开始在gdb的监控下运行。
仔细分析一下gdb给出的输出结果,不难看出,程序是由于段错误而导致异常中止的,说明内存操作出了问题,具体发生问题的地方是在调用_IO_vfscanf——internal()的时候。为了得到更有价值的信息,可以使用gdb提供的溯源跟踪命令backtrace命令,执行结果如下:
通过以上的信息不难看出gdb已经将错误信息定位到了第六行,现在可以仔细检查一下了
使用gdb提供的frame命令可以定位到发生错误代码的代码段,该命令后面跟着的数值是在backtrace中找到的行号。
通过上面的调试我们可以确定发生错误的信息是“input”,之后我们将“input”改为“&input”即可
之后推出gdb即可
之后重新编译并运行以下simple.c
至此,一个简易的调试完成,下一次我们将更为详细的深入介绍。