上一篇博客已经介绍了
1,认识并使用vscode
2,使用g++编译运行一个多文件C++工程
3,使用cmake编译一个多文件C++工程
4,在vscode上面编译运行/调试一个多文件C++工程
使用vscode在linux平台开发C++程序(1)(包括cmake,gdb)
接下来介绍:
db是GNU开源组织发布的一个强大的Linux下的程序调试工具。
一般来说,GDB主要帮助你完成下面四个方面的功能:
启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。
可让被调试的程序在你所指定的调置的断点处停住。(断点可以是条件表达式)
当程序被停住时,可以检查此时你的程序中所发生的事。
你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。
sudo apt-get update
sudo apt-get install gdb
还是上一篇博客用到的例子,但是为了方便查看更长的调试过程,在main函数中加一个while循环。
而且注意,最后编译形成的可执行文件 main_cmake 是加了-g选项形成的。
-g选项告诉GCC产生能被GNU调试器GDB使用的调试信息,以调试程序。
产生带调试信息的可执行文件g++ -g hello.cpp -o hello,
注意到这个-g选项加在了g++后面,其实这个参数的位置放哪里都无所谓,
也可以这样g++ hello.cpp -o hello -g,下面要讲的其他的参数的位置也是同样无所谓的。
如果是使用cmake进行编译则需要设置debug模式编译
1、通过命令行的方式
cmake -DCMAKE_BUILD_TYPE=Debug ..
2、在cmakelist.txt中添加
set(CMAKE_BUILD_TYPE Debug CACHE STRING "set build type to debug")
或者set(CMAKE_BUILD_TYPE "Debug")
只有这个可执行文件 main_cmake 才是加了调试信息的debug版本的可调式的可执行文件。gdb调试需要了解的主要内容为三个方面
首先使用gdb命令调试
gdb main_cmake//gdb+主程序开始调试
在可调试main_cmake中打断点
以下是所有打断点的方式
1,使用break方式打断点(b 为break的缩写)
1)b 行号
2)b 文件:行号
3)b 行号 if 条件 //条件断点,加一个条件 例如 b 13 if n==4 (当n=4的时候断)
4)b 函数名 //不管其参数是什么,只要函数名和所给的一样,就都会打上断点
5)b 函数名带参数
6)b 类名:函数名
7)b 类名:函数名带参数
8)b 文件:函数名
9)b 文件:函数名带参数
2,使用watch方式打断点
watch 表达式
//比如:运行到某处断点以后,输入命令 watch n ,该语句写了以后就相当于在运行到的这个地方打了个断点,
以后程序运行到此处都会显示n以前的值和现在的值。
补充:
1)查看打过的所有断点info breakpoints 缩写为 i b或者i b 断点编号
2)删除断点
1,clear 删除断点
1)clear 函数名
2)clear 函数名带参数
3)clear 行号
4)clear 文件名:行号
2,delete 删除断点 (简写d或者del)
1)delete 断点编号
2)delete 断点范围
3)delete 删除所有断点
3,加断点的某些特殊功能
1)disable(简写dis)断点编号或范围n1-n2 //让某些断点暂时失效
2)enable(简写en,ena)断点编号或范围n1-n2 //让某些断点重新生效
3)enable once 断点编号 //只断某断点一次,后面执行到该断点的时候不断
4)enable count数量 断点编号 //只断某断点前n次,后面的不断
5)ignore断点编号 次数 //该断点的前n次不断,后面断
4,保存和读取加了断点的文件
1)save breakpoint 断点保存文件名 //将目前加了的断点保存为某个文件
2)gdb 可执行文件名 -x 断点保存文件名 //读取以前加的断点再调试可执行文件
1,与启动有关的命令
1),run开始运行,使用gdb main_cmake开始调试,然后加上断点,就可以输入run命令,开始调试,直接运行到第一个断点处中断。
2),continue,简写为c,即继续执行,在当前中断处继续执行,直到执行到下一个断点处中断。
2,与停止有关的命令
1)kill停止程序
2)quit退出gdb,简写q
3,与执行有关的命令
1)continue继续,简写为c
2)where显示当前执行的具体函数和代码
3)step单步进入,简写s
4)next单步跳出,简写n
5)finish完成本函数
5.3.1查看栈
1)backtrace 简写bt //显示当前断点处的函数栈的所有函数栈帧
//例如在c函数中有一个断点,c函数是被b函数调用的,b函数是被a调用的;则会显示c,b,a函数的栈帧。
2)bt 栈帧数 //显示指定数量的栈帧(栈帧编号从小到大)
3)bt -栈帧数 //显示指定数量的栈帧(栈帧编号从大到小)
4)backtrace full //显示所有栈帧的局部变量
5)frame 简写f //显示当前栈帧
6)f 帧编号 //切换到当前堆栈的指定栈帧
7)up n //向上移n个位置(往栈底走)
8)down n //向下移n个位置
9)info locals //查看当前帧的局部变量
5.3.2查看源码
1)list 简写l //查看当前源码,默认查看上下5行
2)l 行号 //显示指定行号代码(行号在中间)
3)l 函数名 //显示指定函数的代码
4)l- //往前显示代码
5)l 开始,结束 //显示从开始行到结束行的所有源代码
6)I 文件名:行号
7)set listsize 数字 //设置要显示的源代码行数(是上下n行)
8)show listsize //查看一次l显示的代码行数
5.3.3查看变量
1,查看内存
1)x 地址 //查看指定内存的地址
2)x/nfu 地址 //以格式化的方式查看指定的内存
n 单位数量
f 格式化,例如十进制i,16进制x,字符c
u 一个单位大小
b 一个字节
h 双字节
w 四个字节
g 八个字节
2,查看变量
1)print 查看变量 简写p
p 变量名
p 文件名::变量名
p 或print或call 直接执行函数(包括用户函数和内部函数)
2)ptype 变量 //查看变量类型
3)ptype 数据类型 //查看类型信息
4)set print prtty //格式化结构体输出
5)set print array on/off //数组友好显示与否
前面介绍了可以在vscode上直接调试一个C++工程,也介绍了直接使用gdb调试一个工程。其实也可以在vscode上调试某个C++的过程中使用gdb命令进行调试。这个用法也是比较有必要的,比如只有使用gdb才能看内存信息。
一般情况下默认是 No configurations, 此时按下 F5,会提示你配置文件 launch.json 不存在,点击 Open launch.json,然后开始下一步的 launch.json 配置。
在上一步结束后,我们可以看到 launch.json 界面。
其中需要注意并修改的是:
配置后如下图:
按上述配置后即可将 gdb 调试入门(二) 中生成的 helloworld 可执行文件进行 gdb 调试。此时再次按下 F5,即可进入 gdb 调试界面。
注:如果还需要配置 编译 等更多指令,可以如上图中写入注释掉的部分:
"preLaunchTask": "build" 生成子 task,可在里面编辑 gcc 命令等。具体可参考 VSCode GDB 调试配置
"miDebuggerServerAddress" 配置服务器的地址和端口。
如果顺利完成上述操作,可以看到以下操作界面:
可以观察到这里有个小工具栏:
工具栏从左到右依次代表:
同时按 F9 可以在当前行加入断点。具体细节请参考:VSCode Debugging。
常见命令和解释:https://blog.csdn.net/awm_kar98/article/details/82840811
gdb入门详解:https://zhuanlan.zhihu.com/p/74897601
GDB多线程调试(调试命令+调试演示):https://blog.csdn.net/weixin_42158742/article/details/113100151