Linux 调试代码工具:gdb

文章目录

  • 一、debug vs release:两种程序形态的本质差异
    • 1. 什么是 debug 与 release?
    • 2. 核心差异对比
  • 二、为什么需要 debug:从项目生命周期看调试价值
    • 1. 项目开发流程中的调试闭环(流程图示意)
    • 2. Debug 的核心意义与目的
  • 三、gdb 的使用🔑
    • 1. 编译阶段:gcc/g++ -g
      • (1)gcc/g++ 的 debug 编译选项
      • (2)验证调试信息是否正确生成
    • 2. gdb 调试入门:从启动到核心命令使用
      • (1)启动调试会话:gdb [可执行程序]
      • (2)核心调试命令速查表📝
      • (3)🔴断点 Break Point:b
        • 🚀基础断点:按行号或函数快速暂停
        • 🧠条件断点:动态过滤无效暂停
        • 📑查看断点列表:info break
        • 🛑禁用 / ✅启用断点:disable/enable [编号]
        • 🗑️删除断点:delete [编号]


一、debug vs release:两种程序形态的本质差异

1. 什么是 debug 与 release?

  • Debug 版本(调试版):
    编译器在构建时保留符号表、调试信息(变量名、函数名、行号等)
    禁用或减少代码优化(默认优化级别 -O0)
    包含额外调试辅助代码(如断言 assert、边界检查)
    目标:为开发者提供完整的调试上下文
  • Release 版本(发布版):
    剥离符号表与调试信息(可通过 strip 进一步精简)
    启用深度优化(默认优化级别 -O2,追求执行效率)
    移除调试辅助代码,压缩体积并提升运行性能
    目标:提供给用户的最终交付形态

2. 核心差异对比

特性Debug 版本Release 版本
编译选项-g(生成调试信息)、-O0(无优化)-O2(默认优化)、-s(剥离符号)
符号表完整保留(函数名、变量名、行号)仅保留必要符号(用于动态链接)
文件体积较大(调试信息占比可达 50%+)较小(优化后代码更紧凑)
执行效率慢(无优化且含调试辅助代码)快(指令重排、循环展开等优化)
调试支持完全支持(GDB 精准定位到源码行)仅支持有限调试(需手动加载符号表)
典型用途开发阶段调试、单元测试生产环境部署、用户交付

二、为什么需要 debug:从项目生命周期看调试价值

1. 项目开发流程中的调试闭环(流程图示意)

自测通过
自测不通过
测试通过
测试发现问题
立项
开发
debug
release发布
开发自测release版
提交测试,测试团队验证release
上线
灰度内测
全量运营

关键反馈节点:
开发阶段:基于 Debug 版快速定位逻辑错误(如空指针、数组越界)
自测阶段:用 Release 版验证性能与资源占用(Debug 版的优化缺失可能掩盖真实问题)
测试阶段:通过核心转储(Core Dump)分析生产环境 Crash 时,需依赖 Debug 符号表

2. Debug 的核心意义与目的

  • 精准定位问题根源

  • 验证程序逻辑正确性:调试器支持单步执行(step)、条件断点(break if i>100),允许开发者逐行验证分支逻辑、循环

  • 优化代码可读性与可维护性:debug 阶段暴露的问题(如复杂函数逻辑)促使开发者重构代码,间接提升代码质量;断言(assert())在 Debug 版生效,强制检查前置条件(如指针非空),提前暴露潜在风险

  • 衔接测试与生产环境


三、gdb 的使用🔑

1. 编译阶段:gcc/g++ -g

(1)gcc/g++ 的 debug 编译选项

# 基础调试配置(必备)  
gcc -g -o debug_program source.c    # C语言编译  
g++ -g -o debug_program source.cpp  # C++语言编译  

🚨注意:默认情况下(不加 -g),gcc/g++ 生成 release 版

(2)验证调试信息是否正确生成

# 检查符号表(含函数名/变量名)  
nm debug_program | grep main            # 应显示main函数地址与符号名  # 对比Release版(无符号表时仅显示地址)  
nm release_program | grep main          # 可能显示 T 0x400550(无符号名)  

2. gdb 调试入门:从启动到核心命令使用

(1)启动调试会话:gdb [可执行程序]

gdb debug_program    # 调试可执行文件  

(2)核心调试命令速查表📝

命令全称功能描述示例
llist显示源码(默认 10 行,可指定行号 / 函数名)l 50 显示第 50 行附近代码;l main 显示 main 函数
bbreak设置断点(行号 / 函数名 / 条件表达式)b 100 在第 100 行设断点;b myfunc if x>10 条件断点
rrun运行程序(可带参数)r input.txt 以 input.txt 为参数运行程序
nnext逐过程,单步执行(跳过函数调用)在调用函数时,n 会直接执行完整个函数调用
sstep逐语句,单步执行(进入函数内部)调试自定义函数时,s 会进入函数第一行
pprint打印变量 / 表达式值p *ptr 打印指针指向的值;p arr[5] 打印数组元素
display-自动显示变量(程序暂停时更新)display i 每次暂停时显示变量 i 的值
undisplay-取消自动显示undisplay 1 取消第 1 号自动显示项(info display查看编号)
btbacktrace查看调用栈(定位函数调用顺序)段错误时执行bt,快速定位出错函数
qquit退出调试q 退出 gdb 会话
set varset variable动态修改变量值(在调试过程中临时赋值,影响程序运行逻辑)set var i=10 将变量 i 的值强制设为 10;set *ptr=0x1234 修改指针指向的内存值
finish-继续运行直到当前函数返回(跳出当前函数,查看返回值)step 进入子函数后,执行 finish 直接运行到函数返回并停在调用行

gdb 内置命令历史机制,可自动记录最近执行的命令,在完成一条命令后直接按下回车键,即可快速重复执行上一条命令。

示例:

(gdb) next  # 第一次输入next命令,单步执行程序  
Breakpoint 1, main () at test.c:10  
10          int x = 5;  
(gdb)       # 直接回车,重复执行上一条命令(next)  
11          x += 3;  
(gdb)       # 再次回车,继续重复执行next  
12          printf("x = %d\n", x);  

(3)🔴断点 Break Point:b

bbreak 命令的缩写,是 gdb 中 设置断点(Breakpoint) 的核心指令。

🚀基础断点:按行号或函数快速暂停

行号断点:最直接的位置标记
语法:b [行号] 或 break [行号]
作用:在当前文件的指定源码行号处设置断点,程序运行到该行时暂停。

(gdb) b 100          # 在当前文件第100行设置断点  
(gdb) break test.c:50 # 在test.c文件的第50行设置断点(跨文件指定)

函数断点:按逻辑单元定位
语法:b [函数名] 或 break [函数名]
作用:在函数入口处设置断点,包括自定义函数、库函数或系统调用。

(gdb) b main         # 在程序入口main函数处设置断点(程序启动后首次暂停)  
(gdb) break printf    # 在调用标准库函数printf时暂停(需保留符号表)  
(gdb) b mymodule.c:myfunc # 在mymodule.c文件的myfunc函数入口处暂停  

优势:无需关心具体行号,直接按函数边界控制执行流,适合模块化调试(如快速定位某个功能函数的逻辑起点)。

🧠条件断点:动态过滤无效暂停

语法:b [行号或函数名] if [条件表达式]
作用:仅当条件表达式为真时,断点才生效(避免每次执行到断点都暂停,提升调试效率)。

(gdb) b 200 if i==100 # 当循环变量i等于100时,在第200行暂停(跳过前99次循环)  
(gdb) break myfunc if *ptr==NULL # 当指针ptr为空时,在myfunc函数入口暂停(定位空指针异常)  
📑查看断点列表:info break
(gdb) info break  
Num     Type           Disp Enb Address            What  
1       breakpoint     keep y   0x00000000004005a3 in main at test.c:10  
2       watchpoint     keep y   0x00007fffffffde40 array[5]  
  • Num:断点编号(删除 / 禁用时需指定此编号)。
  • Type:断点类型(breakpoint/watchpoint/hbreakpoint)。
  • Enb:是否启用(y 启用,n 禁用)。
  • Disp:断点持续性(keep 持续生效,del 触发一次后删除)。
🛑禁用 / ✅启用断点:disable/enable [编号]
(gdb) disable 2      # 禁用编号为2的内存断点(暂时忽略,保留配置)  
(gdb) enable 1       # 重新启用编号为1的行断点(无需重新设置条件)  
🗑️删除断点:delete [编号]

ps.命令缩写:d [编号]

(gdb) delete 1       # 删除编号为1的行断点  
(gdb) delete         # 删除所有断点(需确认提示)  
(gdb) d <断点编号>        # 例:d 3 (等价于 delete 3)  
(gdb) delete            # 不加编号时,🔴删除所有断点(谨慎使用!)  

断点编号的「线性增长」特性
GDB 内部维护一个 全局唯一的断点编号计数器,具备以下特性:

  • 编号永不重复:
    每个断点(包括行断点、函数断点、观察点等)被创建时,编号按创建顺序依次递增,与是否删除无关。
    例:依次创建 3 个断点,编号为 1、2、3;
    删除编号 2 后,新创建的断点编号为 4(而非复用 2)。
  • 删除不影响后续编号:
    即使中间编号的断点被删除,新断点的编号仍从 当前最大编号 +1 继续生成。
    例:
(gdb) break main.c:10   # 断点1  
(gdb) break main.c:20   # 断点2  
(gdb) delete 2          # 删除断点2  
(gdb) break main.c:30   # 新断点编号为3(而非2)  
(gdb) info breakpoints  
# 输出:Num 1, 3(断点2已删除)  

END

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/76815.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python设计模式:命令模式

1. 什么是命令模式&#xff1f; 命令模式是一种行为设计模式&#xff0c;它将请求封装为一个对象&#xff0c;从而使您能够使用不同的请求、队列或日志请求&#xff0c;以及支持可撤销操作。 命令模式的核心思想是将请求的发送者与请求的接收者解耦&#xff0c;使得两者之间的…

nlp面试重点

深度学习基本原理&#xff1a;梯度下降公式&#xff0c;将损失函数越来越小&#xff0c;最终预测值和实际值误差比较小。 交叉熵&#xff1a;-p(x)logq(x)&#xff0c;p(x)是one-hot形式。如果不使用softmax计算交叉熵&#xff0c;是不行的。损失函数可能会非常大&#xff0c;…

Leetcode:二叉树

94. 二叉树的中序遍历 class Solution {public List<Integer> inorderTraversal(TreeNode root) {TreeNode cur root;Stack<TreeNode> stack new Stack<>();List<Integer> list new ArrayList<>();while (!stack.isEmpty() || cur ! null) {…

SQL:Constraint(约束)

目录 &#x1f3af; 什么是 Constraint&#xff1f; MySQL 中常见的约束类型&#xff1a; 1. PRIMARY KEY 2. FOREIGN KEY 3. UNIQUE 4. NOT NULL 5. DEFAULT 6. CHECK&#xff08;MySQL 8.0&#xff09; 7. AUTO_INCREMENT &#x1f3af; 什么是 Constraint&#xf…

数据库数据恢复——sql server数据库被加密怎么恢复数据?

SQL server数据库数据故障&#xff1a; SQL server数据库被加密&#xff0c;无法使用。 数据库MDF、LDF、log日志文件名字被篡改。 数据库备份被加密&#xff0c;文件名字被篡改。 SQL server数据库数据恢复过程&#xff1a; 1、将所有数据库做完整只读备份。后续所有数据恢…

MySQL 用 limit 影响性能的优化方案

一.使用索引覆盖扫描 如果我们只需要查询部分字段&#xff0c;而不是所有字段&#xff0c;我们可以尝试使用索引覆盖扫描&#xff0c;也就是让查询所需的所有字段都在索引中&#xff0c;这样就不需要再访问数据页&#xff0c;减少了随机 I/O 操作。 例如&#xff0c;如果我们…

【算法笔记】并查集详解

&#x1f680; 并查集&#xff08;Union-Find&#xff09;详解&#xff1a;原理、实现与优化 并查集&#xff08;Union-Find&#xff09;是一种非常高效的数据结构&#xff0c;用于处理动态连通性问题&#xff0c;即判断若干个元素是否属于同一个集合&#xff0c;并支持集合合…

鸿蒙HarmonyOS埋点SDK,ClkLog适配鸿蒙埋点分析

ClkLog埋点分析系统&#xff0c;是一种全新的、开源的洞察方案&#xff0c;它能够帮助您捕捉每一个关键数据点&#xff0c;确保您的决策基于最准确的用户行为分析。技术人员可快速搭建私有的分析系统。 ClkLog鸿蒙埋点SDK通过手动埋点的方式实现HarmonyOS 原生应用的前端数据采…

JMeter的关联

关联&#xff1a;上一个请求的响应结果和下一个请求的数据有关系 xpath提取器 适用场景 HTML/XML文档结构化数据&#xff1a; 适用于从HTML或XML文档中提取结构化数据。例如&#xff0c;提取表格中的数据、列表中的项目等。示例&#xff1a;从HTML表格中提取所有行数据。 …

Spring Security 权限配置详解

&#x1f31f;Spring Security 权限配置详解&#xff1a;从基础到进阶 Spring Security 是一个功能强大、可高度自定义的安全框架&#xff0c;主要用于为基于 Spring 的应用程序提供身份验证和授权功能。 本篇文章将带你深入理解 Spring Security 的权限配置机制&#xff0c;掌…

pycharm中安装Charm-Crypto

一、安装依赖 1、安装gcc、make、perl sudo apt-get install gcc sudo apt-get install make sudo apt-get install perl #检查版本 gcc -v make -v perl -v 2、安装依赖库m4、flex、bison(如果前面安装过pypbc的话,应该已经装过这些包了) sudo apt-get update sudo apt…

【MCAL】AUTOSAR架构下基于SPI通信的驱动模块详解-以TJA1145为例

目录 前言 正文 1.TJA1145驱动代码中的SPI协议设计 1.1 对SPI Driver的依赖 1.2 对SPI配置的依赖 1.2.1 SpiExternalDevice 1.2.2 Channel_x 1.2.3 Job_x 1.2.4 Sequence N 1.2.5 Sequence M 1.2.6 Sequence L 1.2.7 小结 2.基于Vector驱动代码的SPI配置 2.1 SPI引…

JavaScript:BOM编程

今天我要介绍的是JS中有关于BOM编程的知识点内容&#xff1a;BOM编程&#xff1b; 介绍&#xff1a;BOM全名&#xff08;Browser Object Model&#xff08;浏览器对象模型&#xff09;&#xff09;。 是浏览器提供的与浏览器窗口交互的接口&#xff0c;其核心对象是 window。与…

Memcached缓存系统:从部署到实战应用指南

#作者&#xff1a;猎人 文章目录 一、安装libevent二、安装配置memcached三、安装Memcache的PHP扩展四、使用libmemcached的客户端工具五、Nginx整合memcached:六、php将会话保存至memcached Memcached是一款开源、高性能、分布式内存对象缓存系统&#xff0c;可应用各种需要缓…

解决前后端时区不一致问题

前后端时区不一致导致&#xff1a; 》数据不显示在前端 》页面显示时间有误 》一些对时间有要求的方法&#xff0c;无法正确执行&#xff0c;出现null值&#xff0c;加上我们对null值有判断/注解&#xff0c;程序就会报错中断&#xff0c;以为是业务逻辑问题&#xff0c;其实…

35.Java线程池(线程池概述、线程池的架构、线程池的种类与创建、线程池的底层原理、线程池的工作流程、线程池的拒绝策略、自定义线程池)

一、线程池概述 1、线程池的优势 线程池是一种线程使用模式&#xff0c;线程过多会带来调度开销&#xff0c;进而影响缓存局部性和整体性能&#xff0c;而线程池维护着多个线程&#xff0c;等待着监督管理者分配可并发执行的任务&#xff0c;这避免了在处理短时间任务时创建与…

驱动开发硬核特训 · Day 6 : 深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比

&#x1f50d; B站相应的视屏教程&#xff1a; &#x1f4cc; 内核&#xff1a;博文视频 - 从静态绑定驱动模型到现代设备模型 主题&#xff1a;深入解析设备模型的数据流与匹配机制 —— 以 i.MX8M 与树莓派为例的实战对比 在上一节中&#xff0c;我们从驱动框架的历史演进出…

Blender安装基础使用教程

本博客记录安装Blender和基础使用&#xff0c;可以按如下操作来绘制标靶场景、道路标识牌等。 目录 1.安装Blender 2.创建面板资源 步骤 1: 设置 Blender 场景 步骤 2: 创建一个平面 步骤 3: 将 PDF 转换为图像 步骤 4-方法1: 添加材质并贴图 步骤4-方法2&#xff1a;创…

智能手机功耗测试

随着智能手机发展,用户体验对手机的续航功耗要求越来越高。需要对手机进行功耗测试及分解优化,将手机的性能与功耗平衡。低功耗技术推动了手机的用户体验。手机功耗测试可以采用powermonitor或者NI仪表在功耗版上进行测试与优化。作为一个多功能的智能终端,手机的功耗组成极…

从代码学习深度学习 - 多头注意力 PyTorch 版

文章目录 前言一、多头注意力机制介绍1.1 工作原理1.2 优势1.3 代码实现概述二、代码解析2.1 导入依赖序列掩码函数2.2 掩码 Softmax 函数2.3 缩放点积注意力2.4 张量转换函数2.5 多头注意力模块2.6 测试代码总结前言 在深度学习领域,注意力机制(Attention Mechanism)是自然…