GDB的基本使用
我有话说
因为时间和精力原因,本文写的虎头蛇尾了,除了启动调试与程序执行以外只有少量截图演示,只是简单的说明。如果有需要可以联系我,我有时间的话会把演示补上,谢谢理解。
启动调试与程序执行
启动调试并传递参数
命令(这三者在功能上没有任何区别 ) | 功能 |
---|---|
gdb --args <exe> <args> | 在启动dgb时传入参数 |
set args <args> | 在启动gdb后,运行程序前传入参数 |
r/run <args> | 在启动gdb后,运行程序时传入参数 |
测试代码:
#include <iostream>
using namespace std;int main(int argc, char** argv) {cout << "i have "<< argc << " arguments " <<"there are my arguments: " << endl;for (int i = 0; i < argc; ++i) {cout << argv[i] << endl;}return 0;
}
不传入参数:
三种传入参数的方法:
附加进进程
附加进进程主要是用于调试已经启动的进程,在附加进进程后,进程会进入追踪暂停状态(tracing stop / t 状态),当退出gdb时进程会继续运行。
附加进进程 | 查看进程id的方法 | |
---|---|---|
gdb attach <pid> | ps -ajx | |
gdb --pid <pid> | ps -aux |
测试代码:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;int main() {size_t i = 1;while (true) {cout << "这是第 " << i++ << " 次循环" << endl;this_thread::sleep_for(chrono::seconds(1));}return 0;
}
测试结果:
逐过程调试和逐语句调试以及退出当前函数
命令 | 功能 |
---|---|
next/n | 逐过程调试 单步执行(step-over),遇到函数跳过函数 |
step/s | 逐语句调试 单步执行(step-into),遇到函数进入函数 |
continue/c | 运行到下一个断点处 |
finish | 退出当前函数 |
测试代码:
#include <iostream>
#include <string>
using namespace std;void test() {string str = "gdb";str += " welcome";str += " you";cout << str << endl;
}int main() {test();return 0;
}
测试结果:
退出调试
命令 | 功能 |
---|---|
detach | 分离当前正在调试的进程(必须处于启动状态) |
quit/q | 退出gdb |
测试代码:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;int main() { cout << "enter main function" << endl;int i = 0;for (;;) {cout << "i have looped " << ++i << " times" << endl;this_thread::sleep_for(chrono::seconds(1));}return 0;
}
测试结果:
断点管理
设置断点
命令 | 功能 |
---|---|
break/b <filename : line> | 在源代码的某一行设置断点,当调试的程序为单文件程序时,可以省略文件名 |
b <func_name> | 为函数设置断点。如果有同名函数,就为所有同名函数设置断点 如果只想为特定的函数设置断点,就需要添加限定符,以便区分到底是为哪个函数设置断点 |
rb <regex> | 为满足正则表达式的函数设置断点 |
b <location> if <expression> | 设置条件断点,当条件成立时断点就会停止进程。常用在循环中,但其他场景也能用 |
tb <location> | 设置临时断点,该断点只会命中一次 |
b [+ -] <offest> | 通过偏移量设置断点,当前代码执行到某一行时,如果要为当前代码行的前面某一行或者后面某一行设置断点,就可以通过偏移量来达到快速设置断点的目的 |
测试代码:
#include <iostream>
#include <thread>
#include <chrono>
using namespace std;void test() {cout << "enter test()" << endl;cout << "quit test()" << endl;
}void test(int) {cout << "enter test(int)" << endl;cout << "quit test(int)" << endl;
}void test(double) {cout << "enter test(int)" << endl;cout << "quit test(int)" << endl;
}void test_func() {cout << "enter test_func()" << endl;cout << "quit test_func()" << endl;
}int main() {int temp;cin >> temp;while (temp < 100) {cout << "temp: " << temp++ << endl;this_thread::sleep_for(chrono::milliseconds(500));}return 0;
}
# b <func_name># 此时,只会对class中的test_func和test_func(int)两个函数设置断点
b class::test_func()
b test_func(int)
# rb <regex>rb test_func* # 这样就为所有以test_func开头的函数设置了断点
查看、禁用、删除断点
命令 | 功能 |
---|---|
i b(info breakpoints / info break) | 查看所有断点 |
i b <id> | 查看某一个断点 |
disable/enable <id> | 禁用/启用断点 |
disable <id1 - id2> | 禁用id1到id2号断点 |
enable once <id> | 启动一次断点 |
enable delete <id> | 启动断点,在断点被击中后删除 |
enable count <times> <id> | 启动断点,在该断点被击中times次后自动禁用 |
ignore <times> <id> | 忽略前times次击中断点 |
delete / clear | 删除所有断点(clear 无法删除观察点和捕获点) |
delete <id> | 删除断点 |
delete <id1 id2 ......> | 删除id1、id2、......号断点 |
delete <id1 - id2> | 删除id1到id2号断点 |
delete <id1 - id2 id3 - id4 ......> | 删除id1到id2、id3到id4、......号断点 |
clear <func_name> | 删除函数内所有的断点,如果存在同名函数,那么所有同名函数中的断点都会被删除 |
clear <filename:line> | 删除文件中某一行的断点 |
查看、修改变量
查看变量
命令 | 功能 |
---|---|
show args | 查看命令行参数 |
info(i) args | 查看函数参数,参数必须要有名字才能查看 |
i locals | 查看局部变量 |
print(p) <variable> | 查看变量的值 |
set print null-stop | 设置字符串的显示规则,查看字符串变量时到''0'停止 |
set print pretty | 设置结构体显示规则,让结构体中每个字段占一行 |
set print array on | 设置数组显示规则,让数组中的每个元素各占一行 |
p <gdb内置函数> | 如 sizeof,strlen,strcpy |
测试代码:
#include <iostream>
using namespace std;void test1(int, double, const char*) {cout << "enter test(int, double, const char*)" << endl;cout << "exit test(int, double, const char*)" << endl;
}void test2(int i, const char* str) {cout << "enter test2(int i, const char* str)" << endl;cout << "exit test2(int i, const char* str)" << endl;
}int main() {test1(114514, 79856.33, "hello");test2(222222, "world");return 0;
}
修改变量
命令 | 功能 |
---|---|
print/p <variable> = <val> | 修改包括普通变量,成员变量,结构体,类等,可以用来控制程序的执行流程 |
p <gdb内置函数> | 通过调用gdb内置函数来修改变量 p strcpy(str, "this is string") |
查看、修改内存
# 查看内存
# n 是显示内存的长度,以f和u的读取方式显示n个数据
# f 是显示格式(x是十六进制,d是十进制,u是无符号十六进制,o是八进制,t是二进制,f是浮点,s是字符串)
# u 是单位(b是单字节,h是双字节,w是四字节,g是八字节)
# nfu都可省略 n省略时默认为1,f省略时为你上一次指定的格式(如果没有则为x),u省略时为你上一次指定的单位(如果没有则为w)x /nfu <addr># 修改内存
# var可写可不写,写了是为了避免set与其他单词组成命令
# 如set width就是gdb内置命令
set(var)<addr> = <value>
寄存器的查看和修改
寄存器的查看和修改一般用在无调试符号的程序中(release版本)。
查看寄存器
命令 | 功能 |
---|---|
i registers | 查看所有通用寄存器 |
i all-registers | 查看所有寄存器 |
i r <name> | 查看某一个寄存器 |
当函数的参数小于等于6个时,会将参数放在寄存器中,否则会放入函数栈中。
如果查看的寄存器中的值是一个字符串,可以结合p (char*) <addr> 来查看其中的内容。
修改寄存器
命令 | 功能 |
---|---|
i line <行号> | 查看行号对应代码的汇编地址 |
disassemble | 反汇编 |
set var $pc/rip = <addr> | pc/rip(program counter)寄存器,用来保存程序中下一条要执行的指令,可以通过修改pc/rip寄存器来改变程序执行的流程 |
p $pc/rip = <addr> | 同上 |
源代码的查看和管理
命令 | 功能 |
---|---|
list / l | 显示源代码,第一次默认显示10行(前后各5行),之后每次都向后显示10行 |
l - | 向前显示 |
list <dir> : <line> | 查看指定文件指定行代码 |
set listsize <value> | 设置每次显示的行数 |
list <name> | 查看指定函数的代码,如果有同名函数,就会把所有同名函数显示出来。 可以添加域限定符::来指定显示哪一个同名函数 可以通过添加<dir> : <func name>来限定查看哪一个文件中的函数 |
search <regex> | 从当前行开始向后搜索第一个满足正则表达式的源代码,搜索到之后按回车表示以当前正则表达式继续搜索下一个 |
forward-search <regex> | 同search <regex> |
reverse-search <regex> | 从当前行开始向前搜索第一个满足正则表达式的源代码,搜索到之后按回车表示以当前正则表达式继续搜索下一个 |
show directories | 查看源代码的查找目录,一般是程序的工作目录和当前所在目录 |
directory <path> | 设置源代码的查找目录 |
函数调用栈管理
命令 | 功能 |
---|---|
backtrace/bt | 查看栈回溯信息 |
frame/f <frame id / frame addr> | 切换栈帧 |
info f <id> | 查看栈帧信息 |
这些命令用来检查死锁、无限递归等问题。
相关文章:

GDB的基本使用
我有话说 因为时间和精力原因,本文写的虎头蛇尾了,除了启动调试与程序执行以外只有少量截图演示,只是简单的说明。如果有需要可以联系我,我有时间的话会把演示补上,谢谢理解。 启动调试与程序执行 启动调试并传递参数…...

如何利用AI创作高质量的文章
讯飞星火 利用AI创作高质量的文章需要遵循以下步骤: 确定主题和目标受众:在开始写作之前,明确文章的主题和目标受众。这将帮助你确定文章的风格、结构和内容。 收集资料和信息:在撰写文章之前,进行充分的研究&#x…...

开源的量化交易领域平台vn.py(VeighNa)
一:vn.py(VeighNa)下的工具以及社区版和Elite版的区别 vn.py是一款广泛应用于量化交易领域的开源软件,它主要有以下用途和功能: 1. 交易系统开发框架:vn.py提供了一个完整的交易系统开发框架,可…...

选择搜索引擎进行搜索
<!DOCTYPE html> <html> <head><meta charset"utf-8"><title>选择搜索引擎进行搜索</title><script>function searchSelectedEngine() {var keyword document.getElementById(keyword).value;var engine document.getEl…...

安卓framework修改density
安卓平台,不同屏幕分辨率需要修改density值,以适配UI显示,比如字体大小等. 命令行下进入安卓SDK源码的device/目录 再根据不同芯片厂进入不同目录, 比如展锐就是 cd device/sprd, 高通是device/qcom/搜索关键字"ro.sf.lcd_density", grep -nr “ro.sf.lcd_density”…...

我们如何将数据输入到神经网络中?
前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。 下面我拿识别美女的例子来给大家介绍如何将美女的图片数据输入到神经网络中。 此例中,待输入的数据是一张图像。为了存储图像…...

基于python模板的药品名称识别系统设计与实现
博主介绍: 大家好,本人精通Java、Python、C#、C、C编程语言,同时也熟练掌握微信小程序、Php和Android等技术,能够为大家提供全方位的技术支持和交流。 我有丰富的成品Java、Python、C#毕设项目经验,能够为学生提供各类…...

【第五节】Win32汇编程序设计
目录 一、汇编的第一个“helloworld” 二、汇编中的标号 三、的使用 四、数据定义 五、全局变量 六、局部变量 七、结构体 八、结构体的访问 九、获取变量地址 十、函数 十一、分支与循环 十二、内联汇编 十三、裸函数的使用 一、汇编的第一个“helloworld” .38…...

2.1算法的时间复杂度与空间复杂度
本篇博客介绍算法的时间复杂度与空间复杂度 一、算法效率 算法好坏从时间和空间两个维度衡量 二、时间复杂度 1.概念 时间复杂度是算法中基本操作的执行次数,定量描述了算法的运行时间 2.注意 (1)时间复杂度是偏…...

Linux VSFTP 部署与配置
一、VSFTP 简介与应用 VSFTP(Very Secure FTP Daemon)是一款功能强大、安全可靠的FTP服务器软件,广泛应用于Linux/Unix系统中。它提供了高效的文件传输服务,并具备诸多安全特性,如用户认证、权限控制、SSL/TLS加密等。…...

【Docker】Docker Consul
docker consul Docker Consul 是一个用于服务发现和配置的开源工具,它是 HashiCorp 公司推出的一个项目。Consul 提供了一个中心化的服务注册和发现系统,可以帮助开发人员轻松地在 Docker 容器和集群之间进行服务发现和配置管理。 Consul 使用基于 HTT…...

diamond安装与使用
1.前言 diamond是一款用于蛋白质和翻译后DNA搜索的序列比对工具,专为大规模序列数据的高性能分析设计。其主要特点包括: - 与BLAST相比,蛋白质和翻译后DNA的成对比对速度快100倍至10000倍。 2. 参考 https://github.com/bbuchfink/diamond …...

flume--数据从kafka到hdfs发生错误
解决: #1.将flume自带的依赖删除 mv /opt/installs/flume1.9/lib/guava-11.0.2.jar /opt/installs/flume1.9/lib/guava-11.0.2.jar.bak #2.将hadoop的依赖发送到flume下 cp /opt/installs/hadoop3.1.4/share/hadoop/common/lib/guava-27.0-jre.jar /opt/installs/f…...

Android笔试面试题AI答之Kotlin(14)
文章目录 64. Kotlin中定义函数还是属性场景?使用属性的场景使用函数的场景示例 65. 阐述Kotlin中变量初始化有几种?其中lateinit、by lazy、delegates.notNull有什么区别 ?Kotlin中变量初始化的几种方式lateinit、by lazy、Delegates.notNull的区别 66. Kotlin中…...

博弈论,CF 1600E - Array Game
目录 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 一、题目 1、题目描述 2、输入输出 2.1输入 2.2输出 3、原题链接 1600E - Array Game 二、解题报告 1、思路分析 记最长递增前缀长度为L&a…...

win10安装docker,打包python、java然后centos执行镜像
一、win10安装Docker Desktop docker官网(需要魔法)下载:https://www.docker.com/products/docker-desktop/ 安装方法参考:https://blog.csdn.net/beautifulmemory/article/details/137970794 下载完毕后界面安装,不勾…...

【数据结构入门】二叉树之堆的实现
文章目录 前言一、树1.1 树的概念1.2 树的相关概念 二、二叉树2.1 二叉树的概念2.2 特殊的二叉树2.3 二叉树的性质 三、堆3.1 堆的概念3.2 堆的性质3.3 堆的存储3.4 堆的实现3.4.1 堆的初始化3.4.2 堆的销毁3.4.1 堆向上调整算法3.4.2 堆向下调整算法3.4.3 堆的创建3.4.4 堆的插…...

智能微气候:精准调控背后的算法革命
( 于景鑫 国家农业信息化工程技术研究中心)当人工智能遇见现代农业,会擦出怎样的火花?随着数字农业、智慧农业的蓬勃发展,人工智能技术正以前所未有的速度渗透到农业生产的方方面面。其中,以深度学习为代表的前沿算法,尤其是大语言模型(LLM),正在成为驱…...

eNSP 华为交换机链路聚合
华为交换机链路聚合 链路聚合好处: 1、提高带宽 2、链路冗余 SW_2: <Huawei>sys [Huawei]sys SW_2 [SW_2]vlan batch 10 20 [SW_2]int g0/0/4 [SW_2-GigabitEthernet0/0/4]port link-type access [SW_2-GigabitEthernet0/0/4]port default vl…...

编译器揭秘
从上世纪50年代开始,编程语言五花八门,编译器和解释器层出不穷。此处只列出常见编程语言的编译器和解释器信息,不常见的编程语言有单独文章介绍。 C/C cc 此处代表Unix C编译器,其他平台可能借用cc软链接到真正的C编译器。MSVC 微…...

ubuntu下qt连接mysql出现 QMYSQL driver not loaded
1、首先检查是否重新安装了MySQL的驱动,可以使用命令: sudo apt-get remove libqt5sql5-mysql sudo apt-get install libqt5sql5-mysql 2、重新安装ibmysqlclient-dev即可解决 sudo apt-get remove libmysqlclient-dev sudo apt-get install libmysq…...

html 首行缩进2字符
1. html 首行缩进2字符 1.1. 场景 在Html开发中让一段文字(富文本等)首行缩进两个文字,可能在前面加上8个“ ”,因为过去对CSS不熟悉,这种方法实现虽然比较直接,但是文字多的时候会有很多“ ”充斥在代码中…...

什么是IP?
目录 简介 IP IP协议 IP地址 发展历程 IP地址类型 公有地址 私有地址 IP地址编址方式 A类IP地址 B类IP地址 C类IP地址 D类IP地址 特殊的网址 子网 超网 无类间路由 IP地址的分配 IP地址管理 手工管理模式 DHCP分配IP地址的管理模式 通过交换机管理IP 地址…...

js拖拽交换元素位置
摘要:最近在做会议系统,9宫格小画面要支持拖拽调整顺序,需求已经实现了,简单记录下当时的逻辑处理。 /* 关于拖拽逻辑处理 start */ // 当前在拖动的下标 const curDragIndex useRef<number>(-1); /* 拖拽元素事件* onDragStart_开始* onDragend_结束 */ const handleD…...

在 C++ 中实现自定义容器的实用指南
在 C 中实现自定义容器的实用指南 在 C 编程中,容器是存储和管理数据的基本工具。标准库提供了多种容器,如 std::vector、std::list 和 std::map,但在某些情况下,开发者可能需要实现自定义容器以满足特定需求。本文将详细介绍如何…...

《深入浅出WPF》读书笔记.4名称空间详解
《深入浅出WPF》读书笔记.4名称空间详解 背景 主要讲明名称空间概念,可以理解为命名空间的引用。 xmlns:x"http://schemas.microsoft.com/winfx/2006/xaml" 👆如x可以理解为一些列命名空间的引用。 不一一列举,只讲几个特殊的…...

电驱动总成
电驱动总成(Electric Drive Assembly)是电动汽车和混合动力汽车中关键的组成部分,主要负责将电能转化为机械能,以驱动汽车的轮胎。电驱动总成包括多个关键组件,通常可以分为以下几个主要部分: ### 主要组成…...

JavaScript class和正则
正则表达式练习 出生日期 年 月 日 ()表示一个整体 console.log(1909.match(^19\\d{2}$)); console.log(2024.match(^20(([01][0-9])|(2[0-4]))$)); //年 console.log(1909.match(^(19\\d{2})|(20(([01][0-9])|(2[0-4])))$)); // 月 console.log(12.match(^(0[1-9])|(1[0-2])…...

[Linux#42][线程] 锁的接口 | 原理 | 封装与运用 | 线程安全
互斥量 mutex • 大部分情况,线程使用的数据都是局部变量,变量的地址空间在线程栈空间 内,这种情况,变量归属单个线程,其他线程无法获得这种变量。 • 但有时候,很多变量都需要在线程间共享,这…...

奇异递归Template有啥奇的?
如果一个模版看起来很头痛,那么大概率这种模版是用来炫技,没啥用的,但是CRTP这个模版,虽然看起来头大,但是却经常被端上桌~ 奇异递归模板模式(Curiously Recurring Template Pattern, CRTP)是一…...