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

【Linux】调试器gdb/cgdb的使用

        Linux下我们编译好的代码是无法直接进行调试的,gcc/g++的默认工作模式是release模式,gdb是一个调试器,本篇将介绍一下它的使用。

1.快速认识gdb

要使⽤gdb调试,必须在源代码⽣成⼆进制程序的时候(编译时), 加上 -g 选项,让生成的可执行程序添加调试信息,也可就是让代码处于debug模式
  •  readelf -S 可执行程序 | grep -i debug:查看可执行程序是有debug信息
我们的Makefile可以完善一下。
//Makefile文件
SRC=$(wildcard *.c)
OBJ=$(SRC:.c=.o)
BIN=mycode$(BIN):$(OBJ)gcc -o $@ $^
%.o:%.cgcc -c $< -g  #加上-g选项.PHONY:clean
clean:rm -f $(OBJ) $(BIN)
  • gdb 可执行文件:进入gdb,gdb后面跟的是可执行程序,不是源文件!
  • quit:退出gdb

2.解决gdb难用问题

我们直接使用cgdb,用命令安装

Ubuntu环境:sudo apt-get install cgdb

安装好之后我们再打开cgdb。

cgdb有分屏,是上面是代码屏,下面是调试信息屏,它的界面就清楚很多。

  • 按ESC可以进入代码屏,但是可能会卡死!
  • 如果不小心导致页面卡死了,按i光标就能回退到下面调试信息处。

3.gdb/cgdb相关指令

cgdb的指令和gdb的指令是一样的,下面我就用cgdb演示,演示的代码如下:

#include <stdio.h>
int Sum(int s, int e)
{int result = 0;for(int i = s; i <= e; i++){result += i;}return result;
}
int main()
{int start = 1;int end = 100;printf("begin...\n");int n = Sum(start, end);printf("running done, result is: [%d-%d]=%d\n", start, end, n);return 0;
}

3.1 常见使用

  • l:list,查看源代码,按回车就会往后显示,每次显示10行
  • r:run,从头运行,会在遇到的第一个断点处停下来,没有断点就直接运行到结束

在gdb中会记录最新的那条指令,只要按回车就会执行最新的那条语句

3.1.1 断点

  • b n:break,在第n行打断点
  • b 函数名:在指定的函数入口处打断点
  • b 文件名:n:在指定文件的第n行打断点
  • b 文件名:函数名:在指定文件的指定函数入口处打断点
  • info b:查看所有断点

  • d 断点编号delete,删除断点
  • disable 断点编号:禁用断点,此断点仍存在
  • enable 断点编号:启用断点
  • ccontinue,运行到下一个断点

gdb不退出,断点编号依次递增

3.1.2 语句

  • n:next,逐过程
  • s:step,逐语句
  • finish:执⾏到当前函数返回然后停⽌
  • btbacktrace,查看当前执⾏的各级函数调⽤及参数
  • until n:执行到指定行

3.1.3 变量

  • p 变量名:查看指定的变量名,不能常显
  • p 表达式:可以查看一个表达式的值
  • display 变量名:跟踪显⽰指定变量的值,常显示

  • undisplay 变量名编号:取消跟踪显⽰指定变量

  • info locals:查看一个函数里所有的变量

3.2 常见技巧

3.2.1 watch

  • watch 变量或表达式:监视一个变量或表达式,如果这个变量或表达式在运行期间发生了变化,gdb会暂停运行并通知使用者,不会常显,有变化才会显示

比如说我们监视这个result变量,watch result之后会有一个watchpoint的断点,用指令info b就能查看这个断点类型和监视的对象

当程序往后执行,检测到这个变量的变化后就会显示出来,并且这个watch可以对这个变量进行新旧的对比

如果不想要这个断点,就用 d 断点编号 进行删除

常见应用场景:如果你有⼀些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它,如果变化了,就会通知你。

3.2.2 set var

  • set var 变量=新的值:我们在调试期间修改这个变量的值变成新的值,就不用退出gdb修改源代码来确定问题
比如这个求和函数,result的初始值应该是0,这里故意设置成1,设置成错的。
int Sum(int s, int e)
{//int result = 0;int result = 1; //设置错误for(int i = s; i <= e; i++){result += i;}return result;
}

在我们调试的时候发现这个地方写错了,可直接用set var result=0进行值的暂时修改

但是这个操作不会修改源代码,发现问题知道错在哪后,还是要对源代码修改。

3.2.3 条件断点

  • b n if 条件:当条件成立的时候在第n行设置断点

比如在求和函数循环体内,当i为20的时候打个断点。

  • condition 断点编号 条件:给已存在的断点添加条件,断点已存在不用加if

注意两者的语法有区别,不要写错了!

这个断点可以搭配指令c一起用,我们刚刚打了一个条件断点,当i==20时触发断点,按c就会直接跳到这个地方

本次分享就到这里了,我们下篇再见~

http://www.lryc.cn/news/612151.html

相关文章:

  • 信号处理:信号产生
  • 张艺兴续约担任传音手机全球品牌代言人 携手共启创新征程
  • 企业级DDoS防护实战案例
  • 数字取证和网络安全:了解两者的交叉点和重要性
  • 什么是 Kafka 中的消息?它由哪些部分组成
  • 《设计模式之禅》笔记摘录 - 13.迭代器模式
  • JP3-4-MyClub后台前端(二)
  • leetcode 3479. 水果成篮 III 中等
  • 多端同步新解法:Joplin+cpolar联合通过开源设计实现跨平台无缝协作?
  • 【学习笔记之redis】删除缓存
  • vue3 el-select el-option 使用
  • 学习嵌入式之硬件——ARM体系
  • CubeFS存储(一)
  • 【前端开发】四. JS内置函数
  • [特殊字符]企业游学 | 探秘字节,解锁AI科技新密码
  • 【Linux】重生之从零开始学习运维之主从MGR高可用
  • 无人机航拍数据集|第6期 无人机垃圾目标检测YOLO数据集772张yolov11/yolov8/yolov5可训练
  • 【python】OpenCV—Defect Detection
  • AI浪潮下,FPGA如何实现自我重塑与行业变革
  • 深度模拟用户行为:用Playwright爬取B站弹幕与评论数据
  • 2025年高防IP隐身术:四层架构拆解源站IP“消失之谜”
  • 微算法科技(NASDAQ:MLGO)利用鸽群分散算法,提高区块链交易匹配算法效能
  • Kafka ISR机制和Raft区别:副本数优化的秘密
  • 智能提示词引擎的革新与应用:PromptPilot使用全解析
  • 北京JAVA基础面试30天打卡03
  • PDF注释的加载和保存的实现
  • Go语言数据类型深度解析:位、字节与进制
  • Git 乱码文件处理全流程指南:从识别到彻底清除
  • NodeJs学习日志(1):windows安装使用node.js 安装express,suquelize,sqlite,nodemon
  • 将英文PDF文件完整地翻译成中文的4类方式