当前位置: 首页 > 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.dtcms.com/a/317850.html

相关文章:

  • 生成式 AI 重塑自动驾驶仿真:4D 场景生成技术的突破与实践
  • vector使用模拟实现
  • 牛客AI简历筛选:破解秋招效率难题
  • 向量数据库基础入门:RAG 与向量检索基础认知构建
  • 《C语言程序设计》笔记p9
  • LLM——浅谈 LangGraph 中断式工作流:构建一个可交互的问答流程
  • 4、docker数据卷管理命令 | docker volume
  • 【关于Java的对象】
  • vue3 el-dialog自定义实现拖拽、限制视口范围增加了拖拽位置持久化的功能
  • 实战教程:从“对象文件为空“到仓库重生——修复 Git 仓库损坏全记录
  • 大数据存储域——Hive数据仓库工具
  • STM32 APP跳转后无法进入中断
  • QT----不同线程中信号发送了槽函数没反应QObject::connect: Cannot queue arguments of typeXXX
  • C++编程语言:标准库:工具类(Bjarne Stroustrup)
  • Python赋能气象与气候数据分析的生态构建与实战路径
  • Linux中systemd与systemctl管理指南
  • LlaMA_Factory实战微调VL大模型
  • 【数据分享】西藏土壤类型数据库
  • AlphaEarth模型架构梳理及借鉴哪些深度学习领域方面的思想
  • [AI 生成] Spark 面试题
  • 【深度学习】Graph Transformer Networks(GTN,图变换网络)
  • Linux 中 Git 操作大全
  • 测试单节点elasticsearch配置存储压缩后的比率
  • cacti
  • 深入理解C++中的stack、queue和priority_queue
  • 部署 Zabbix 企业级分布式监控笔记
  • C语言高级编程技巧与最佳实践
  • 学习bug
  • R4周打卡——Pytorch实现 LSTM火灾预测
  • 人工智能——深度学习——认识Tensor