当我们能够在windows下,使用vs 2019等编译器去进行调试的时候,我们可以将在Linux下使用gdb调试这两者之间进行对比:
调试这个操作,在方法上有区别吗?(Linux和windows)其实,在调试思路上是一样的,在调试的操作方式上一定不一样。
因此,在学习Linux的gdb调试时,一定要抓住我们的调试思路去学习。
在Linux下,我们使用的是命令行调试。
因此,本章着重解析的是操作方法,不是思路:
首先我们先写好测试用的代码:
并且将代码写入makefile中
接着开始调试:调试工具:gdb
使用gdb+需要调试的代码文件来开启调试模式:
但此时这里显示的是没有可调试的地方:
因为在默认情况下,gdb无法对程序进行调试。这是为什么?原因很简单
程序分为debug版本和release版本。只要debug版本才能进行调试。
在Linux中,用gcc/g++生成的软件程序是release版本!
(这里顺便复习一下:gcc默认:动态链接、默认release)
所以,我们需要将其变成debug。我们在编译软件的时候,加上-g。
这时候再make一下,编译后的程序就是debug版本了。
这时候,就能进行正式调试了。
第一步:查看代码:指令:l(L的小写)
解释:第一个输入L,不从0行开始显示。输入l 0,则从0行开始。按下空格,gdb会记住前一次的行数,会从下一行开始,也就是说,只需要l一次,那么剩下的直接按回车就行了。
在将代码全部显示出来后,开始打断点:
通过指令:b {行号}即可打上断点,其中b是break的简写
通过指令:info b来查看断点的编号
去除断点:使用d {断点编号},注意是编号,不是断点的行号,d是delete的简写。
打上断点后,通过指令r,进行跑程序,会在断点除停下来,r的简写是run
在这个断点时,我们有两种选择:一是直接跑完断点(逐过程),二是慢慢地跑断点的内容(逐语句)
如果是逐过程:通过指令:n,是next的简写
如果逐语句,进入函数:通过指令s,是step的简写
进入Print函数,使用n走下一步,直到走完这个函数。
当有多个断点的时候,我们想要从一个断点到另外一个断点,那么可以使用指令:c,continue的简写。
当我们进入一个函数后(这里依然使用24行的函数,也就是第一个断点的函数进行举例),想要查看main函数的栈堆情况,可以使用指令bt
进入这个函数后,我们只想要跑完这个函数,又不到下一个断点,那么使用指令finish
在调试的时候,我们想要看到变量的改变:
指令:p {想要看到的变量}
如果想要一边看变化,一边跑,那么通过指令:display {想要查看的变量名}
不想要常显示的时候,使用指令undisplay {行号},比如:undisplay 2,就是把sum去掉
指令:until {行号},代表跳转至指定行号。如果指定的行号是没有代码的行或者是没有什么意义的,就会自动跳转到有实用意义的行。
修改变量的值:set var {变量}=val
这些指令就是能够在gdb的进行调试的指令啦!
总结一下:
1.在调试之前,我们在代码编译的时候,加上-g,使之变成debug文件
2.用l 0,然后不断回车,查看完整代码信息,也能l {行号},查看所需要的代码信息
3.打断点:b {行号}
4.查看断点:info b
5.跑程序:r
6.跑到断点后,逐语句:s,逐过程:n
7.查看变量:p {i}
8.常显示:display {i} 除去常显示:undisplay
9.修改变量值:set var {} = val