gdb是linux中的调试器,由于linux是命令行式的操作,所以要进行调试也一定是以命令行的方式进行,相比于win下vs等IDE的调试使用起来操作比较繁琐,但是程序调试的思路都是大致的。
但是在某些开发场景并没有设计专门的IDE,这种情况下是没有办法用IDE进行调试的,这个时候只能使用gdb调试了。
俗话说一名合格的程序员,大部分的时间都是在debug调试,可见熟悉gdb调试是至关重要的了!
编译及运行结果:
进入gdb环境进行调试:
但是再次版本下,我们发现输入gdb指令:l 0的时候,报错:
原因是默认情况下,我们在linux下使用gcc/g++默认生成的程序都是release版本,这种发布的版本是不带调试信息的,无法进行调试,是给用户使用的;
我们需要调试,就得编译的时候带选项-g告知编译器编译debug可调式版本的程序!
我们进一步观察能发现,release版本的成虚要比debug版本更小,因为优化,抹去了调试用的信息等:
成功进入gdb调试环境并且能够调试了,我们介绍常用指令的学习
l(list):显示出可执行程序内的代码,方便观察
当我们用l指令配合一个数字的时候:l + num表示从num行开始显示代码;
此时只能显示10行代码:,接着继续按回车,就能接着显示后续的10行代码;
当我们用l指令配合两个数字(用逗号隔开)的时候:l num1,num2表示显示从num1行到num2行的代码;
当我们使用l+函数名的时候:l addToVal 表示显示addToVal函数的代码,同样每次显示10行;
b + 行数: 表示在指定行添加断点(breakpoint)
break+函数名: 进入指定函数,在其作用域内第一行有效代码设置断点
在第5行和第10行加断点:
在addToVal函数第一行代码处设置断点:
info b: 显示出所有断点的信息
d + 断点编号:删除该编号的断点
(注意,断点编号不是行号,d之前需要用info查一下断点的编号Num)
l(list):程序运行指令,有断点运行到第一个断点处,无断点运行整个程序;
无断点的情况下运行完了整个程序:
会显示断点的编号以及中断位置所处的函数名和当前文件名以及断点行号;
n(next) : 在程序已经run的基础上,逐过程执行,遇到函数调用不会进入直接执行完毕,类似VS中Debug调试的F10
s(step) :在程序已经run的基础上, 逐语句执行,遇到函数可进入函数内部观察细节,类似VS中Debug调试的F11
c(continue) : 在程序已经run的基础上,从当前断点跳跃到下一个断点处,类似于VS中Debug调试的F5
在24行addToVal()函数入口处的断点处停下,用c指令,直接跳转到了26行的断点,期间的addToVal()和Print()函数都已被执行!
bt :查看各级函数调用的栈帧信息以及参数
finish: 在某个函数内部时,不想再执行该函数,可以用finish直接结束函数,从而跳出该函数,1.之后回到这个函数的调用处,等待进一步的命令;2.得到这个函数的返回值;
p(print)+变量名 : 打印当前栈帧内的变量的值
display 临时变量 : 跟踪一个变量,变量常驻在屏幕上,每次停下来都显示他的值;有点像VS的监视窗口中添加监视的变量;
undisplay+临时变量编号 : 使其不再常驻在屏幕上 (与display配合使用,起相反作用)
until+行号 :直接跳至指定的有效代码行,一般用于直接跳出某个循环或递归
diable+断点号 : 禁用指定的断点
启用断点,和上面disable用法一样,不再描述;