GDB 调试全方位指南:从入门到精通

在程序开发中,调试是定位和解决问题的核心环节。GDB (GNU Debugger) 作为一款功能强大的命令行调试器,是Linux环境下C/C++开发者的必备利器。本文将系统讲解GDB的使用方法,涵盖基础操作到高级技巧,助你高效排错。


一、基础准备:编译与启动

1. 程序发布模式与调试信息

  • Debug模式: 编译器保留完整调试信息(符号表、行号等),便于调试。程序体积较大,运行效率稍低。
  • Release模式: 编译器进行深度优化,去除调试信息,生成体积小、运行快的程序,不适合直接调试

关键点: 要使用GDB调试,编译时必须显式添加 -g 选项,生成包含调试信息的可执行文件。

gcc -g test.c -o test  # 编译包含调试信息的可执行程序 'test'
g++ -g myapp.cpp -o myapp # C++ 同理

2. 启动与退出 GDB

  • 启动: gdb <可执行文件名>
    gdb test  # 调试名为 'test' 的程序
    
  • 退出:
    • 输入命令:quitq
    • 快捷键:Ctrl + D

二、核心调试命令详解

1. 查看源代码 (list / l)

  • l [行号]: 从指定行号开始显示源代码(默认显示当前上下文10行)。
    • l 15: 显示第15行附近的代码。
    • 连续输入 l 或按 Enter 键继续向下显示。
  • l [函数名]: 显示指定函数的源代码。
    • l main: 显示 main 函数的代码。

2. 运行控制

命令缩写作用
runr开始/重新开始运行程序。遇到断点暂停,无断点则运行到结束。
nextn单步执行(不进入函数)。执行下一行代码,将函数调用当作一步执行完。
steps单步进入。执行下一行代码,进入被调用函数的内部。
continuec继续运行。从当前暂停处继续执行,直到遇到下一个断点或程序结束。
finishfin执行完当前函数。运行到当前函数返回,并暂停在调用该函数的位置。
until [行号]u运行到指定行。用于跳过循环或快速到达代码中的特定位置。

3. 断点管理 (break / b)

  • 设置断点:
    • b [行号]: 在指定行设置断点。b 20
    • b [函数名]: 在函数入口处设置断点。b calculate
  • 查看断点: info breakpoints (i b)
  • 删除断点:
    • delete [断点编号] (d [编号]): 删除指定编号断点。d 2
    • delete (d): 删除所有断点。
  • 禁用/启用断点:
    • disable [断点编号]: 禁用断点(断点存在但无效)。
    • enable [断点编号]: 启用被禁用的断点。

4. 变量操作

  • 查看值: print [变量名] (p [变量名])
    • p sum: 打印变量 sum 的当前值。
    • p &sum: 打印变量 sum 的地址。
    • p *ptr: 打印指针 ptr 指向的值。
  • 修改值: set var [变量名]=[值]
    • set var count=0: 将变量 count 设置为 0。
  • 自动显示:
    • display [变量名]: 每次程序暂停时自动显示该变量的值。
    • info display: 查看当前设置的所有自动显示项及其编号。
    • undisplay [编号]: 取消指定编号的自动显示。

5. 其他常用命令

  • backtrace (bt): 查看调用栈。显示当前执行位置及其调用路径(栈帧),极其重要!
  • frame [栈帧编号] (f [编号]): 切换栈帧。配合 bt 使用,查看不同函数调用层的上下文。
  • info locals (i locals): 查看当前栈帧的局部变量
  • info args (i args): 查看当前函数的参数值。

三、高级调试技巧

1. 多线程调试

  • info threads (i threads): 列出所有线程,显示线程ID、状态和当前执行位置。
  • thread [线程ID] (t [ID]): 切换到指定线程进行调试。t 3
  • thread apply [线程ID] [命令]: 对指定线程执行命令。
    • thread apply 3 bt: 查看线程3的调用栈。
  • thread apply all [命令]: 对所有线程执行命令。
    • thread apply all bt: 查看所有线程的调用栈(非常有用!)。
  • 线程调度锁:
    • set scheduler-locking on锁定当前线程。只有当前调试的线程会执行,其他线程暂停,避免干扰。
    • set scheduler-locking off解除锁定(默认状态)。所有线程正常调度执行。
    • set scheduler-locking step: 仅在单步执行(n, s)时锁定当前线程,run/continue时其他线程可运行。

2. 调试核心转储 (Core Dump)

核心转储记录了程序崩溃瞬间的内存状态,是事后调试的关键。

  1. 启用核心转储生成:
    ulimit -c unlimited  # 在当前Shell会话中设置核心转储文件大小无限制
    
    • 提示: 有时需要配置系统参数(如 /proc/sys/kernel/core_pattern)来指定核心文件路径和命名规则。
  2. 程序崩溃后,通常会在当前目录或指定位置生成名为 corecore.[pid] 的文件。
  3. 使用GDB加载核心文件:
    gdb <可执行文件名> <核心文件名>
    
    gdb myapp core.12345  # 调试 'myapp' 程序,加载核心文件 'core.12345'
    
  4. 加载后,立即查看崩溃点
    • bt: 查看崩溃时的完整调用栈,定位问题函数和行号。
    • f [栈帧编号]: 切换到相关栈帧。
    • p [变量] / i locals: 检查崩溃点的变量状态。

四、总结与最佳实践

GDB 是程序调试的瑞士军刀,熟练掌握它能极大提升排错效率。关键点在于:

  1. 编译加 -g 调试的基石,没有调试信息寸步难行。
  2. 善用断点 (b) 与运行控制 (r, n, s, c): 控制程序执行流程。
  3. 洞察变量状态 (p, display, info locals): 理解程序内部数据变化。
  4. 利用调用栈 (bt, f): 理清代码执行路径,快速定位问题源头。
  5. 掌握高级技巧:
    • 多线程调试 (info threads, thread, scheduler-locking) 解决并发问题。
    • 核心转储调试 (gdb <exe> <core>, bt) 用于事后分析崩溃原因。
  6. 勤加练习: 结合真实项目中的Bug进行调试是掌握GDB的最佳途径。

小贴士:

  • 使用 .gdbinit 文件可以定制 GDB 启动行为(如预加载命令、设置别名)。
  • GDB 支持命令补全(按 Tab 键)和历史命令(上下箭头键)。
  • 探索 help [命令] 获取命令的详细帮助信息。

通过系统学习和实践这些技巧,你将能够更加自信和高效地使用 GDB 征服程序中的各种疑难杂症,显著提升开发质量和效率!

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

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

相关文章

Python:从元类到多态的实战指南

Python 作为一门灵活且强大的编程语言&#xff0c;其高级特性为开发者提供了极大的创造力和代码优化空间。本文将围绕元类、序列化、抽象类与多态等核心高级特性展开&#xff0c;结合丰富的实战代码示例&#xff0c;从原理到应用进行全方位解析&#xff0c;帮助你更深入地理解 …

LLM实战(三)——昇腾300i duo推理卡(NPU)大模型推理记录

npu推理环境配置:https://ascend.github.io/docs/sources/ascend/quick_install.html llama-factory适配的NPU说明:https://llamafactory.readthedocs.io/zh-cn/latest/advanced/npu_inference.html 一些CANN命令: 与cuda的对应关系 # 查看NPU信息 npu-smi info = nvidia-s…

【原创】锐捷AM5532宿舍AP接口状态智能巡检实战:Python脚本+Excel报表+QQ自动推送,某高校落地案例

⚡ 项目已稳定运行 180+ 天,累计巡检 14 万接口,邮件告警 0 漏报 📊 CSDN 质量分 5.0 标准:代码 + 图表 + 可落地 + 可复制, 欢迎收藏、点赞、评论三连! 一、背景 某 高校学生宿舍采用锐捷 RG-AM5532 系列交换机下挂无线 AP,高峰期 2.4 万终端并发。 网络中心痛点: …

用户、组和目录的磁盘配额

一、XFS_quota限制用户和组的容量&#xff08;block&#xff09;与文件数量&#xff08;inode&#xff09;&#xff1b;限制block就限制了用户可以使用的磁盘容量&#xff0c;限制inode就可以限制用户新建的文件数量限制某一目录的最大磁盘配额&#xff08;directory project&a…

[GESP202506 五级] 最大公因数

题目描述 对于两个正整数 a,ba,ba,b&#xff0c;他们的最大公因数记为 gcd⁡(a,b)\gcd(a,b)gcd(a,b)。对于 k>3k > 3k>3 个正整数 c1,c2,…,ckc_1,c_2,\dots,c_kc1​,c2​,…,ck​&#xff0c;他们的最大公因数为&#xff1a; gcd⁡(c1,c2,…,ck)gcd⁡(gcd⁡(c1,c2,……

实现一个进程池(精讲)

目录 写进程池前的理论扫盲 进程池的实现 写进程池前的理论扫盲 父进程创建子进程&#xff0c;父子俩都看见同一片资源&#xff0c;这片资源被俩进程利用&#xff0c;用来通信&#xff0c;这片资源就是管道&#xff0c;如图所示&#xff0c;能很好地诠释管道。 那么什么是进程…

【tips】css模仿矢量图透明背景

就像棋盘格background-image: linear-gradient(45deg, #f0f0f0 25%, transparent 25%), linear-gradient(-45deg, #f0f0f0 25%, transparent 25%), linear-gradient(45deg, transparent 75%, #f0f0f0 75%), linear-gradient(-45deg, transparent 75%, #f0f0f0 75%);background-…

visual studio 历史版本安装

visual studio 历史版本安装 链接&#xff1a;Visual Studio 版本路线图 说明&#xff1a;该页面提供历史版本的发布说明及下载链接&#xff08;需滚动至页面底部查找相关版本&#xff09;。例如&#xff0c;2022 版本可能包含 17.0 至 17.14 等子版本&#xff0c;用户可根据需…

微软推出“愤怒计划“:利用AI工具实现恶意软件自主分类

微软周二宣布推出一款能够自主分析并分类软件的人工智能&#xff08;AI&#xff09;代理系统&#xff0c;旨在提升恶意软件检测能力。这款基于大语言模型&#xff08;LLM&#xff09;的自主恶意软件分类系统目前仍处于原型阶段&#xff0c;被微软内部代号命名为"愤怒计划&…

SOLIDWORKS Electrical:实现真正意义上的机电协同设计

随着市场的发展&#xff0c;企业面临两个方面的挑战&#xff1a;从业务和市场方面来看&#xff0c;为了在竞争中取得更大优势&#xff0c;需要更高质量的产品&#xff0c;较低的成本并缩短产品上市周期&#xff1b;从设计和技术方面来看&#xff0c;产品的集成度越来越高&#…

MySql_忘记了root密码怎么办

《MySql_忘记了root密码怎么办》在忘记root密码的时候&#xff0c;可以按以下步骤处理&#xff08;以windows为例&#xff09;。_1) 关闭正在运行的MySQL服务。_2) 打开DOS窗口&#xff0c;转到mysql\bin目录。_3) 输入mysqld –skip-grant-tables 回车。–skip-grant-tables 的…

wstool和catkin_tools工具介绍

好的&#xff0c;我们来详细介绍一下 python3-wstool 和 python3-catkin-tools 这两个在 ROS (Robot Operating System) 开发中非常重要的工具&#xff0c;以及它们之间的关系。 首先&#xff0c;python3- 这个前缀表示这些是针对 Python 3 的软件包版本&#xff0c;这在现代 R…

吴恩达 深度学习笔记

最近在看吴恩达深度学习系列课程&#xff0c;简单做一个基本框架笔记。 如感兴趣或了解更多内容&#xff0c;推荐看原课程 以前也做过一些与机器学习和深度学习有关的笔记&#xff0c;过分重复的就一笔带过了。 01 第一门课 神经网络和深度学习 1.1 第一周&#xff1a;深度学习…

2025数字马力一面面经(社)

2025数字马力一面面经&#xff08;社&#xff09; 日常自我介绍js数据类型有哪些&#xff08;报完菜名后简单分析了一下使用引用类型&#xff09;谈谈对const、var、let的理解&#xff08;变量提升、let和const的主要区别、使用const命名引用类型的时可以对引用类型进行操作&am…

PyQt 中 pyqtSignal 的使用

目录 基本用法 示例代码 关键特性 常见用途 一、信号的定义规则 二、完整用法步骤 1. 导入必要模块 2. 定义带信号的类 3. 定义接收信号的槽函数 4. 连接信号与槽 5. 发射信号 6. 断开连接(可选) 三、高级特性 1. 跨线程通信 2. 信号连接方式 3. 信号与匿名函数 4. 信号转发 …

使用Python验证常见的50个正则表达式

什么是正则表达式&#xff1f;正则表达式&#xff08;Regular Expression&#xff09;通常被用来检索、替换那些符合某个模式(规则)的文本。此处的Regular即是规则、规律的意思&#xff0c;Regular Expression即“描述某种规则的表达式”之意。本文收集了一些常见的正则表达式用…

Redis是单线程性能还高的原因

Redis是单线程Redis单线程是指Redis的网络IO和键值对读写是由一个线程完成的,其他功能还是使用多线程执行Redis主干业务使用单线程的原因Redis本质就是一个大的共享资源,共享资源是需要对其进行并发控制的,即使增加了线程,大部分线程也是在等待互斥锁,并行变串行,而且还需要进行…

若依前后端分离版学习笔记(七)—— Mybatis,分页,数据源的配置及使用

一 Mybatis 1、Maven依赖 在ruoyi父项目的pom文件中有一个分页插件的依赖 <!-- pagehelper 分页插件 --> <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper-spring-boot-starter</artifactId><version&…

灌区信息化智能管理系统解决方案

一、方案背景 灌区作为农业灌溉的重要基础设施&#xff0c;承担着保障粮食安全和促进农业可持续发展的关键作用。然而&#xff0c;传统灌区管理方式普遍存在信息孤岛、数据滞后、调度不精准等问题&#xff0c;导致水资源浪费和管理效率低下。在此背景下&#xff0c;灌区信息化智…

软件包管理、缓存、自定义 YUM 源

1. 软件包管理是啥 你可以把软件包管理器理解成 Linux 的“应用商店 安装工人”&#xff1a; 应用商店&#xff1a;帮你找到软件&#xff08;包&#xff09;安装工人&#xff1a;帮你下载安装、配置、升级、卸载管理账本&#xff1a;记录系统里都安装了啥、版本号是多少、依赖…