搭建嵌入式GDB调试环境以及VSCode+gdbserver 图形化调试
目录
1 搭建嵌入式gdb调试环境
1.1 交叉编译工具链自带的gdb和gdbserver
1.2 使用gdb进行嵌入式程序调试
1.2.1编写简单测试程序
1.2.2 gdb调试程序
1.3 源码编译gdb和gdbserver
1.3.1 下载gdb和gdbserver源码
1.3.2 编译gdb
1.3.3 移植gdbserver
2 VSCode+gdbserver 图形化调试
1 搭建嵌入式gdb调试环境
一般的桌面 Linux 系统,比如 ubuntu、centos 等,我们可以直接运行 gdb 来调试程序。但是嵌入式中芯片性能一般比较弱,所以直接在嵌入式系统中运行 gdb 不太现实(性能强大的嵌入式芯片可以这么做)。嵌入式系统中一般在 PC 端运行 gdb 工具,源码也是在 PC 端,源码对应的可执行文件放到开发板中运行。为此我们需要在开发板中运行 gdbserver,通过网络与 PC 端的 gdb 进行通信。因此要想在 PC 上通过 gdb 调试嵌入式程序,那么需要两个东西:gdb 和gdbserver,其中gdb 是运行在 PC 上的,gdbserver 需要我们移植到开发板上。
1.1 交叉编译工具链自带的gdb和gdbserver
一般来说交叉编译工具链都自带了gdb和gdbserver,因此可以不用移植,我去试了下,发现gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf里面自带的gdbserver不能用
我把他放到开发板上执行,提示
[root@imx6ull:/mnt]# ./gdbserver
-bash: ./gdbserver: No such file or directory
然后我又试了下gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf的gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/bin这个目录下的gdbserver放到开发板上是可以用的

那么gdb我也用7.5.0里面的gcc-linaro-7.5.0-2019.12-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gdb。
1.2 使用gdb进行嵌入式程序调试
1.2.1编写简单测试程序
首先编写一个简单的测试程序,用于调试
#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[])
{unsigned int times = 0;while(1) {printf("runing times:%d\r\n", times);times++;sleep(1);}
}
然后使用如下命令进行编译
arm-linux-gnueabihf-gcc test.c -o test -g //要使用-g选项才会有调试信息
然后我把他放到了开发板的/mnt目录下
1.2.2 gdb调试程序
首先在开发板上执行如下命令
./gdbserver :1234 test
在开发版上执行命令的时候,是不需要指定IP地址的,只需要指定端口号即可,然后他就会一直监听
![]()
然后在电脑上用下面的命令开始调试
./arm-linux-gnueabihf-gdb test #我这里加了./是因为我没把这个交叉编译工具链加到环境变量中

然后再用下面的命令去连接开发板
target remote 172.31.8.195:1234

这时候开发板上也会发现被连接了

接下来就可以在电脑上调试程序了
比如看一下源码

比如我在main函数的第一行设置断点

1.3 源码编译gdb和gdbserver
如果交叉编译工具链里面没有gdb和gdbserver,那么就要自己源码编译gdb和gdbserver,方法如下。
1.3.1 下载gdb和gdbserver源码
去网址: http://www.gnu.org/software/gdb/download/


然后解压
tar xzvf gdb-13.2.tar.gz
1.3.2 编译gdb
在交叉编译configure时,通常会需要设置--build、--host和--target选项。各个选项的含义如下:
--build:编译所用的机器的平台。
--host:编译出的代码运行的平台。
--target:编译出来的工具链生成的代码的运行平台。这个选项不常用,一般只在编译gcc、ld等工具链的过程中用到,编译gdb,gdbserver时也会用到。
在不涉及到交叉编译的时候,--build、--host、--target是一样的,不需要特别设置。交叉编译的时候,比如需要在x86平台编译arm程序,就需要设置--build和--host选项。
通常,本机上的gcc、ld等工具是没有前缀的,这个时候--build可以设置为空。交叉编译工具链通常都有一个前缀,比如arm-unknown-linux-gnueabi-gcc,这个时候,--host就要设置为arm-unknown-linux-gnueabi。
Example:
./configure --build=''--host=arm-unknown-gnueabi
然后用如下命令开始编译、安装
cd gdb-13.2/
mkdir /data/chw/imx6ull_20230512/nfs_rootfs/gdb_install
./configure --target=arm-linux-gnueabihf --prefix=/data/chw/imx6ull_20230512/nfs_rootfs/gdb_install
make -j8
make install
上面编译的过程中如果报错,
gdb-13.2/missing: makeinfo: not found
WARNING: 'makeinfo' is missing on your system.You should only need it if you modified a '.texi' file, orany other file indirectly affecting the aspect of the manual.You might want to install the Texinfo package:<http://www.gnu.org/software/texinfo/>The spurious makeinfo call might also be the consequence ofusing a buggy 'make' (AIX, DU, IRIX), in which case you mightwant to install GNU make:<http://www.gnu.org/software/make/>
Makefile:1794: recipe for target 'doc/bfd.info' failed
那就
sudo apt-get install texinfo
如果报错
configure: error: GMP is missing or unusable
Makefile:11803: recipe for target 'configure-gdb' failed
make[1]: *** [configure-gdb] Error 1
make[1]: *** Waiting for unfinished jobs....
那就用下面的方法
apt-get install libgmp-dev
编译安装完之后,得到

这里就不修改PATH环境变量了,测试的时候直接加路径。
1.3.3 移植gdbserver
gdbserver是在开发板上运行的,需要交叉编译,gdbserver源码在./gdb-13.2/gdbserver里面
cd ./gdb-13.2/gdbserver
./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar LD=arm-linux-gnueabihf-ld --prefix=/data/chw/imx6ull_20230512/nfs_rootfs/gdbserver_install //配置
make
报错
../gdbsupport/libgdbsupport.a: error adding symbols: File format not recognized
collect2: error: ld returned 1 exit status
Makefile:361: recipe for target 'gdbreplay' failed
make: *** [gdbreplay] Error 1
make: *** Waiting for unfinished jobs....
这个问题我是这么想的,这个libgdnsupport.a库是在前面编译gdb的时候产生的,但由于gdb是在X86电脑上运行的,所以这个libgdnsupport.a库是x86格式的,

所以我要在重新配置编译一遍gdb,只不过这次配置要用下面的命令,要编译交叉编译的版本,但是不要make install,要是install那么前面编译的X86版本的gdb就被覆盖了,这一次其实不是为了编译gdb,只是为了使用编译gdb过程中产生的库,
tar xzvf gdb-13.2.tar.gz
cd ./gdb-13.2
./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar LD=arm-linux-gnueabihf-ld
make -j8 //这次gdb就不要安装了,要不然吧前面编译的覆盖了
然后再编译gdbserver
cd ./gdb-13.2/gdbserver
./configure --target=arm-linux-gnueabihf --host=arm-linux-gnueabihf CC=arm-linux-gnueabihf-gcc CXX=arm-linux-gnueabihf-g++ AR=arm-linux-gnueabihf-ar LD=arm-linux-gnueabihf-ld --prefix=/data/chw/imx6ull_20230512/nfs_rootfs/gdbserver_install //配置
make -j8
这时候就会在当前目录下生成一个gdbserver,把它拷贝到开发板上即可
然后在开发板上执行

然后电脑上执行

这说明自己编译出来的gdb和gdbserver也是可以用的。
2 VSCode+gdbserver 图形化调试
前面介绍的是用gdb命令进行调试的,接下来看一下直接用vscode调试,这样要比gdb命令方便。
先按照下面的博客安装必要的插件:ubuntu上安装vscode,并远程开发与远程调试服务器代码_vscode ssh远程连接ubuntu后,怎么打开项目代码-CSDN博客
我现在调试是这样的,我的vscode是安装在windows上的,然后我要调试的代码test.c是在ubuntu服务器上的,所以我要先vscode远程打开ubuntu服务器上的test.c代码,就根据上面链接的博客操作就可以,然后run--Add Configuration---![]()
会生成一个launch.json,
把vscode里面的launch.json改成下面的内容
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "(gdb) Launch",
"type": "cppdbg",
"request": "launch",
"program": "${workspaceFolder}/test",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"miDebuggerPath": "/data/chw/imx6ull_20230512/nfs_rootfs/gdb_install/bin/arm-linux-gnueabihf-gdb",
"miDebuggerServerAddress": "172.31.8.195:1234"
}
]
}
其中
- miDebuggerPath:此项需要手动添加,用于指定所使用的交叉编译器 gdb 路径。
- miDebuggerServerAddress:此项需要手动添加,远程 gdbserver 服务器地址。
然后开发板上还是老样子,运行gdbserver
![]()
然后vscode上直接按F5,然后开发板上打印出了被连接的log。

然后就可以在vscode上进行调试了。

相关文章:
搭建嵌入式GDB调试环境以及VSCode+gdbserver 图形化调试
目录 1 搭建嵌入式gdb调试环境 1.1 交叉编译工具链自带的gdb和gdbserver 1.2 使用gdb进行嵌入式程序调试 1.2.1编写简单测试程序 1.2.2 gdb调试程序 1.3 源码编译gdb和gdbserver 1.3.1 下载gdb和gdbserver源码 1.3.2 编译gdb 1.3.3 移植gdbserver 2 VSCodegdbserver 图…...
深入理解 Django 模板系统
概要 在任何 Web 开发过程中,渲染和展示数据是不可或缺的一部分。Django 作为一个高效的 Python Web 框架,提供了一个强大且灵活的模板系统。本文将详细介绍 Django 模板系统的核心概念、语法和高级功能。 一、Django 模板系统简介 Django 的模板系统允…...
Flutter:安装依赖报错doesn‘t support null safety
项目中需要引用http依赖,在pubspec.yaml文件中添加如下信息: 当同步时,报错信息如下: [myflutter] flutter pub upgrade Resolving dependencies... The current Dart SDK version is 3.1.3. Because myflutter depends on http &…...
MS2111多点低压差分(M-LVDS)线路驱动器和接收器
MS2111 是多点低压差分 (M-LVDS) 线路驱动器和接收器。经过 优化,可运行在高达 200Mbps 的信号速率下。所有部件均符合 M LVDS 标准 TIA / EIA-899 。该驱动器的输出支持负载低至 30Ω 的多 点总线。 MS2111 的接收器属于 Type-2 , 可在 -1…...
flink的起源、概念、特点、应用
flink的起源 Flink的起源可以追溯到2010年,当时它作为一个研究项目开始。该项目最初由德国柏林工业大学(Berlin Institute of Technology)的一群研究人员发起,包括Matei Zaharia、Kostas Tzoumas和Stephan Ewen等。 项目最初被称为…...
11月第1周榜单丨飞瓜数据B站UP主排行榜榜单(B站平台)发布!
飞瓜轻数发布2023年10月30日-11月5日飞瓜数据UP主排行榜(B站平台),通过充电数、涨粉数、成长指数、带货数据等维度来体现UP主账号成长的情况,为用户提供B站号综合价值的数据参考,根据UP主成长情况用户能够快速找到运营…...
Modbus入门
Modbus入门 ModbusModbus模拟工具模拟工具使用配置Slave配置Poll C#使用ModBus通讯在无法使用 SerialPort类 的情况下使用TCP进行 Modbus modbus使用范围广泛,广泛应用于各类仪表,PLC等。它属于应用层协议,底层硬件基于485/以太网。 Modbus的…...
Sysmon 日志监控
系统监视器 (Sysmon) 是一个 Windows 日志记录加载项,它提供精细的日志记录功能并捕获默认情况下通常不记录的安全事件。它提供有关进程创建、网络连接、文件系统更改等的信息。分析 Sysmon 日志对于发现恶意活动和安全威胁至关重要。 在不断…...
JWT(JSON web token)的三个组成部分
每日鸡汤:每个你想要学习的瞬间都是未来的你向自己求救 前几天去考 系统架构师的考试,有一道案例分析题就是关于JWT的,作为一个前端工程师,我居然没答上来,真的气的拍大腿,但凡再努力一点呀!这次…...
CUDA学习笔记7——CUDA内存组织
CUDA内存组织 CUDA设备内存的分类与特征 内存类型物理位置访问权限可见范围生命周期1全局内存芯片外可读写所有线程和主机端由主机分配与释放2常量内存芯片外只读所有线程和主机端由主机分配与释放3纹理和表面内存芯片外一般只读所有线程和主机端由主机分配与释放4寄存器内存…...
C#把自启动程序添加到注册表中
1.Regedit自启动注册表路径 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Run 2.获取运行程序路径 SetAutoStart(AppDomain.CurrentDomain.FriendlyName, AppDomain.CurrentDomain.BaseDirectory); 3.添加到注册表中,如果注册表已经存…...
Java面试题(每天10题)-------连载(26)
目录 多线程篇 1、什么是FutureTask? 2、什么是同步容器和并发容器的实现? 3、什么是多线程的上下文切换? 4、ThreadLocal的设计理念与作用? 5、ThreadPool(线程池)用法与优势? 6、Concur…...
通用型 SPI-Flash 相关知识汇总(w25q16\q64,gd25q128\q256)
目录 管脚定义: 常用指令: GD25q16: gd25Q28 编辑 gw25q16 编辑 芯片丝印说明: GD系列: winbond系列: Read Identification(9FH): 常见ID: GD: 编辑…...
鸿蒙原生应用开发-DevEco Studio超级终端模拟器的使用
一、了解超级终端模拟器支持的设备情况 该特性在DevEco Studio V2.1 Release及更高版本中支持。 目前超级终端模拟器支持“PhonePhone”、“PhoneTablet”和“PhoneTV”的设备组网方式,开发者可以使用该超级终端模拟器来调测具备跨设备特性的应用/服务,如…...
抖音AAN服务商有几家?
大家都知道抖音服务商多如牛毛,有本地生活服务商,MCN机构服务商,企业认证服务商,ISV服务商等等。但是aan服务商就屈指可数。 aan技术服务商 从关系层面讲,aan服务商的关系友好到啥程度呢,就好比微信指定了…...
10-26 maven配置
打开idea 打开setting 基于Idea创建idea项目 加载jar包:(一般需要自己去手动加入,本地仓库是没有的)...
贰[2],OpenCV函数解析
1,imread:图片读取 CV_EXPORTS_W Mat imread( const String& filename, int flags IMREAD_COLOR );//参数1(filename):文件地址 //参数2(flags):读取标志 注:ImreadModes,参数2(flags)枚举定义 enum ImreadModes { IMREAD…...
探秘Python闭包与作用域
文章目录 闭包的定义与作用LEGB规则nonlocal与global关键字在Python的世界里,理解闭包(Closure)和作用域(Scope)是提升编程技巧和深度的一大步。这篇文章将带你深入了解闭包的神秘面纱,掌握LEGB规则,并使用nonlocal与global关键字来巧妙控制变量作用域。 闭包的定义与作…...
GPT-4V:AI在教育领域的应用
OpenAI于9月25日发布了最新的GPT-4V模型,为ChatGPT引入了语音和图像功能,为用户提供更多元化的使用方式。这次更新将为用户带来更便捷、直观的交互体验,用户可以直接拍照上传并针对照片内容提出问题。OpenAI的最终目标是构建安全、有益的人工…...
自动化之Java面试
1.重写与重载的区别 重载规则: 方法名相同,参数个数或类型不同,与返回值类型无关,节约词汇,例如driver.switchTo().frame(index/nameOrId/frameElement) java的重载(overload) 最重要的应用场景就是构造器…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
CMake基础:构建流程详解
目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...
系统设计 --- MongoDB亿级数据查询优化策略
系统设计 --- MongoDB亿级数据查询分表策略 背景Solution --- 分表 背景 使用audit log实现Audi Trail功能 Audit Trail范围: 六个月数据量: 每秒5-7条audi log,共计7千万 – 1亿条数据需要实现全文检索按照时间倒序因为license问题,不能使用ELK只能使用…...
Neo4j 集群管理:原理、技术与最佳实践深度解析
Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
pikachu靶场通关笔记22-1 SQL注入05-1-insert注入(报错法)
目录 一、SQL注入 二、insert注入 三、报错型注入 四、updatexml函数 五、源码审计 六、insert渗透实战 1、渗透准备 2、获取数据库名database 3、获取表名table 4、获取列名column 5、获取字段 本系列为通过《pikachu靶场通关笔记》的SQL注入关卡(共10关࿰…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
MySQL账号权限管理指南:安全创建账户与精细授权技巧
在MySQL数据库管理中,合理创建用户账号并分配精确权限是保障数据安全的核心环节。直接使用root账号进行所有操作不仅危险且难以审计操作行为。今天我们来全面解析MySQL账号创建与权限分配的专业方法。 一、为何需要创建独立账号? 最小权限原则…...
LLMs 系列实操科普(1)
写在前面: 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容,原视频时长 ~130 分钟,以实操演示主流的一些 LLMs 的使用,由于涉及到实操,实际上并不适合以文字整理,但还是决定尽量整理一份笔…...
