原文链接.
记录一下方便以后查找
什么是GDB?
从GDB的官网可以知道:
GDB是一个GNU项目的调试器,它使您可以查看一个程序在执行过程中正在执行的操作,或是一个程序崩溃时正在做什么。
GDB主要可以完成下面四种功能:
- 启动程序,可以按照工程师自定义的要求随心所欲的运行程序。
- 让被调试的程序在工程师指定的断点处停住,断点可以是条件表达式。
- 当程序被停住时,可以检查此时程序中所发生的事,并追索上文。
- 动态地改变程序的执行环境。
调试前的准备
gdb调试需要被调试的可执行文件包含调试所需的符号表(symbol table),在编译时加上*-g*参数就能使编译出来的可执行文件包含调试所需的符号。
编译
gcc -g test.c -o test
进入gdb调试环境,这里也可以直接指定一些参数,也可以在进入环境之后再指定参数,这样进入gdb调试环境之后,test程序还没有运行,需要手动运行。
gdb test
几条常用的命令
在gdb调试环境里面,可以用help来查看有哪些命令(command),还可以用
help command
来获取关于命令的详细帮助
1.list
可以在gdb环境中显示出代码,必须要包含符号表才可以显示,如果可执行文件没有符号表,可以用file命令后期手动导入,一般后缀带dbg的包里面会包含符号表.
- list :显示特定行号周围的代码
- list :显示特定函数名前后的代码
- list:显示当前行前后代码,当前行会随程序运行,暂停而改变
- list -:显示当前行前面的源码
2.run
进入gdb环境之后,用run命令来运行程序。在程序运行之前,我们可以设置如下四方面的工作环境:
- 程序运行参数
set args可以在gdb启动之后为被debug的程序设置传入的参数,如set args 1 2 3则是传入三个参数:1 2 3
*gdb --args executable-file [inferior-arguments …]*则是在进入gdb环境之前就传入参数如gdb --args test 1 2 3 - 运行环境
path设置搜索路径,相当于在shell中设置PATH变量
set environment varname [=value]用于设置环境变量的值与shell中直接设置值一样
show environment [varname]则用于查看环境变量。 - 工作目录
cd <dir>用于切换程序执行的路径
pwd用于显示程序执行的路径 - 程序的输入和输出
nfo terminal 用于显示程序用到的终端的模式;gdb中也可以使用重定向控制程序输出,如run > outfile;
tty命令可以指定输入输出的终端设备,如:tty /dev/ttyS1。
3.break命令
用来设置断点,用法包括:
- break <function>
在进入函数时停住 - break <linenum>
在指定行号停住 - break +offset / break -offset
在当前行的offset行停住,offset为数字 - break filename:linenum
在某个文件的第几号停住 - break filename:function
在某个文件的指定函数处停住 - break
执行下一条语句停住 - break … if <condition>
… : 可以是上述的linenum
condition : 表示条件
例如:break 16 if i=2
表示需要在i == 2时停止在16行。
- info breakpoints
用于查看有哪些断点
4.单步执行命令
单步执行的命令有以下几个:
- step
单步执行,后面的count表示需要执行几条命令,遇到函数会进入 - next
和上面的step基本一样,区别时next遇到函数不会进去 - finish
运行程序,执行单前函数返回,并打印函数返回时的返回值和堆栈信息. - until
用于执行程序知道退出一个循环体
5.continue命令
用于在程序被断点中断时,恢复程序的执行,用法是:
continue [ignore-count]
c [ignore-count]
fg [ignore-count]
ignore-count表示需要忽略后面多少个断点
6.print命令
当程序被停住时,可以使用print命令(缩写为p)来查看当前程序运行时的数据:
print <expr>
print /<f> <expr>
是表达式,是被调试的程序中的表达式,是输出的格式,比如,如果要把表达式按16进制的格式输出,那么就是/x。在表达式中,有几种GDB所支持的操作符,它们可以用在任何一种语言中,“@”是一个和数组有关的操作符,“::”指定一个在文件或是函数中的变量,“{} ”表示一个指向内存地址的类型为type的一个对象。
当需要查看一段连续内存空间的值的时间,可以使用GDB的“@”操作符,“@”的左边是第一个内存地址,“@”的右边则是想查看内存的长度:
p *array@len
我们可用display命令设置一些自动显示的变量,当程序停住时,或是单步跟踪时,这些变量会自动显示。 如果要修改变量,如x的值,可使用如下命令:
print x=4
x=4
7.watch命令
watch一般来观察某个表达式(变量也是一种表达式)的值是否有变化了,如果有变化,马上停住程序。我们有下面的几种方法来设置观察点: watch :为表达式(变量)expr设置一个观察点。一量表达式值有变化时,马上停住程序。rwatch :当表达式(变量)expr被读时,停住程序。awatch :当表达式(变量)的值被读或被写时,停住程序。info watchpoints:列出当前所设置了的所有观察点。
watch i
8.examine命令
我们可以使用examine命令(缩写为x)来查看内存地址中的值。examine命令的语法如下所示:
x/<n/f/u> <addr>
表示一个内存地址。“x/”后的n、f、u都是可选的参数,n 是一个正整数,表示显示内存的长度,也就是说从当前地址向后显示几个地址的内容;f 表示显示的格式,如果地址所指的是字符串,那么格式可以是s,如果地址是指令地址,那么格式可以是i;u 表示从当前地址往后请求的字节数,如果不指定的话,GDB默认是4字节。u参数可以被一些字符代替:b表示单字节,h表示双字节,w表示四字节,g表示八字节。当我们指定了字节长度后,GDB会从指定的内存地址开始,读写指定字节,并把其当作一个值取出来。n、f、u这3个参数可以一起使用,例如命令“x/3uh 0x54320”表示从内存地址0x54320开始以双字节为1个单位(h)、16进制方式(u)显示3个单位(3)的内存。 ==
其他
可以在使用时help来查看具体使用方法
- jump : 用于跳转
- signal : 用于发送信号给程序
- return : 用于强行返回一个函数,后面可以接返回值
- call:用于强行调用某函数
- info用于查看各种信息