当前位置: 首页 > article >正文

【C++】使用gdb在命令行下调试C++程序(二)

如果你没看过上篇文章,建议你看看上篇【C++】使用gdb在命令行下调试C++程序(一)

这篇文章补充上次没写完的gdb调试。

我就是要在Linux上安装gdb

好的,我将WSL搭载的Linux发行版从24.04降级到22.04,结果gcc gdb全部安装成功了。

sudo apt install gcc
sudo apt install gdb

安装成功
这说明真的就是24.04的问题,但是为什么我也不太清楚,可能因为22.04默认安装gcc11,而24.04默认安装gcc14。所以如果你也有类似的问题,可以尝试降级。

打印/追踪变量

我们在函数的21行打一个断点:

Thread 1 hit Breakpoint 1, main () at testOP.cpp:21
21          S s2{1};

此时运行,使用p 变量名来打印变量的名字

(gdb) p s2
$1 = {num = 8}

由于s2还没被赋值,此时打印的是内存的残留数据,再运行一行,s2的值就有了:

(gdb) n
22          cout << (s1 == s2) << endl;
(gdb) p s2
$7 = {num = 1}

使用display 变量名可以追踪变量,每次执行操作时都会打出变量的值:

(gdb) b 21
Breakpoint 3 at 0x7ff619ac146e: file testOP.cpp, line 21.
(gdb) r   
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 4288.0x2c34]
[New Thread 4288.0x67ec]
[New Thread 4288.0x3718]

Thread 1 hit Breakpoint 3, main () at testOP.cpp:21
21          S s2{1};
(gdb) display s1
1: s1 = {num = 1}
(gdb) n
22          cout << (s1 == s2) << endl;
1: s1 = {num = 1}

需要注意的是display操作需要在程序运行时执行,否则会找不到符号:No symbol "s1" in current context.

undisplay 变量编号,可以取消跟踪,比如上面的s1编号就是1(前面那个数字)

(gdb) n
22          cout << (s1 == s2) << endl;
1: s1 = {num = 1}
(gdb) undisplay 1
(gdb) n
1
23      }

打印函数堆栈

bt可以打印函数的堆栈

(gdb) bt
#0  main () at testOP.cpp:21
(gdb) r
The program being debugged has been started already.
Start it from the beginning? (y or n) n
Program not restarted.
(gdb) s
S::S (this=0x5ffec8, num=1) at testOP.cpp:8
8           S(int num) : num(num) {};
(gdb) bt
#0  S::S (this=0x5ffec8, num=1) at testOP.cpp:8
#1  0x00007ff619ac147f in main () at testOP.cpp:21

比如我在进入S的构造函数以后,此函数就取代了main函数成为新的栈顶。

赋值

可以使用set var 变量名=值对变量进行赋值

(gdb) display s1
2: s1 = {num = 1}
(gdb) set var s1=2
(gdb) n
22          cout << (s1 == s2) << endl;
2: s1 = {num = 2}

大体上来说这种赋值需要遵循C++的语法,比如

  1. 需要保证变量是可以赋值的,不能为const,不能在当前作用域不可见——比如gdb还没运行到函数内部,就对函数内的局部变量赋值,等等。
  2. 不能对有多个成员的结构体赋总值,但是可以按C++语法用大括号。

总之,代码里不能进行的赋值操作,set var也不行。

开启 / 禁用断点

disable b使所有断点无效

(gdb) info b
Num     Type           Disp Enb Address            What
3       breakpoint     keep y   0x00007ff619ac146e in main() at testOP.cpp:21
        breakpoint already hit 1 time
4       breakpoint     keep y   0x00007ff619ac145d in main() at testOP.cpp:20
(gdb) disable b
(gdb) info b   
Num     Type           Disp Enb Address            What
3       breakpoint     keep n   0x00007ff619ac146e in main() at testOP.cpp:21
        breakpoint already hit 1 time
4       breakpoint     keep n   0x00007ff619ac145d in main() at testOP.cpp:20

enable b 使所有断点有效

(gdb) enable b
(gdb) info b  
Num     Type           Disp Enb Address            What
3       breakpoint     keep y   0x00007ff619ac146e in main() at testOP.cpp:21
        breakpoint already hit 1 time
4       breakpoint     keep y   0x00007ff619ac145d in main() at testOP.cpp:20

disable b 编号使一个断点无效
enable b 编号使一个断点有效

指定行号跳转

until 行号 进行指定位置跳转,执行完区间代码

(gdb) b 20
Breakpoint 5 at 0x7ff619ac145d: file testOP.cpp, line 20.
(gdb) r
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 25504.0x5ab0]
[New Thread 25504.0x559c]
[New Thread 25504.0x550c]

Thread 1 hit Breakpoint 5, main () at testOP.cpp:20
20          S s1{1};
2: s1 = {num = 0}
(gdb) until 22
main () at testOP.cpp:22
22          cout << (s1 == s2) << endl;
2: s1 = {num = 1}

这里直接一路执行到代码的22行

结束函数

finish 在一个函数内部,执行到当前函数返回

(gdb) r
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 17196.0x1850]
[New Thread 17196.0x2fbc]
[New Thread 17196.0x3ab0]

Thread 1 hit Breakpoint 5, main () at testOP.cpp:20
20          S s1{1};
2: s1 = {num = 0}
(gdb) s
S::S (this=0x5ffecc, num=1) at testOP.cpp:8
8           S(int num) : num(num) {};
(gdb) finish
Run till exit from #0  S::S (this=0x5ffecc, num=1) at testOP.cpp:8
main () at testOP.cpp:21
21          S s2{1};
2: s1 = {num = 1}

使用step步进到构造函数中,finish直接跳出函数。

跳转到下一个断点

c 从一个断点处,直接运行至下一个断点处

(gdb) r
Starting program: D:\Codes\leetcode\3133\test.exe 
[New Thread 2180.0x227c]
[New Thread 2180.0x55c4]
[New Thread 2180.0x6080]

Thread 1 hit Breakpoint 5, main () at testOP.cpp:20
20          S s1{1};
2: s1 = {num = 0}
(gdb) c
Continuing.

Thread 1 hit Breakpoint 6, main () at testOP.cpp:21
21          S s2{1};
2: s1 = {num = 1}

gdb在20行命中第一个断点,然后我们直接跳到21行下一个断点。


http://www.kler.cn/a/549869.html

相关文章:

  • Matlab自学笔记四十七:如何把日期时间型数据作为横坐标进行绘图
  • 数据结构——顺序表与链表
  • 【第1章:深度学习概览——1.3 深度学习的核心组件与概念解析之神经网络基础】
  • 麒麟v10 server版安装ollama跑Deepseek
  • React的内部机制详解
  • 【Flink快速入门-5.流处理之多流转换算子】
  • 【Python的FastAPI 与 Uvicorn】快速启动你StableDiffusion模型Web 应用
  • 相机功耗问题常用的拆解手法
  • 使用 Python 爬虫获取微店商品详情 API 接口数据
  • uniapp中实现国际化
  • 对界面简单易用封装SDK
  • QT基础二、信号和槽
  • LeetCode 热门100题-和为 K 的子数组-错题
  • 国家超算平台上线DeepSeek - R1系列模型:开启AI新征程
  • [JVM篇]虚拟机性能监控、故障处理工具
  • WEB安全--SQL注入--PDO与绕过
  • 用deepseek学大模型04-模型可视化与数据可视化
  • 破解微服务疑难杂症:2025年全解决方案
  • CSS flex布局 列表单个元素点击 本行下插入详情独占一行
  • 数据结构笔记之时间复杂度O(n)中的O是什么的缩写,为什么要用O这个字母?