gdb是一个由GNU开源组织发布的,在UNIX/Linux操作系统下的,基于命令行的,功能强大的程序调试工具。本文主要讨论在Linux系统下gdb调试工具的基本使用。
gdb简介
gdb是由GNU开源组织发布的一个强大的在UNIX/Linux操作系统下的程序调试工具,gdb主要帮助工程师完成下面4个方面的功能:
- 启动程序,可以按照工程师自定义的要求随心所欲的运行程序
- 让被调试的程序在工程师指定的断点处停住,断点可以是条件表达式
- 当程序被停住时,可以检查此时程序中所发生的事,并追索上文
- 动态地改变程序的执行环境
启动gdb
对C/C++程序的调试,需要在编译前加上-g的选项,即1
$g++ -g test.cpp -o test
调试可执行文件,即gdb后接可执行文件:
1
$gdb test
当程序非法执行后core dump后产生的文件
1
$gdb test core
如果程序是一个服务程序,则可以指定这个服务程序运行时的进程ID,gdb会自动attach上去,并调试它。程序应当是在PATH中可以搜索的到。
1
$gdb test <PID>
gdb交互命令
启动gdb后,进入到交互模式,可以通过以下命令完成对程序的调试。
运行
- run(简记为r):其作用是运行程序,当遇到断点后,程序会自动在停止在断点处,等待用户输入下一步的命令
- continue(简记为c):其作用是继续执行,到下一个断点处或运行至程序结束
- next(简记为n):单步跟踪程序,当遇到函数调用时,并不进入到该函数体内。此命令与step的主要区别是,step遇到函数时会跟进到函数内部中进行运行,而next是直接调用函数,并不会跟进到函数体内部
- step(简记为s):单步调试,如果遇到函数调用,会跟进到函数体内部
- until:当在一个循环体内单步跟踪时,这个命令可以直接运行直到退出循环体
- until+行号 :运行至某行,不仅仅是用来跳出循环的
- finish:运行程序,直到当前函数完成返回,并打印函数返回时的堆栈地址和返回值及参数值等信息
- call 函数名(参数):调用程序中可见的函数,并传递参数进去
- quit(简记为q):退出gdb
关于断点
- break n(简记为b n):在第n行处设置断点(可以带上代码路径和代码名称)
- break [break-args] if (condition):条件断点,当满足条件时进入断点
- delete 断点号n:删除第n个断点
- disable断点号n:关闭第n个断点
- enable断点号n:开启第n个断点
- clear行号n:清除第n行的断点
- info b:显示当前程序的断点设置情况
- delete breakpoints:清除所有断点
关于源码显示
- list(简记为l):其作用就是列出程序的源代码,默认每次显示10行,连续输入会显示接下来的10行代码
- list 行号:将显示已当前文件以行号为中心的前后10行代码
- list 函数名:将显示“函数名”所在函数的源代码
打印表达式
- print 表达式(简记为p):其中表达式可以是任何当前正在被测试程序的有效表达式,比如当前正在调试程序的程序,包括数字,变量甚至是函数调用
- print a:将显示整数a的值
- print ++a:将把a中的值加1,并显示出来
- print gdb_test(1):将以整数1(也可为变量)作为参数调用gdb_test()函数
- display 表达式:在单步运行时非常有用,它将在每次单步表达式进行指令之后,紧接着输出被设置的表达式及值
- watch 表达式:设置一个监视点,一旦被监视的表达式发生变化时,gdb将强行终止正在被调试的程序
- whatis:查询变量或函数
- info function:查询函数
查询运行信息
- where/bt:当前运行的堆栈列表
- bt backtrace:显示当前调用堆栈
- up/down:改变堆栈显示的深度
- set args 参数:指定运行时的参数
- show args:查看设置好的参数
- info program:来查看程序是否在运行,以及进程号,被暂停的原因
分割窗口
- layout:用于分割窗口,可以一边查看代码,一边测试
- layout src:显示源代码窗口
- layout asm:显示反汇编窗口
- layout regs:显示源代码/反汇编和CPU寄存器窗口
- layout split:显示源代码和反汇编窗口
- Ctrl+L:刷新窗口
番外篇
gdb有一个增强工具——cgdb,主要功能就是可以在调试的同时显示代码,界面类似vim,其他使用和gdb基本相同。