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 微…...

docker详细操作--未完待续
docker介绍 docker官网: Docker:加速容器应用程序开发 harbor官网:Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台,用于将应用程序及其依赖项(如库、运行时环…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Cesium1.95中高性能加载1500个点
一、基本方式: 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

前端导出带有合并单元格的列表
// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...

SpringTask-03.入门案例
一.入门案例 启动类: package com.sky;import lombok.extern.slf4j.Slf4j; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cache.annotation.EnableCach…...

tree 树组件大数据卡顿问题优化
问题背景 项目中有用到树组件用来做文件目录,但是由于这个树组件的节点越来越多,导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多,导致的浏览器卡顿,这里很明显就需要用到虚拟列表的技术&…...