一.概述
GBD是GNU开源组织发布的一个强大的UNIX下的程序调试工具。非图形界面方式。
一般来说,GDB主要帮忙完成一下四个方面的功能:
- 启动程序,可以按照自己定义的要求随心所欲的运行程序。
- 可以让被调试的程序在你所指定的调试的断点处停住。(断点可以是条件表达式)
- 当程序被停住时,可以检查此时你的程序中所发生的事情。
- 动态的改变你程序的执行环境。
GDB编译命令:g++ -g tst.c -o tst (注意如果要使用GDB进行调试,需要加上-g,表示把调试信息加到可执行文件中,否则看不到程序的函数名和变量名)
启动gdb:
- gdb
- gdb core;gdb同时调试一个运行程序和core文件,core是程序非法执行后core dump后产生的文件。
- gdb PID;如果程序是服务程序,那么可以指定这个服务程序运行时的进程ID。该程序应该PATH环境变量中搜索得到。
调试已经运行的程序有两种方法:
- 在Linux下用ps查看已经运行的程序的PID,然后用gdb PID 的格式把gdb挂接到正在运行的程序。
- 先用gdb 关联上源代码,执行gdb,在gdb中用attach命令来挂接进程的PID,并用detach来取消挂接的进程。
可以通过gdb --help 命令(这是没有进入gdb调试环境的)查看gdb命令的一些参数选项,用来定制gdb的行为。
进入gdb调试环境后,可以使用help命令查看在gdb调试环境中可以使用哪些命令,gdb把命令分为很多类别,可以使用help 来查看具体类别下的每一条命令。help 查看具体命令的帮助文档。
gdb调试环境中可以执行Linux下的shell命令,在gdb调试环境中通过shell 来执行。gdb中的shell命令。
gdb中还有一个make命令,用来在gdb调试环境中通过make 来重新build自己的程序。
list(缩写l)命令列出源码,按回车重复执行上一次命令。
break(缩写b)设置断点命令,break 16 在程序16行处设置断点,break func 在函数入口处设置断点。
info break 查看断点信息
run (缩写r)运行程序
next(缩写n)命令,往下执行一条语句
continue命令(缩写c),继续运行程序,除非遇到断点,否则把剩余程序执行完。
print命令(缩写p),打印变量值,p i, 打印变量i的值。
backtrace命令(缩写bt),查看函数栈。
finish命令,退出函数
q命令,退出gdb。
set args命令可以设置运行时参数,用于传递给main函数的argv参数,这种情况下需要main函数的参数列表不能为空,要有argc和argv两个参数。set args 的第一个参数传给argv[1]以此类推。
show args命令查看设置好的运行参数。
path < dir > 设定程序的运行路径
show path 查看程序的运行路径
set environment varname [=value] 设置环境变量。如 set env USER=tt
show environment [varname] 查看环境变量
cd < dir > 相当于shell的cd命令
pwd 显示当前所在目录
info terminal 显示你程序用到的终端模式
使用重定向控制程序输出。如:run > outfile
tty命令可以指写输入输出的终端设备。如:tty /dev/ttyb
当进程被gdb停住时,可以使用info program 来查看程序是否在运行、进程号、被暂停的原因。
在gdb中,我们有以下几种暂停程序的方式:断点(breakpoint)、观察点(watchpoint)、捕捉点(catchpoint)、信号(signals)、线程停止(threadstops)。可以使用c或者continue命令恢复程序运行。
如果断点在循环中的话,程序停在循环中,这是输入命令c,会发现程序会再次停在同一个断点上,没有继续执行之后的代码,这时可以使用ignore命令,如:ignore 2 100 (ignore 断点编号 忽略断点次数)。忽略断点的次数要大于循环次数,才能跳出循环。
二、设置断点
break +offset
break -offset
在当前行号的前面或者后面的offset行停住。offset为自然数。
break filename:linenum 在源文件filename的linenum行处停住
break filename:function 在源文件filename的function函数处停住
break *address 在程序运行的内存地址处停住
break 命令没有参数时,表示在下一条指令处停住
break … if …可以是上述参数,condition表示条件,在条件成立时停住。
info breakpoints [n] 、info break [n] 查看断点,n表示断点号。
三、设置观察点
观察点一般用来观察某个表达式(变量也是表达式)的值是否发生变化,如果有变化,立马停住程序。
设置观察点的方法:
命令 | 用途 |
---|---|
watch < expr > | 为表达式expr设置一个观察点,一旦表达式的值发生变化,马上停住程序 |
rwatch < expr > | 当表达式被读时,停住程序 |
awatch < expr > | 当表达式的值被读或者被写时,停住程序 |
info watchpoints | 列出当前设置的所有观察点 |
设置捕捉点
设置捕捉点来捕捉程序运行时的一些事件。
设置捕捉点格式: catch < event >
当event发生时,停住程序。event可以是下面的内容:
维护停止点
以上的三种点,就是gdb中的三类停止点。如果觉得定义好的停止点没用了,可以使用delete、clear、disable、enable这几个命令来维护。
命令 | 用途 |
---|---|
clear | 清除所有的已定义的停止点 |
clear < function > ; clear < filename:function > | 清除所有设置在函数上的停止点 |
clear < linenum > ; clear < filename : linenum > | 清楚所有设置在指定行上的停止点 |
delete [ breakpoints ] [range…] | 删除指定断点,breakpoints为断点号,如果不指定断点号表示删除所有断点。range表示断点号范围,如:3-7 |
disable [ breakpoints ] [range…] | 比删除更好的一种方式是disable停止点,disable之后,gdb不会删除,当还需要,enable即可。简写dis |
enable [ breakpoints ] [range…] | enbale所指定的停止点 |
enable [ breakpoints ] once range … | enable 指定停止点一次,当程序停止后,该停止点马上被gdb自动disable |
enable [ breakpoints ] delete range … | enable 指定停止点一次,当程序停止后,该停止点马上被gdb自动删除 |