当前位置: 首页 > 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.xdnf.cn/news/1251145.html

相关文章:

  • 推荐一款优质的开源博客与内容管理系统
  • Android PDFBox 的使用指南
  • 【数据结构与算法】刷题篇——环形链表的约瑟夫问题
  • 8.6笔记
  • 93、【OS】【Nuttx】【构建】cmake menuconfig 目标
  • vxe-table表格编辑单元格,进行正则验证,不符合验证,清空单元格数据。
  • 【“连亏十年” 川机器人,启动科创板IPO辅导】
  • 短剧小程序系统开发:技术驱动下的内容创新之路
  • 后端服务oom
  • [linux] Linux系统中断机制详解及用户空间中断使用方法
  • Java技术栈/面试题合集(19)-架构设计篇
  • Android—服务+通知=>前台服务
  • 简单spring boot项目,之前练习的,现在好像没有达到效果
  • 攻防世界WEB(新手模式)20-unseping
  • Android14的QS面板的加载解析
  • Tesseract + Poppler 实现图片型 PDF 转文字
  • jmm 指令重排 缓存可见性 Volatile 内存屏障
  • Perforce P4 Plan - DevOps实时规划工具
  • Python day36
  • 基于单片机智能浇花/智能灌溉/智慧农业/智能大棚
  • 双馈和永磁风机构网型跟网型联合一次调频并入同步机电网,参与系统一次调频,虚拟惯量下垂,虚拟同步机VSG控制matlab/simulink
  • 【软考系统架构设计师备考笔记5】 - 专业英语
  • 【关于Java的泛型(基础)】
  • 《动手学深度学习》读书笔记—9.3深度循环神经网络
  • 阿里云 Flink
  • 第七章课后综合练习
  • SpringBoot 3.x整合Elasticsearch:从零搭建高性能搜索服务
  • 【网络基础】计算机网络发展背景及传输数据过程介绍
  • vue3 vite 使用vitest 单元测试 组件测试
  • Lesson 31 Success story