VScode C++ 开发 (四):GDB调试器 (good!)

1. 前言

  • GDB(GNU Debugger) 是一个用来调试C/C++程序的功能强大的调试器,是Linux系统开发C/C++最常用的调试器
  • 程序员可以使用GDB来跟踪程序中的错误,从而减少程序员的工作量。
  • Linux 开发C/C++ 一定要熟悉 GDB
  • VSCode是通过调用GDB调试器来实现C/C++的调试工作的

GDB主要功能:

  • 设置断点(断点可以是条件表达式)
  • 使程序在指定的代码行上暂停执行,便于观察
  • 单步执行程序,便于调试
  • 查看程序中变量值的变化
  • 动态改变程序的执行环境
  • 分析崩溃程序产生的core文件

2. 常用调试命令参数

调试开始:执行gdb [exefilename] ,进入gdb调试程序,其中exefilename为要调试的可执行文件名

1 ## 以下命令后括号内为命令的简化使用,比如run(r),直接输入命令 r 就代表命令run
2
3 $(gdb)help(h)        # 查看命令帮助,具体命令查询在gdb中输入help + 命令 
4
5 $(gdb)run(r)         # 重新开始运行文件(run-text:加载文本文件,run-bin:加载二进制文件)
6
7 $(gdb)start          # 单步执行,运行程序,停在第一行执行语句
8
9 $(gdb)list(l)        # 查看原代码(list-n,从第n行开始查看代码。list+ 函数名:查看具体函数)
10
11 $(gdb)set            # 设置变量的值
12
13 $(gdb)next(n)        # 单步调试(逐过程,函数直接执行)
14
15 $(gdb)step(s)        # 单步调试(逐语句:跳入自定义函数内部执行)
16
17 $(gdb)backtrace(bt)  # 查看函数的调用的栈帧和层级关系
18
19 $(gdb)frame(f)       # 切换函数的栈帧
20
21 $(gdb)info(i)        # 查看函数内部局部变量的数值
22
23 $(gdb)finish         # 结束当前函数,返回到函数调用点
24
25 $(gdb)continue(c)    # 继续运行
26
27 $(gdb)print(p)       # 打印值及地址
28
29 $(gdb)quit(q)        # 退出gdb
30
31 $(gdb)break+num(b)                 # 在第num行设置断点
32
33 $(gdb)info breakpoints             # 查看当前设置的所有断点
34
35 $(gdb)delete breakpoints num(d)    # 删除第num个断点
36
37 $(gdb)display                      # 追踪查看具体变量值
38
39 $(gdb)undisplay                    # 取消追踪观察变量
40
41 $(gdb)watch                        # 被设置观察点的变量发生修改时,打印显示
42
43 $(gdb)i watch                      # 显示观察点
44
45 $(gdb)enable breakpoints           # 启用断点
46
47 $(gdb)disable breakpoints          # 禁用断点
48
49 $(gdb)x                            # 查看内存x/20xw 显示20个单元,16进制,4字节每单元
50
51 $(gdb)run argv[1] argv[2]          # 调试时命令行传参
52
53 $(gdb)set follow-fork-mode child   # Makefile项目管理:选择跟踪父子进程(fork())

3. 命令详解

当程序运行时出现问题时,通过GDB调试可以快速找到问题点,当然不是所有问题都能通过调试找到问题点。

在GCC编译程序时,需要加 -g参数,可以通过在-g选项后附加数字123来指定在代码中加入调试信息的多少。默认的级别是2(-g2),此时产生的调试信息包括扩展的符号表、行号、局部或外部变量信息。级别3(-g3)包含级别2中的所有调试信息,以及源代码中定义的宏。级别1(-g1)不包含局部变量和与行号有关的调试信息,因此只能够用于回溯跟踪和堆栈转储之用。

#include <stdio.h>
 
int main()
{
	int a;
	while(1)
	{
		printf("请输入a的值:\n");
		scanf("%d",&a);
		int b = 10/a;
		printf("b = %d\n",b);
	}
	return 0;
}

3.1 编译

gcc -g demo.c -o demo

3.2 启动GDB

终端输入命令:

gdb demo     # demo 是可执行文件
  • 若有参数:gdb --args demo paramet,当GDB提示符出现的时候,表明GDB已经做好准备进行调试了,现在可以通过run命令让程序开始在GDB的监控下运行,如下图:

在这里插入图片描述

  • 输入:run
    在这里插入图片描述
    runstart 指令都可以用来在 GDB 调试器中启动程序,它们之间的区别是:

  • 默认情况下,run 指令会一直执行程序,直到执行结束。如果程序中手动设置有断点,则 run 指令会执行程序至第一个断点处;

  • start 指令会执行程序至 main() 主函数的起始位置,即在 main() 函数的第一行语句处停止执行(该行代码尚未执行)。

如果进程已经运行,可以根据进程号启动:gdb –p pid

3.3 断点

打断点
  • 断点命令:break,也可以简写为b

  • 某一行进行打断点(第3行):b 3

  • 多个文件,对某个文件的某一行打断点:b demo.cpp:4,表示对demo.c文件4行打断点;

  • 对函数打断点:b fun ,表示对fun()函数打断点

  • 多个文件,对某个函数打断点:b demo.c:fun ;

查询断点
  • 查询所有断点:info b
  • 查询第n个断点:info b n
  • 条件断点: b demo.c:8 if Value = 10
删除断点:delete,简写d
  • 删除所有的断点:delete break
  • 删除某个断点 n为断点号:delete break n
  • 删除设在n行的断点(多个文件与打断点一样):clear n
  • en/enable启用某个断点
  • dis/disable 禁用某个断点
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

3. 4 打印

打印断点处某变量值,用命令 p;

  • 16进制:p/x
  • 二进制:p/t

3.5 单独调试

  • 单步调试:next ,简写为n,一条一条简单语句执行。

在这里插入图片描述

  • 单步调试:step,简写s,若在某个函数断点处,则进入此函数。

在这里插入图片描述

  • 退出当前断点进入下一个断点,或继续运行。
    命令:continue ,简写c

  • finish 退出进入的函数 ,并且打印函数返回时的堆栈地址和返回值及参数值等信息,回到上一层调用函数

  • until 在一个循环体内单步跟踪时,这个命令可以运行程序直到退出循环体,可简写为u

until + 行号 运行至某行
call + 行数 + (参数)
调用程序中可见的函数,并传递参数

如:call gdb_test(66)

3.6 显示源码

查看源码:list(l),默认显示10行

  • l 函数名
  • l 数组

3.7 设置/查看变量值(set/show)

  • 修改变量值:set 变量名=value
  • 查看变量值:show 变量名

3.8 查看堆栈信息

当程序崩溃可以使用,where命令,查看死在那个位置

  • bt查看函数栈

  • f/frame切换到当前调用线程的指定堆栈

  • f 2 进入第2栈

3.9 查看线程

  • i threads 【查看所有线程】
  • t num 【进入num线程】
  • thread 【查当前线程】
  • thread 2 【切换到第二个线程】

4.【实战】命令行调试

4.1 准备代码

建一个C++源代码文件 sum.cpp,添加以下代码

#include <iostream>
using namespace std;

int main(int argc, char const *argv[])
{
    int N = 100;
    int sum = 0;
    int i = 1;
    
    while(i <= N){
        sum = sum + i;
        i = i + 1;
    }
    
    cout << "sum = " << sum <<endl;
    cout << "The program is over " <<endl;
    
    return 0;
}

4.2. 进入调试模式

在进入调试模式之前,先编译源代码,如下过程。

  • 普通编译方式
g++ sum.cpp -o no_g.out
  • 编译出用于调试的可执行文件
g++ -g sum.cpp -o yes_g.out

使用gdb命令进行调试,如果我们调试 no_g.out ,将会提示错误。因为no_g.out这个可执行文件不包含用于调试的信息,输入quit再按回车即可,通过gdb yes_g.out指令执行包含调试信息的可执行文件,看到以下输出
在这里插入图片描述
此时可以正常进入调试

4.3 调试过程

直接执行

run

或者使用简写r,运行结果如下图
在这里插入图片描述
在第11行打断点,

在这里插入图片描述
也可以使用简写的方式,在第12行打断点

b 12

结果如下图
在这里插入图片描述
使用info breakpoints指令或者指令简写i b查看当前的断点,如下图结果

在这里插入图片描述
使用run指令或者r指令执行程序,此时命中了第11行断点,如下图内容

在这里插入图片描述
此时可以查看变量的值,如查看i的值,可以使用print i或者p i指令,如下图
在这里插入图片描述
此时程序执行到第11行处,如果我们需要继续执行,输入continue指令并按回车即可,程序将执行到代码的第12行,如下图
在这里插入图片描述因为我们是在while循环体内,i的值将不断变化,如果我们需要跟踪i值的变化,需要输入display i指令即可,再输入continue指令让程序单步执行,每次都会打印i的值,如下图
在这里插入图片描述
可以观察到,通过循环,又回到了第一个断点,此时i的值已经变成了2。在gdb调试中,如果我们只按回车键,gdb将执行我们最后一次输入的指令,所以我们可以一直按回车键继续让程序单步执行。

当断点执行都某个位置时,我们想要查看断点附近5行的代码,可以执行list指令进行查看,如下图
在这里插入图片描述

参考

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
如果在VS Code中没有C++的GDB或LLDB调试,你可以按照以下步骤进行设置: 1. 首先,确保你已经安装了GDB或LLDB调试。你可以在终端中运行以下命令来检查它们是否安装: ``` gdb --version lldb --version ``` 如果没有安装,你可以使用包管理(如apt、yum、brew等)来安装它们。 2. 安装C/C++扩展:打开VS Code并导航到"Extensions"(或按下Ctrl+Shift+X),搜索并安装名为"C/C++"的扩展。 3. 在VS Code中打开你的C++项目。 4. 在项目文件夹中创建一个名为".vscode"的文件夹(如果不存在),然后在其中创建一个名为"launch.json"的文件。 5. 在"launch.json"文件中添加以下配置(用于GDB调试): ```json { "version": "0.2.0", "configurations": [ { "name": "C++ Launch (GDB)", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/<可执行文件名>", "args": [], "stopAtEntry": false, "cwd": "${workspaceFolder}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "<GDB可执行文件路径>" } ] } ``` 替换`<可执行文件名>`为你的C++可执行文件的名称,`<GDB可执行文件路径>`为你的GDB可执行文件的路径。 6. 如果你使用的是LLDB调试,可以使用以下配置(替换`<LLDB可执行文件路径>`): ```json { "version": "0.2.0", "configurations": [ { "name": "C++ Launch (LLDB)", "type": "lldb", "request": "launch", "program": "${workspaceFolder}/<可执行文件名>", "args": [], "cwd": "${workspaceFolder}", "externalConsole": false, "preLaunchTask": "build", "miDebuggerPath": "<LLDB可执行文件路径>" } ] } ``` 替换`<可执行文件名>`为你的C++可执行文件的名称,`<LLDB可执行文件路径>`为你的LLDB可执行文件的路径。 7. 保存"launch.json"文件。 8. 现在你可以在VS Code的调试选项卡中选择C++调试配置,并点击启动按钮开始调试。 这样,你就可以在VS Code中使用GDB或LLDB调试调试你的C++代码了。如果你遇到任何问题,请提供详细的错误信息,以便我能够更好地帮助你。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

@BangBang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值