gdb 调试 linux 应用程序的技巧介绍
使用 gdb 来调试 Linux 应用程序时,可以显著提高开发和调试的效率。gdb(GNU 调试器)是一款功能强大的调试工具,适用于调试各类 C、C++ 程序。它允许我们在运行程序时检查其状态,设置断点,跟踪变量值的变化,并通过栈回溯了解程序中的问题所在。
掌握一些 gdb 的技巧,不仅能够更快速地定位问题,还可以帮助我们更好地理解程序的行为,特别是在调试复杂的 Linux 系统应用时。

gdb 基础命令
在调试程序时,gdb 允许我们启动程序并控制其执行。以下是一些基本操作命令:
break:设置断点。断点可以在某一行或某个函数上设置。例如,我们可以使用break main在main函数的开头设置一个断点。run:启动程序。next:单步执行,但不进入函数内部。step:单步执行,并进入函数内部。continue:继续执行程序,直到遇到下一个断点。print:打印变量的值。backtrace:查看当前的函数调用栈。watch:监视某个变量的值,当它发生变化时暂停程序。
这些是调试过程中最常用的基本命令。接下来,探讨一些更高级的技巧和方法。
调试共享库
在 Linux 环境中,许多应用程序依赖共享库(Shared Libraries),特别是在 CentOS 系统中,调试动态加载的共享库是一项常见的任务。gdb 可以非常方便地调试这些库。我们可以通过以下步骤来实现对共享库的调试。
-
首先,通过命令
info sharedlibrary来查看程序加载了哪些共享库。

-
如果想对特定共享库中的函数设置断点,可以使用共享库的符号名。例如,如果你想在共享库中的
foo_function处设置断点,可以使用命令:break libfoo.so:foo_function -
有时候,程序在动态加载共享库时会遇到问题。此时,我们可以通过设置断点在
dlopen函数上,查看共享库加载的时机:break dlopen
实例
假设我们正在调试一个依赖于 libssl.so 的程序,该程序在启动时崩溃。通过 gdb,我们可以加载程序并设置断点,以查找共享库加载的问题。启动 gdb 后,执行以下命令:
(gdb) info sharedlibrary
这将显示当前加载的共享库。如果程序在加载 libssl.so 时崩溃,可以使用以下命令在 dlopen 上设置断点:
(gdb) break dlopen
(gdb) run
在断点处,使用 bt(backtrace)命令查看调用栈,了解是哪一部分代码引发了问题。
调试多线程程序
Linux 应用中,特别是服务器类应用程序,通常会使用多线程技术。在调试多线程应用程序时,gdb 提供了很多强大的功能。例如,gdb 能够查看和切换不同线程的上下文,并可以对特定线程进行单步调试。
- 使用
info threads命令查看当前所有的线程。gdb 会列出每个线程的 ID 以及它们的状态。 - 使用
thread <id>命令可以切换到指定的线程进行调试。例如,thread 2可以切换到线程 ID 为 2 的线程。 - 当程序崩溃时,
bt命令可以显示当前线程的调用栈,但有时候需要查看其他线程的调用栈。这时可以使用thread apply all bt,它将显示所有线程的调用栈。

实例
假设我们有一个多线程的 HTTP 服务器应用程序,它在处理大量请求时偶尔会崩溃。我们可以使用 gdb 来调试这个多线程程序。启动 gdb 后,使用以下命令查看所有线程:
(gdb) info threads
假设我们发现线程 5 出现了问题,切换到该线程:
(gdb) thread 5
(gdb) bt
通过查看调用栈,我们可以快速定位问题发生的地方。为了进一步调试,可以对该线程设置断点,使用 continue 或 step 来追踪问题的根源。
栈回溯与变量检查
当程序崩溃时,gdb 可以通过栈回溯(backtrace)功能帮助我们分析问题。栈回溯会显示函数调用的完整路径,帮助确定问题发生的上下文。通过 bt 命令可以显示当前调用栈。
当我们需要查看函数内部的变量时,使用 frame 命令可以切换到不同的栈帧,并使用 info locals 查看局部变量的值。如果想查看某个变量的值,可以直接使用 print 命令。
实例
假设我们有一个复杂的递归函数出现了崩溃。使用 gdb 进行调试时,可以在崩溃时输入 bt 查看调用栈:
(gdb) bt
我们可能会看到如下输出:
#0 0x00007ffff7b11b9a in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1 0x00007ffff7b13580 in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2 0x00005555555548e7 in recursive_function (n=1000) at test.c:13
这个输出表明程序在 recursive_function 函数内发生了崩溃。为了进一步分析,我们可以查看该函数内的局部变量:
(gdb) frame 2
(gdb) info locals
此时,gdb 会显示该帧中所有局部变量的值,帮助我们理解问题的根源。
调试内存相关问题
在 Linux 系统中,内存管理对于应用程序的稳定性至关重要。内存泄漏、非法访问等问题可能导致应用崩溃。gdb 提供了一些内存调试的工具和技巧,帮助我们识别和解决这类问题。
-
使用
watch命令监控内存地址。当程序试图修改某个内存地址时,程序会暂停执行。例如,我们可以使用以下命令监视变量ptr的内存地址:watch *ptr当变量
ptr的值发生变化时,程序会暂停,并提示是哪一行代码引发了变化。 -
对于内存越界问题,
valgrind与 gdb 结合使用效果非常好。valgrind 是一个内存检测工具,能够检测内存泄漏和非法访问问题。我们可以通过 valgrind 获取详细的内存错误报告,然后在 gdb 中进一步调试问题。
实例
假设我们有一个程序由于数组越界而崩溃。启动 gdb 之后,首先我们找到引发崩溃的代码行,然后在数组相关的代码处设置一个 watchpoint:
(gdb) watch array[10]
(gdb) run
当程序试图越界访问数组时,gdb 会暂停,并提示我们是哪一行代码导致了越界访问。通过 bt 命令可以查看完整的调用栈,找到问题的根源。
调试优化后的程序
在生产环境中,很多程序在编译时会使用优化选项(如 -O2 或 -O3),这可能会导致编译器优化掉一些代码,或改变代码的执行顺序,从而使得调试变得困难。幸运的是,gdb 提供了一些方法来调试优化后的程序。
- 可以使用
set debug-file-directory指定调试符号文件的路径,帮助 gdb 更好地识别优化后的代码。 - 使用
disassemble命令查看汇编代码,帮助理解代码执行的细节。
实例
假设我们在调试一个使用 -O2 优化选项编译的程序,程序执行时遇到了问题。我们发现程序的执行顺序与源代码不同,这是因为优化后的代码被重新排列。此时,我们可以使用 disassemble 命令查看当前函数的汇编代码,帮助理解问题所在:
(gdb) disassemble main
通过分析汇编代码,可以更好地理解优化后的代码行为。
结语
gdb 是调试 Linux 应用程序的强大工具。无论是在调试共享库、多线程程序,还是在分析内存问题,gdb 提供了多种灵活的功能。通过结合这些技巧,开发者可以快速定位
并解决复杂的程序错误,使调试过程更加高效。在实际使用中,掌握这些技巧能够显著提高程序开发的效率,尤其是在 CentOS 等生产环境中进行调试时。
通过以上的实例,可以看到 gdb 不仅适用于简单的单线程应用,还可以胜任复杂的多线程、多模块程序的调试工作。在日常开发中,多加使用并结合实际项目,不仅能帮助我们更好地理解 Linux 系统中的程序执行过程,也可以提升程序的健壮性。
相关文章:
gdb 调试 linux 应用程序的技巧介绍
使用 gdb 来调试 Linux 应用程序时,可以显著提高开发和调试的效率。gdb(GNU 调试器)是一款功能强大的调试工具,适用于调试各类 C、C 程序。它允许我们在运行程序时检查其状态,设置断点,跟踪变量值的变化&am…...
Java项目实战II基于Java+Spring Boot+MySQL的房产销售系统(源码+数据库+文档)
目录 一、前言 二、技术介绍 三、系统实现 四、文档参考 五、核心代码 六、源码获取 全栈码农以及毕业设计实战开发,CSDN平台Java领域新星创作者 一、前言 随着房地产市场的蓬勃发展,房产销售业务日益复杂,传统的手工管理方式已难以满…...
aws(学习笔记第一课) AWS CLI,创建ec2 server以及drawio进行aws画图
aws(学习笔记第一课) 使用AWS CLI 学习内容: 使用AWS CLI配置密钥对创建ec2 server使用drawio(vscode插件)进行AWS的画图 1. 使用AWS CLI 注册AWS账号 AWS是通用的云计算平台,可以提供ec2,vpc,SNS以及clo…...
【Python】Eventlet 异步网络库简介
Eventlet 是一个 Python 的异步网络库,它使用协程(green threads)来简化并发编程。通过非阻塞的 I/O 操作,Eventlet 使得你可以轻松编写高性能的网络应用程序,而无需处理复杂的回调逻辑或编写多线程代码。它广泛应用于…...
【JNI】数组的基本使用
在上一期讲了基本类型的基本使用,这期来说一说数组的基本使用 HelloJNI.java:实现myArray函数,把一个整型数组转换为双精度型数组 public class HelloJNI { static {System.loadLibrary("hello"); }private native String HelloW…...
React跨平台
React的跨平台应用开发详解如下: 一、跨平台能力 React本身是一个用于构建用户界面的JavaScript库,但它通过React Native等框架实现了跨平台应用开发的能力。React Native允许开发者使用JavaScript和React来编写原生应用,这些应用可以在iOS和…...
如何在 SQL 中更新表中的记录?
当你需要修改数据库中已存在的数据时,UPDATE 语句是你的首选工具。 这允许你更改表中一条或多条记录的特定字段值。 下面我将详细介绍如何使用 UPDATE 语句,并提供一些开发建议和注意事项。 基础用法 假设我们有一个名为 employees 的表,…...
宠物饮水机的水箱低液位提醒如何实现?
ICMAN液位检测芯片轻松实现宠物饮水机的水箱低液位提醒功能! 工作原理 : 基于双通道电容式单点液位检测原理 方案特点: 液位检测精度高达1mm,超强抗干扰,动态CS 10V 为家用电器水位提醒的应用提供了一种简单而又有…...
EXCEL_光标百分比
Public Sub InitCells()Dim iSheet As LongFor iSheet Sheets.Count To 1 Step -1Sheets(iSheet).ActivateActiveWindow.Zoom 85ActiveWindow.ScrollRow 1ActiveWindow.ScrollColumn 1Sheets(iSheet).Range("A1").ActivateNext iSheetEnd Sub对日项目中的文档满天…...
(一)Web 网站服务之 Apache
一、Apache 的作用和特点 作用:Apache 是一款开源的网站服务器端软件,为网站的运行提供了稳定的基础。特点: 开源免费:这使得任何人都可以免费使用和修改它。模块化设计:具有高度的灵活性,可以根据需求选择…...
英语词汇小程序小程序|英语词汇小程序系统|基于java的四六级词汇小程序设计与实现(源码+数据库+文档)
英语词汇小程序 目录 基于java的四六级词汇小程序设计与实现 一、前言 二、系统功能设计 三、系统实现 四、数据库设计 1、实体ER图 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍:✌️大厂码农|毕设布道师&a…...
AI学习指南深度学习篇-学习率衰减的实现机制
AI学习指南深度学习篇-学习率衰减的实现机制 前言 在深度学习中,学习率是影响模型训练的重要超参数之一。合理的学习率设置不仅可以加速模型收敛,还可以避免训练过程中出现各种问题,如过拟合或训练不收敛。学习率衰减是一种动态调整学习率的…...
My_qsort() -自己写的 qsort 函数
2024 - 10 - 05 - 笔记 - 21 作者(Author):郑龙浩 / 仟濹(网名) My_qsort()- 自己写的qsort函数 My_qsort为自己写的qsort函数,但是采用的不是快速排序,而是冒泡排序,是为了模仿qsort函数而尝试写出来的函数。 思路:…...
《向量数据库指南》——Mlivus Cloud打造生产级AI应用利器
哈哈,各位向量数据库和AI应用领域的朋友们,大家好!我是大禹智库的向量数据库高级研究员王帅旭,也是《向量数据库指南》的作者。今天,我要和大家聊聊如何使用Mlivus Cloud来搭建生产级AI应用。这可是个热门话题哦,相信大家都非常感兴趣! 《向量数据库指南》 使用Mlivus …...
Electron 进程通信
预加载(preload)脚本只能访问部分 Node.js API,但是主进程可以访问全部API。此时,需要使用进程通信。 比如,在preload.js中,不能访问__dirname,不能使用 Node 中的 fs 模块,但主进程…...
Kubernetes资源详解
华子目录 1.Kubernetes中的资源1.1资源管理介绍1.2资源管理方式1.2.1命令式对象管理1.2.2kubectl常见command命令1.2.3资源类型1.2.4常用资源类型 基本命令示例运行和调试命令示例高级命令示例总结 其他命令示例create和apply区别案例显示命名空间查看命名空间中的pod如何对外暴…...
C++11之线程
编译环境:Qt join:阻塞当前线程,直到线程函数退出 detach:将线程对象与线程函数分离,线程不依赖线程对象管理 注:join和detach两者必选其一,否则线程对象的回收会影响线程的回收,导致…...
界星空科技漆包线行业称重系统
万界星空科技为漆包线行业提供的称重系统是其MES制造执行系统解决方案中的一个重要组成部分。以下是对该系统的详细介绍: 一、系统概述 万界星空科技漆包线行业称重系统,是集成在MES系统中的一个功能模块,专门用于漆包线生产过程中的重量检…...
RabbitMQ的高级特性-事务
事务:RabbitMQ是基于AMQP协议实现的, 该协议实现了事务机制, 因此RabbitMQ也⽀持事务机制. SpringAMQP也提供了对事务相关的操作. RabbitMQ事务允许开发者确保消息的发送和接收是原⼦性的, 要么全部成功, 要么全部失败 配置事务管理器: Bean public Ra…...
Qt Linguist手册
概述 Qt 为将 Qt C 和 Qt Quick 应用程序翻译成当地语言提供了出色的支持。发布经理、翻译和开发人员可以使用 Qt 工具来完成他们的任务。 发布经理对应用程序的发布负总责。通常,他们负责协调开发人员和翻译人员的工作。他们可以使用 lupdate 工具同步源代码和翻…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
视频字幕质量评估的大规模细粒度基准
大家读完觉得有帮助记得关注和点赞!!! 摘要 视频字幕在文本到视频生成任务中起着至关重要的作用,因为它们的质量直接影响所生成视频的语义连贯性和视觉保真度。尽管大型视觉-语言模型(VLMs)在字幕生成方面…...
现代密码学 | 椭圆曲线密码学—附py代码
Elliptic Curve Cryptography 椭圆曲线密码学(ECC)是一种基于有限域上椭圆曲线数学特性的公钥加密技术。其核心原理涉及椭圆曲线的代数性质、离散对数问题以及有限域上的运算。 椭圆曲线密码学是多种数字签名算法的基础,例如椭圆曲线数字签…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/
使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题:docker pull 失败 网络不同,需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...
.Net Framework 4/C# 关键字(非常用,持续更新...)
一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...
零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)
本期内容并不是很难,相信大家会学的很愉快,当然对于有后端基础的朋友来说,本期内容更加容易了解,当然没有基础的也别担心,本期内容会详细解释有关内容 本期用到的软件:yakit(因为经过之前好多期…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
