##

LINUX下GDB的使用方法

简单说说GDB的用法,请赐教,诸君,拔剑吧!
1.什么是GDB,能干啥?
 gdb是GNU开源组织发布的一个强大的Linux下的程序调试工具。

 一般来说,GDB主要帮助你完成下面四个方面的功能:

1、启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。

2、可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)

3、当程序被停住时,可以检查此时你的程序中所发生的事。

4、你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。

(来自百度百科)
2.GDB调试的对象
 GDB主要来调试C/C++语言写的程序,当然也就可以调试其他语言程序。这里我们只说C/C++(其他语言我也不会呀)
GDB调试一定要是可执行文件而不是.c文件
要用gcc进行编译,具体的命令如下:

gcc -g 源文件.c -o 输出的目标文件

-g,-o参数缺一不可

LINUX下GDB的使用方法(简单说说)
3.GDB常用的调试命令
一大波命令来袭,hold,或者jump
(gdb)help:查看命令帮助,具体命令查询在gdb中输入help + 命令,简写h

(gdb)run:重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件),简写r

(gdb)start:单步执行,运行程序,停在第一执行语句

(gdb)list:查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数),简写l

(gdb)set:设置变量的值

(gdb)next:单步调试(逐过程,函数直接执行),简写n

(gdb)step:单步调试(逐语句:跳入自定义函数内部执行),简写s

(gdb)backtrace:查看函数的调用的栈帧和层级关系,简写bt

(gdb)frame:切换函数的栈帧,简写f

(gdb)info:查看函数内部局部变量的数值,简写i

(gdb)finish:结束当前函数,返回到函数调用点

(gdb)continue:继续运行,简写c

(gdb)print:打印值及地址,简写p

(gdb)quit:退出gdb,简写q

(gdb)break+num:在第num行设置断点,简写b

(gdb)info breakpoints:查看当前设置的所有断点

(gdb)delete breakpoints num:删除第num个断点,简写d

(gdb)display:追踪查看具体变量值

(gdb)undisplay:取消追踪观察变量

(gdb)watch:被设置观察点的变量发生修改时,打印显示

(gdb)i watch:显示观察点

(gdb)enable breakpoints:启用断点

(gdb)disable breakpoints:禁用断点

(gdb)x:查看内存x/20xw 显示20个单元,16进制,4字节每单元

(gdb)run argv[1] argv[2]:调试时命令行传参

(gdb)set follow-fork-mode child#Makefile项目管理:选择跟踪父子进程(fork())

core文件:先用$ ulimit -c 1024 开启core,当程序出错会自动生成core文件。调试时 gdb a.out core
ctrl+c:退出输入

以上就是GDB的命令其中的部分,下面列详细写一些基础常用的命令:
 **list **
list 可写为l,可以列出所调试程序的代码
LINUX下GDB的使用方法(简单说说)

1.list+linenumber
可以列出linenumber附近的代码
2.list function
可以列出函数上下文的源程序 run&quit 在GDB中如何将程序运行起来,此时只要输入run命令,就可以将命令跑起来 而quit则是退出GDB调试 **break** ![](https://ws1.sinaimg.cn/large/006SH20tly1fv98ppm7o1j30cr00xt8l.jpg)

gdb调试时使用break命令来设置断点,有如下几种下断点地方法

break < function >

在进入指定的函数function时既停止运行,C++中可以使用class::function或function(type, type)格式来指定函数名称

break < lineNumber>

在指定的代码行打断点

break +offset/break -offset

在当前行的前面或后面的offset行打断点,offset为自然数

break filename:lineNumber

在名称为filename的文件中的第lineNumber行打断点

break filename:function

在名称为filename的文件中的function函数入口处打断点

break *address

在程序运行的内存地址处打断点

break

在下一条命令处停止运行

break … if < condition>

在处理某些循环体中可使用此方法进行调试,其中…可以是上述的break lineNumber、

break +offset/break -offset中的参数,其中condition表示条件,在条件成立时程
序即停止运行,如设置break if i=100表示当i为100时程序停止运行。

查看断点时,也可以使用info命令如info breakpoints [n]、info break [n]其中n 表示断点号来查看断点信息。

可以通过delete命令删除所有的断点
next
使用next命令单步执行程序代码,next的单步不会进入函数的内部,与next对应的step命令则在单步执行一个函数时进入函数内部,类似于VC++中的step into.
其用法如下
next
单步跟踪,如果有函数调用不会进入函数,如果后面不加count表示一条一条的执行,加count表示执行后面的count条指令
continue
当程序遇到断点停下来之后,可以执行continue继续执行到下一个断点或到程序结束
print
print可以缩写为p,可以通过print命令查看参数或程序运行数据
值得注意的是print输出可以指定输出格式:

x按16进制格式显示变量

d按十进制显示变量

u按十六进制格式显示无符号整形

o按八进制格式显示变量

t按二进制格式显示变量

c按字符格式显示变量

f按浮点数格式显示变量
GDB查看,执行汇编语言
查看汇编 disassemble

/m 源码和汇编一起排列
/r 还可以看到16进制代码
下面就是查看的汇编代码
LINUX下GDB的使用方法(简单说说)
那么我如果要是在红箭头出进行下断如何下?
LINUX下GDB的使用方法(简单说说)
LINUX下GDB的使用方法(简单说说)
还有这种随源码一起排列的,是不是很直观:
LINUX下GDB的使用方法(简单说说)
再补充几条命令
backtrace(直译回溯)(bt)

当你的程序调用了一个函数,函数的地址,函数参数,函数内的局部变量都会被压入“栈”(Stack)中。你可以用这条命令来查看当前的栈中的所有信息。人为的将程序下断停住,直接上图:
LINUX下GDB的使用方法(简单说说)
bt n
显示栈顶的几个层的信息
bt -n
显示栈底下的几层信息

but,如果你要查看某一层的信息,你需要在切换当前的栈,一般来说,程序停止时,最顶层的栈就是当前栈,如果你要查看栈下面层的详细信息,首先要做的是切换当前栈。(就有了下面这条命令)
frame(帧)(f)
f
n是一个从0开始的整数,是栈中的层编号。比如:frame 0,表示栈顶,frame 1,表示栈的第二层。
up
表示向栈的上面移动n层,可以不打n,表示向上移动一层。
down
表示向栈的下面移动n层,可以不打n,表示向下移动一层。

info f

会打印出更为详细的当前栈层的信息,只不过,大多数都是运行时的内内
地址
LINUX下GDB的使用方法(简单说说)

(以下讲解没有截图,为避免审美疲劳,请适度观看)

print(p)

 可以输出东西可多,全局变量,静态全局变量,局部变量,

 如果你的局部变量和全局变量发生冲突(也就是重名),一般情况下是局部变量会隐藏全局变量。
查看全局变量,利用::,例如在1.c中看x

gdb)p “1.c”::x

数组(动)
p *[email protected]
array:数组的首地址,len:数据的长度
(gdb) p *[email protected]
$1 = {1, 2, 3, 4, 5}
(静)
直接p数组名
所有寄存器的值

info registers

查看指定的寄存器的值

p $eip

结构体
如果你想很漂亮的输出结构体请设置
set print pretty on
打开print pretty这个东西,没错,输出很漂亮滴,
(盗一手别人的图)
LINUX下GDB的使用方法(简单说说)
是不是很漂亮,不再是那种一行不间断,能看死人的那种。
总而言之,p很强大,只要你想输出。

全剧终)没有第二部

相关文章: