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

Linux系统篇,开发工具(六):文件的编译配置、调试的理解、cgdb和gdb的操作使用

系列文章目录

第三章 开发工具的认识与使用


文章目录

  • 系列文章目录
    • @[TOC](文章目录)
  • 前言
  • 一、文件的编译
    • 1.1 debug 配置
    • 1.2 release 配置
  • 二、Linux 文件调试
  • 三、程序调试器gdb
    • 3.1 认识gdb
    • 3.2 cgdb的使用
      • 3.2.1 基本操作
      • 3.2.2 断点和运行操作
        • 3.2.2.1 断点信息
        • 3.2.2.2 断点操作
        • 3.2.2.3 运行操作
        • 3.2.2.4 其他操作
  • 四、gdb的调试技巧
    • 4.1 watch 监视变量变化
    • 4.2 set var 修改运行时变量
    • 4.3 条件断点
      • 4.3.1 新建条件断点
      • 4.3.2 断点新增条件
    • 4.4 分屏操作
  • 总结

前言

在Linux当中,我们也会遇到代码中的bug,那此时我们就渴望像vs当中一样可以对代码进行调试,因此本节我们就来学习在Linux当中代码的调试工具的使用——gdb。


一、文件的编译

文件源码编译成可执行文件的过程中,可以分为两种编译模式:debug模式和release模式,因此形成的不同文件也就具有对应的特点。

1.1 debug 配置

debug配置是编译器的一套编译规则,由该配置产出的文件可以进行调试,常用于开发中的测试,它决定了该文件在编译过程中细节的处理:

  • 定义:Debug 配置编译的程序,包含完整的符号调试信息,不启用代码优化
  • 作用:专门给开发者写代码、找 bug、测试功能用的模式
  • 特点:
  1. 不做代码优化:在该配置下形成的程序在执行时,不会进行优化代码(即对代码的增删改操作,如:省略中间变量)
  2. 保留完整调试信息:编译时会把变量名、函数名、代码行号、注释关联信息全部打包进 exe(调试符号)
  3. 内存检查宽松:一些轻微内存错误(比如越界、野指针)Debug 能勉强运行,Release 直接崩溃

1.2 release 配置

该配置为开发后发布客户端所使用的,它有着以下的细节:

  • 定义:Release 配置编译的程序,启用完整代码优化,不包含调试符号信息;如需事后调试,可单独生成 .pdb 调试文件
  • 作用:代码完全写完、无 bug 后,打包给别人运行、作业提交、软件发布用的模式
  • 特点:
  1. 度代码优化(编译器自动提速):编译器会自动:删除没用的代码、变量合并重复逻辑精简运算步骤调整代码顺序,提升运行速度
  2. 删除全部调试信息:去掉变量名、行号、断点信息,无法调试,只能直接运行
  3. 内存检查严格:Debug 能运行的轻微 bug,Release 会直接闪退、崩溃,因为优化会暴露内存问题

二、Linux 文件调试

就如同上述所说的文件只有通过debug配置编译,才能对代码进行调试。而Linux中编译而成的文件默认是release 版本本质是gcc 和 g++ 编译时默认选择的是该配置。想要配置为debug版本就需要通过选项改变:

gcc mycmd.c -o mycmd-g通过该选项实现编译成可调试文件

而文件调制的本质无非三点:

  • 找到问题:通过断点将代码分块,以块为单位快速排查问题
  • 查看代码上下文:在找到问题后,对代码块的代码详细运行查看(分为逐语句和逐过程),当然还可以使用监视窗口查看变量的变化
  • 解决问题:根据所学知识,修改和优化问题代码

通过以上调试的过程,成功实现问题的查找和解决。


三、程序调试器gdb

3.1 认识gdb

GDB:是一款用于调试可执行程序的调试器工具

直接使用命令gdb 可执行文件来调试文件,进入调试界面是这样的情况:

我们就可以通过在此处进行对文件的调试,可以实现初步的调试功能:打断点、单行运行、过程运行等,但是这样我们都无法看到现在执行的代码和运行的情况,因此我们推荐使用cgdb这个工具,是gdb的加强升级版,使用方式为:cgdb 可执行文件(不是系统自带,需要安装)

centos:sudo yum install -y cgdb
ubuntu:sudo apt-get install -y cgdb

通过cgdb,我们就能在调试时看到代码和运行到的进程了。

3.2 cgdb的使用

Linux作为命令行操作,它的应用程序也离不开命令行,所以让我们来学习下cgdb的命令使用。

3.2.1 基本操作

基本操作涉及cgdb的进入、退出等不涉及具体使用的操作

编号命令作用
1cgdb 可执行文件(debug)进入cgdb界面
2quit退出cgdb
3list / l 源代码显示文件的源代码(后加:数字从代码第几行开始显示)

3.2.2 断点和运行操作

调式的实现离不开断点的使用,以及运行方法。通过合适的断点分块和判断运行过程还是语句,实现问题的查找

3.2.2.1 断点信息

断点就是你让程序停下来的标记,是调试(cgdb/gdb)最核心的功能。

当然系统为了区分不同的断点,给断点设置了不同的信息,我们使用命令info b进行查看:

让我们先来认识以下断点信息都有哪些:

  • Num:断点编号,每个断点都有自己的编号,并且编号是逐渐递增的,即使删除1号,新增也是4号(不退出情况)
  • Type:断点类型,断点分为五个类型,常用为:breakpoint(普通断点)、watchpoint(观察断点)
  • Disp:断点存活方式:keep= 永久有效,不会自动删除,还有tbreak(临时断点)
  • Enb:是否启用:y= 启用n= 禁用
  • Address:内存地址(代码在内存里的位置,不用管)
  • What:断点位置:哪个文件、第几行、哪个函数

下面会对某些信息做详细解释。

3.2.2.2 断点操作
编号命令作用
1b / break 数字在该程序的第几行打断点
b 文件:行号在对应的文件行打断点
b 文件:函数在对应的文件该函数处打断点
2info b查看断点信息
3d 断点编号删除相应编号的断点
4disable / enable 断点编号禁用 / 启用 对应的断点编号
3.2.2.3 运行操作
编号命令作用
1run / r运行程序,直到遇到断点或程序结束
2next / n逐过程运行,将函数调用视为一个整体步骤执行(例如:直接执行完整个函数,不进入其内部)
3step / s逐语句运行,gdb记录最新的一条输入语句
4finsh直接执行完当前函数
5c直接由上一断点运行到下一断点
6until 行号快速执行到第几行
3.2.2.4 其他操作

我们来讲解以下除了以上调试功能外的常用其他操作:

  • bt:查看代码的调用栈

    我们会遇到这样一个情况:在函数调用返回值的时候需要使用两次n才能运行到下一行。这是因为返回值是函数的一个临时变量,需要mov操作将该变量赋值给变量,所以使用函数赋值做了两件事:callq 和 mov

  • p:查看变量的值
    在调试过程中,查看当前的变量存储的数据值。还可以充当临时计算的工具

  • display / undisplay:加入 / 删除 监视变量
    通过常显示来显示每一步变量的变化情况,便于查看代码上下文

  • info locals:查看现在执行代码块中的临时变量及变量的值


四、gdb的调试技巧

4.1 watch 监视变量变化

在display的监视功能的基础上,新增了变量的变化信息:当变量存储数据改变时列出新老数据

  • 用法:watch + 变量新增监视变量;d + 变量删除监视变量
  • 功能:如果你有⼀些变量不应该修改,但是你怀疑它修改导致了问题,你可以watch它,如果变化了,就会通知你

4.2 set var 修改运行时变量

我们常常会遇到发现变量异常,此时我们需要退出调试并重新设值再次运行,才能继续。而set var这个命令就可以在运行时直接修改变量

  • 用法:set var flag = 1修改运行程序中的变量
  • 功能:不用改代码、不用重新编译,直接在命令行改变量的值。

4.3 条件断点

4.3.1 新建条件断点

创建一个带有条件实现的断点,实现如:达到目标循环次数时停止运行

  • 用法:b 行号 条件:满足条件时触发断点。(如:b 6 if i == 8

4.3.2 断点新增条件

为已有的断点新增运行条件

  • 用法:condition 断点编号 条件:为已存断点新增满足条件。(如:condition 6 if i == 8

4.4 分屏操作

cgdb还可以通过Esc分屏进入到代码文件当中操作,i从代码屏回到调试窗口。


总结

本章的开发工具到本节就结束了,下一章我们将学习到Linux底层的东西,感谢您的阅读,期待下一次的学习。

http://www.gsyq.cn/news/1375369.html

相关文章:

  • 基于对比学习的机器遗忘框架CoUn:原理、实现与调优指南
  • 基于Intel Xe GPU与SYCL的AI模型完整性验证框架设计与实现
  • ML系统可持续性工程实践:从能耗优化到全生命周期管理
  • 告别Alt+F4秒退!在UE4/UE5中实现窗口事件监听的三种方法全评测
  • MyBatis 与 MySQL 执行流程
  • 从spring到spring boot——JAVA项目开发
  • UE4项目实战:用两个Widget组件搞定3DUI穿模问题(附蓝图与材质设置)
  • 2026年4月惠州知名的设备运输服务商推荐,精密设备搬迁/工厂设备搬运/设备安装搬迁/平台吊装,设备运输一站式服务哪家好 - 品牌推荐师
  • Armv9 SME指令集:FMLS与FMLSL浮点运算优化
  • 跨VM RowHammer攻击防御技术与DRAM安全研究
  • LLM推理解耦技术:提升大型语言模型推理效率的关键方法
  • BFloat16与SME2指令集在AI加速中的应用
  • 亚秒级计时电流法在室温离子液体中的突破应用
  • Mysql:事务管理(上)
  • 基于机器学习的癫痫发作检测与预测:从EEG信号处理到LSTM时序建模
  • 告别瞎猜!用DBSCAN和K-means搞定毫米波雷达点云聚类,附完整Matlab代码与数据集
  • 基于退火序贯蒙特卡洛的符号回归:从高维物理数据中自动发现多项式约束
  • 纯前端到底要不要学 Java
  • Unity新手避坑指南:从预制体变体到导航网格,这些基础概念别再搞混了
  • CentOS 7最小化安装后,复制粘贴和网络配置的保姆级教程(附图形界面切换)
  • DYNAMIX:基于强化学习的动态批处理优化,破解分布式训练效率与精度困局
  • 手把手教你用Linux命令‘偷看’UEFI启动日志,排查系统启动失败问题
  • 企业IT必看:如何用Chrome企业版MSI配合组策略,实现全网电脑静默部署
  • 流式处理与可解释AI:构建实时电竞胜率预测系统的核心技术
  • GB5768.3钻牛角尖的几点
  • 别再只会用Set-ExecutionPolicy了!深入理解Windows PowerShell的四种执行策略与安全实践
  • ARM SVE架构WHILEGT指令详解与应用优化
  • Ubuntu 22.04下gcc安装报错?手把手教你用apt-get指定版本解决cpp依赖冲突
  • 不止于播放:用Unity Video Player的RenderTexture模式,轻松实现游戏内电视、监控屏效果
  • 2026年智己LS8与问界M7深度分析:家庭增程SUV场景的配置与性能代差困境 - 品牌推荐