【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行打一个断点:

css 复制代码
Thread 1 hit Breakpoint 1, main () at testOP.cpp:21
21          S s2{1};

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

ini 复制代码
(gdb) p s2
$1 = {num = 8}

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

ini 复制代码
(gdb) n
22          cout << (s1 == s2) << endl;
(gdb) p s2
$7 = {num = 1}

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

ini 复制代码
(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(前面那个数字)

ini 复制代码
(gdb) n
22          cout << (s1 == s2) << endl;
1: s1 = {num = 1}
(gdb) undisplay 1
(gdb) n
1
23      }

打印函数堆栈

bt可以打印函数的堆栈

dart 复制代码
(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 变量名=值对变量进行赋值

ini 复制代码
(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使所有断点无效

less 复制代码
(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 使所有断点有效

less 复制代码
(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 行号 进行指定位置跳转,执行完区间代码

ini 复制代码
(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 在一个函数内部,执行到当前函数返回

ini 复制代码
(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 从一个断点处,直接运行至下一个断点处

ini 复制代码
(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行下一个断点。

本文使用 markdown.com.cn 排版

相关推荐
Once_day34 分钟前
C++之fmt库介绍和使用(1)
开发语言·c++·fmt
是店小二呀37 分钟前
【优选算法 | 字符串】字符串模拟题精选:思维+实现解析
android·c++·算法
不爱学英文的码字机器1 小时前
[操作系统] 策略模式进行日志模块设计
c++·策略模式
凤年徐1 小时前
【C/C++】自定义类型:结构体
c语言·开发语言·c++·经验分享·笔记·算法
DARLING Zero two♡1 小时前
C++效率掌握之STL库:map && set底层剖析及迭代器万字详解
c++·stl·set·map
绯樱殇雪1 小时前
编程题 02-线性结构3 Reversing Linked List【PAT】
c++·pat考试
Rachelhi2 小时前
C++.神经网络与深度学习(赶工版)(会二次修改)
c++·深度学习·神经网络
理论最高的吻2 小时前
77. 组合【 力扣(LeetCode) 】
c++·算法·leetcode·深度优先·剪枝·回溯法
zyx没烦恼2 小时前
unordered_map和unordered的介绍和使用
开发语言·c++
LuckyRich13 小时前
【RabbitMq C++】消息队列组件
c++·分布式·rabbitmq