在 Linux 上调试 C++ 程序
在 Linux 上调试 C++ 程序是一个常见的开发任务,Linux 提供了多种强大的工具来帮助你进行调试。以下是常用的调试方法和工具.
1. 使用 GDB (GNU Debugger)
GDB 是最常用且功能强大的命令行调试器,适用于 C、C++ 和其他语言。它允许你逐步执行代码、设置断点、检查变量值、查看调用栈等。
安装 GDB
大多数 Linux 发行版默认已经安装了 GDB。如果没有,可以通过包管理器安装:
-
Debian/Ubuntu:
sudo apt-get install gdb -
Fedora/CentOS/RHEL:
sudo dnf install gdb -
Arch Linux:
sudo pacman -S gdb
编译带有调试信息的程序
为了使 GDB 能够提供详细的调试信息,你需要在编译时添加 -g 选项,以便生成调试符号。
g++ -g -o my_program my_program.cpp
启动 GDB
你可以通过以下方式启动 GDB:
-
直接运行程序:
gdb ./my_program -
附加到正在运行的进程(如果你需要调试一个已经在运行的程序):
gdb -p <pid>
常用 GDB 命令
-
run [args]: 开始运行程序,传递参数(如果有)。(gdb) run arg1 arg2 -
break <function>或break <file:line>: 设置断点。(gdb) break main (gdb) break my_function (gdb) break my_file.cpp:10 -
continue或c: 继续执行程序,直到遇到下一个断点或异常。(gdb) continue -
step或s: 单步执行,进入函数内部。(gdb) step -
next或n: 单步执行,不进入函数内部。(gdb) next -
print <expression>或p <expression>: 打印变量或表达式的值。(gdb) print x (gdb) print my_object->get_value() -
backtrace或bt: 显示当前调用栈。(gdb) backtrace -
info locals: 显示当前作用域中的局部变量。(gdb) info locals -
info args: 显示当前函数的参数。(gdb) info args -
watch <expression>: 设置监视点,当表达式的值发生变化时暂停程序。(gdb) watch x -
delete <breakpoint-number>: 删除指定编号的断点。(gdb) delete 1 -
quit或q: 退出 GDB。(gdb) quit
示例:调试一个简单的 C++ 程序
假设你有一个简单的 C++ 程序 main.cpp:
#include <iostream>void foo() {int a = 5;int b = 0;int c = a / b; // 这里会触发除零错误
}int main() {foo();std::cout << "Program finished." << std::endl;return 0;
}
-
编译程序:
g++ -g -o my_program main.cpp -
启动 GDB:
gdb ./my_program -
设置断点并运行程序:
(gdb) break foo (gdb) run -
单步执行:
(gdb) step -
查看变量值:
(gdb) print a (gdb) print b -
继续执行,直到遇到除零错误:
(gdb) continue -
查看调用栈:
(gdb) backtrace
2. 使用 Visual Studio Code (VSCode) 调试
VSCode 提供了一个图形化的调试界面,结合 GDB 或 LLDB,可以更方便地调试 C++ 程序。以下是如何在 VSCode 中配置和使用调试器的步骤。
安装必要的扩展
-
安装 C/C++ 扩展:
- 打开 VSCode。
- 点击左侧活动栏中的扩展图标(四个方块组成的图标)。
- 搜索并安装
C/C++扩展(由 Microsoft 提供)。
-
安装调试器:
- 对于 GDB,确保系统上已经安装了
gdb。 - 对于 LLDB,确保系统上已经安装了
lldb。
- 对于 GDB,确保系统上已经安装了
配置 launch.json
在项目的根目录下创建 .vscode 文件夹,并在其中创建 launch.json 文件。这个文件用于配置调试器的启动参数。
{"version": "0.2.0","configurations": [{"name": "(gdb) Launch","type": "cppdbg","request": "launch","program": "${workspaceFolder}/my_program", // 你的可执行文件路径"args": [], // 传递给程序的参数"stopAtEntry": false, // 是否在程序入口处停止"cwd": "${workspaceFolder}", // 工作目录"environment": [],"externalConsole": false, // 是否在外部终端中运行"MIMode": "gdb", // 使用的调试器 (gdb 或 lldb)"setupCommands": [{"description": "Enable pretty-printing for gdb","text": "-enable-pretty-printing","ignoreFailures": true}],"preLaunchTask": "build", // 可选:在调试前运行的任务(如编译)"miDebuggerPath": "/usr/bin/gdb", // GDB 的路径"internalConsoleOptions": "neverOpen"}]
}
创建 tasks.json
如果你希望在调试前自动编译程序,可以在 .vscode 文件夹中创建 tasks.json 文件,定义编译任务。
{"version": "2.0.0","tasks": [{"label": "build","type": "shell","command": "g++","args": ["-g","-o","${workspaceFolder}/my_program","${workspaceFolder}/main.cpp"],"group": {"kind": "build","isDefault": true},"problemMatcher": ["$gcc"],"detail": "Generated task to build the program."}]
}
启动调试
- 打开 VSCode。
- 点击左侧活动栏中的“运行和调试”图标(通常是一个虫子图标)。
- 选择你刚刚配置的调试配置(例如
(gdb) Launch)。 - 点击绿色的“开始调试”按钮,或者按
F5。
3. 使用 LLDB
LLDB 是另一个强大的调试器,最初为 macOS 设计,但现在也广泛支持 Linux。它的命令语法与 GDB 类似,但有一些差异。
安装 LLDB
-
Debian/Ubuntu:
sudo apt-get install lldb -
Fedora/CentOS/RHEL:
sudo dnf install lldb -
Arch Linux:
sudo pacman -S lldb
启动 LLDB
lldb ./my_program
常用 LLDB 命令
-
run [args]: 开始运行程序,传递参数(如果有)。(lldb) run arg1 arg2 -
breakpoint set -n <function>或breakpoint set -f <file> -l <line>: 设置断点。(lldb) breakpoint set -n main (lldb) breakpoint set -f my_file.cpp -l 10 -
continue或c: 继续执行程序,直到遇到下一个断点或异常。(lldb) continue -
step或s: 单步执行,进入函数内部。(lldb) step -
next或n: 单步执行,不进入函数内部。(lldb) next -
print <expression>或p <expression>: 打印变量或表达式的值。(lldb) print x (lldb) print my_object->get_value() -
thread backtrace或bt: 显示当前调用栈。(lldb) thread backtrace -
frame variable: 显示当前帧中的变量。(lldb) frame variable -
quit或q: 退出 LLDB。(lldb) quit
4. 使用 Valgrind 检查内存问题
Valgrind 是一个非常有用的工具,专门用于检测内存泄漏、非法内存访问等问题。虽然它不是调试器,但它可以帮助你发现潜在的内存问题。
安装 Valgrind
-
Debian/Ubuntu:
sudo apt-get install valgrind -
Fedora/CentOS/RHEL:
sudo dnf install valgrind -
Arch Linux:
sudo pacman -S valgrind
使用 Valgrind
valgrind --leak-check=full ./my_program
Valgrind 会运行你的程序,并在程序结束时输出详细的内存分析报告。你可以根据报告中的提示修复内存泄漏或其他问题。
5. 使用 AddressSanitizer (ASan) 检测内存错误
AddressSanitizer 是一个编译器内置的工具,专门用于检测内存错误,如越界访问、未初始化内存访问等。它比 Valgrind 更快,因为它是在编译时插入检查代码的。
编译时启用 ASan
g++ -fsanitize=address -g -o my_program my_program.cpp
运行程序
./my_program
如果程序中有内存错误,AddressSanitizer 会在运行时输出详细的错误信息。
6. 使用 GProf 分析性能
GProf 是一个简单的性能分析工具,可以帮助你了解程序的性能瓶颈。它通过记录函数调用的时间和频率来生成性能报告。
编译时启用 GProf
g++ -pg -o my_program my_program.cpp
运行程序
./my_program
程序运行后会生成一个名为 gmon.out 的文件,包含性能数据。
生成报告
gprof ./my_program gmon.out > profile.txt
你可以查看 profile.txt 文件,了解哪些函数消耗了最多的时间。
总结
在 Linux 上调试 C++ 程序有多种工具和方法可供选择,具体取决于你的需求:
- GDB 是最常用的调试器,适合大多数调试场景。
- VSCode 提供了图形化的调试界面,结合 GDB 或 LLDB,适合喜欢图形化工具的开发者。
- LLDB 是另一个强大的调试器,尤其适合 macOS 和现代 Linux 系统。
- Valgrind 和 AddressSanitizer 专注于内存问题的检测,帮助你发现潜在的内存泄漏和非法访问。
- GProf 用于性能分析,帮助你优化程序的性能。
相关文章:
在 Linux 上调试 C++ 程序
在 Linux 上调试 C 程序是一个常见的开发任务,Linux 提供了多种强大的工具来帮助你进行调试。以下是常用的调试方法和工具. 1. 使用 GDB (GNU Debugger) GDB 是最常用且功能强大的命令行调试器,适用于 C、C 和其他语言。它允许你逐步执行代码、设置断点…...
让跨 project 联查更轻松,SLS StoreView 查询和分析实践
作者:章建(处知) 概述 日志服务 SLS 是云原生观测和分析平台,为 Log、Metric、Trace 等数据提供大规模、低成本、实时的平台化服务。SLS 提供了多地域支持 [ 1] ,方便用户可以根据数据源就近接入 SLS 服务࿰…...
20240107-类型转换
1. 自动类型转换 不损失数据精度的前提下,可自动完成变量的类型转换;不损失数据精度指不将超出变量可表示范围的值赋给该变量。 2.强制类型转换 若出现精度损失,java不会自动完成类型转换,需强制进行,见下代码的第8…...
关于Linux PAM模块下的pam_listfile
讲《Linux下禁止root远程登录访问》故事的时候,说好会另开一篇讲讲pam_listfile。我们先看看pam_listfile的man文档怎么介绍的。 下面这些就好比人物的简介,甚是恼人;让人看得不明就里,反正“他大舅他二舅都是他舅”。可以直接跳…...
OKHttp调用第三方接口,响应转string报错okhttp3.internal.http.RealResponseBody@4a3d0218
原因分析 通过OkHttp请求网络,结果请求下来的数据一直无法解析并且报错,因解析时String res response.body().toString() 将toString改为string即可!...
弱电与电力工程领域,如何通过工程项目管理软件提升效率
在弱电与电力工程领域,通过益企工程云等工程项目管理软件提升效率的方法主要体现在以下几个方面: 1.智能化管理 自动化流程:益企工程云通过自动化处理日常任务和流程,减少手动操作,提高工作效率。 智能预警ÿ…...
引领实时数据分析新时代:阿里云实时数仓 Hologres
在数字化和智能化转型的浪潮中,数据已成为企业决策和运营优化的重要资产。传统的数据仓库解决方案虽然在一定程度上能够帮助企业管理数据,但随着业务需求的不断变化,实时数据处理和高效分析的能力显得愈加重要。为了应对这一挑战,…...
什么是中间件中间件有哪些
什么是中间件? 中间件(Middleware)是指在客户端和服务器之间的一层软件组件,用于处理请求和响应的过程。 中间件是指介于两个不同系统之间的软件组件,它可以在两个系统之间传递、处理、转换数据,以达到协…...
css中的部分文字特性
文章目录 一、writing-mode二、word-break三、word-spacing;四、white-space五、省略 总结归纳常见文字特性,后续补充 一、writing-mode 默认horizontal-tbwriting-mode: vertical-lr; 从第一排开始竖着排,到底部再换第二排,文字与文字之间从…...
PyQt5 UI混合开发,控件的提升
PromoteLabelTest.py 提升的类 import sys from PyQt5.QtWidgets import QApplication, QWidget,QVBoxLayout,QTextEdit,QPushButton,QHBoxLayout,QFileDialog,QLabelclass PromoteLabel(QLabel):def __init__(self,parent None):super().__init__(parent)self.setText("…...
IP查询于访问控制保护你我安全
IP地址查询 查询方法: 命令行工具: ①在Windows系统中,我们可以使用命令提示符(WINR)查询IP地址,在弹窗中输入“ipconfig”命令查看本地网络适配器的IP地址等配置信息; ②在Linux系统中&…...
SpringBoot数据层解决方案
文章目录 1. 数据层解决方案2. 数据源技术 1. 数据层解决方案 现有数据层解决方案技术选型:Druid MyBatis-Plus MySQL 数据源:DruidDataSource持久化技术:MyBatis-Plus / MyBatis数据库:MySQL 下面的研究就分为三个层面进行研…...
前端数据模拟器 mockjs 和 fakerjs
功能:帮助前端生成随机数据,独立于后端单独开发 一、mockjs 安装:npm install mockjs 优点:官网是中文。 缺点:目前该库已经无人维护,也没人解决github上的bug。 官网 github地址 二、fakerjs 安装…...
Python 类 Class
在 Python 中,类(Class)是一种创建对象(Object)的模板,它允许我们定义对象的属性和方法。类是 Python 中实现面向对象编程(OOP)的核心结构。 定义一个类 定义一个类的基本语法如下…...
PHP语言的并发编程
PHP语言的并发编程 引言 随着互联网技术的迅速发展,Web 应用的复杂性和用户并发请求的增加,要求开发者在构建高性能应用时考虑并发编程。并发编程允许程序在同一时间执行多个任务,这对于处理高流量网站、API 和实时应用程序至关重要。虽然 …...
小米智能哑铃上市,代理 IP 视角下的智能健身新篇
在智能科技与健康生活深度融合的时代,小米以其敏锐的市场洞察力和强大的创新能力,不断拓展智能生态版图。米家智能哑铃的发布,无疑是其在智能健身领域的又一重要举措。而当我们从代理 IP 的独特视角来审视这一产品,会发现其中蕴含…...
业务日志设计
当一个项目足够大的时候,我们需要将统计系统完全独立出去,那么就无法避免数据采集的问题,我们可以在业务触发处增加log日志来记录当前变化的原始数据,提供统计系统进行采集 设计一个统计系统的日志记录机制时,主要需要…...
对话|全年HUD前装将超330万台,疆程技术瞄准人机交互“第一屏”
2024年,在高阶智驾进入快速上车的同时,座舱人机交互也在迎来新的增长点。Chat GPT、AR-HUD、车载投影等新配置都在带来新增量机会。 高工智能汽车研究院监测数据显示,2024年1-10月,中国市场(不含进出口)乘用…...
【论文笔记】QLoRA: Efficient Finetuning of Quantized LLMs
🍎个人主页:小嗷犬的个人主页 🍊个人网站:小嗷犬的技术小站 🥭个人信条:为天地立心,为生民立命,为往圣继绝学,为万世开太平。 基本信息 标题: QLoRA: Efficient Finetun…...
计算机网络之---物理层的基本概念
物理层简介 物理层(Physical Layer) 是 OSI(开放系统互联)模型 中的第 1 层,它主要负责数据在物理媒介上的传输,确保原始比特(0 和 1)的传输不受干扰地从一个设备传送到另一个设备。…...
进阶与总结:成为核心贡献者的路径、开源伦理与专栏知识体系复盘
进阶与总结:成为核心贡献者的路径、开源伦理与专栏知识体系复盘 从一次深夜提交被拒说起 上周三凌晨两点,我给一个嵌入式RTOS项目提交了优化中断延迟的补丁。邮件列表三小时后回复:“代码逻辑没问题,但破坏了ARM Cortex-M3的上下文对齐约定,请重新阅读porting guide第4.…...
过程表示法:如何用步骤与操作表示知识
在知识表示中,有一类知识并不主要回答“对象是什么”或“对象之间有什么关系”,而是回答“事情应该怎样一步步完成”。例如,如何求解一个问题、如何执行一项操作、如何完成一个任务流程。这类知识强调步骤、顺序、控制和执行方式,…...
Go语言的sync.Map.CompareAndSwap原子操作实现原理与性能特性
Go语言中的sync.Map作为并发安全的高性能映射结构,其CompareAndSwap(CAS)操作通过原子指令实现无锁并发控制,成为高并发场景下的关键优化手段。本文将深入解析其底层实现原理与性能特性,帮助开发者理解如何在高竞争环境…...
动手学深度学习——转置卷积
1. 前言在前面的内容中,我们已经进入了语义分割这一部分。语义分割任务要求模型为图像中的每一个像素分配类别标签。 但这里会遇到一个非常自然的问题:卷积神经网络在不断提取特征时,通常会通过步幅卷积、池化等操作让特征图越来越小。 那最后…...
把近万个源文件喂给AI之前,我先做了一件事诺
插件化架构 v3 版本最大的变化是引入了模块化插件系统。此前版本中集成在核心包里的原生功能,现在被拆分成独立的插件。 每个插件都是一个独立的 Composer 包,包含 Swift 和 Kotlin 代码、权限清单以及原生依赖。开发者只需安装实际用到的插件࿰…...
MedGemma 1.5入门必看:4步搭建私有化医疗问答系统(无需联网)
MedGemma 1.5入门必看:4步搭建私有化医疗问答系统(无需联网) 你是不是也遇到过这样的困扰?想在网上查点医学知识,要么信息太零散,要么广告满天飞,想找个靠谱的AI问问,又担心自己的健…...
遥感数字图像处理教程【1.6】
3 . 3 单波段图像的统计如果没有特殊的说明,设 数 字 图 像 为 大 小 为 M x N , N 为图像的列数,例为图像的行数, z 0,-, N-l, J 0,… ,M - \ o3 . 3 . 1 基本的统计量1 . 反映图像平均信息的统计参数1)均值像素值的…...
我不是在用 AI 助手,我在把自己的能力沉淀成组织资产坟
1. 什么是 Apache SeaTunnel? Apache SeaTunnel 是一个非常易于使用、高性能、支持实时流式和离线批处理的海量数据集成平台。它的目标是解决常见的数据集成问题,如数据源多样性、同步场景复杂性以及资源消耗高的问题。 核心特性 丰富的数据源支持&#…...
AI 工程化实战:从零手搓代码,这一次彻底搞懂MCP!嗜
简介 langchain中提供的chain链组件,能够帮助我门快速的实现各个组件的流水线式的调用,和模型的问答 Chain链的组成 根据查阅的资料,langchain的chain链结构如下: $$Input \rightarrow Prompt \rightarrow Model \rightarrow Outp…...
瑜伽主题AI绘画落地案例:雯雯的后宫-Z-Image模型在健康类新媒体中的应用
瑜伽主题AI绘画落地案例:雯雯的后宫-Z-Image模型在健康类新媒体中的应用 1. 引言:当瑜伽内容创作遇上AI绘画 如果你是健康、瑜伽或女性生活方式类新媒体账号的运营者,相信你一定遇到过这样的困境:每天需要大量的高质量配图来吸引…...
