当前位置:首页>Linux>在 TinaLinux 开启 gdbserver

在 TinaLinux 开启 gdbserver

  • 2026-10-11 07:11:43
在 TinaLinux 开启 gdbserver

🐂这里是「你牛克斯」: 专注于分享Linux生鲜,记得关注我

一、最基础的概念(看懂分工)

GDB Server(远程调试服务)的调试机制核心在于“控制与通信的分离”。

它采用典型的 C/S(客户端/服务器)架构:在宿主机(Host)上运行功能完整的 GDB 作为客户端(负责提供用户界面、解析符号表等复杂工作),而在目标机(Target)上运行轻量级的 GDB Server(负责直接控制目标进程并读写内存)。两者之间通过 RSP(Remote Serial Protocol,远程串行协议) 协议进行网络或串口通信。

在这个最简单的模型里,你只需要明白一件事:复杂的工作交给开发机(Host),脏活累活交给目标机(Target)。

  • Host 端: 你的电脑,上面运行着完整的 GDB 软件。因为你的电脑配置高、内存大,所以它负责加载代码的各种符号表(比如哪一行代码对应哪个内存地址)。

  • Target 端: 远端的服务器或者嵌入式板子,上面只运行一个非常小的 gdbserver 软件和你的目标程序。它不需要懂代码逻辑,只听从 Host 的指挥。

二、引入协议(看懂怎么交流)

Host 和Guest之间的沟通语言——RSP 协议(Remote Serial Protocol)。

三、深入目标机内部(看懂内核如何参与)

把目光移到目标机(Target)的内部。gdbserver 是怎么控制另一个程序的?

四、完整的闭环流

你在电脑上点“加断点” → GDB 发送网络包 → gdbserver 收到后通过 ptrace 修改目标程序的内存(埋入陷阱) → 目标程序运行到这里触发硬件异常 → 内核拦截并挂起程序 → 内核通知 gdbserver → gdbserver 通过网络包告诉你的电脑 → 你的电脑屏幕上显示“程序已暂停”。

五、实操部分

Host端 :基于X86的架构的Linux容器开发环境

开发板是全志的,全志官方推荐的开发环境是Ubuntu 14.04,我这边用的稍微有点高,但是目前看起来没问题。

user@67c101d9d32e:/home/work$ cat /etc/issueUbuntu 20.04.6 LTS \n \l

需要安装一些32位应用程序以及开发包(SDK里面带了一些ELF,居然是32位的

user@67c101d9d32e:/home/work$ file /home/work/out/host/bin/fsbuild/home/work/out/host/bin/fsbuild: ELF 32-bit LSB executable, Intel 80386, \version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, \for GNU/Linux 2.6.9, with debug_info, \not strippe

所以需要安装一些依赖

sudo dpkg --add-architecture i386sudo apt updatesudo apt install -y     libc6:i386     libstdc++6:i386     zlib1g:i386sudo apt install -y     libncurses5:i386     libgcc-s1:i386

由于主控芯片是玄铁的,TinaSDK里面的交叉编译器是来自玄铁的工具链

TinaSDK 里面有对应的编译入口,位于

user@67c101d9d32e:/home/work$ ls package/devel/gdb/Makefile  patches

编译入口也支持GUI进行配置(make menuconfig)

source build/envsetup.shlunch d1-h_nezha_minmake menuconfiguser@67c101d9d32e:/home/work$ grep gdb .configCONFIG_PACKAGE_gdb is not set#确保这里打开了CONFIG_PACKAGE_gdbserver=yCONFIG_PACKAGE_python-gdbm is not setCONFIG_PACKAGE_python3-gdbm is not setCONFIG_PACKAGE_libgdbm is not set#单独编译这个应用程序,本质上是通过交叉编译器把gdb-server的源码编译到目标架构,可以是ARM/RISC-Vmake package/devel/gdb/install#也可以通过make 全部编译一遍make -j# 编译产物./out/d1-h-nezha_min/compile_dir/target/gdb-10.1/ipkg-sunxi/gdbserver/usr/bin/gdbserver

此外需要准备一个C/C++程序,用于远程调试,-g 参数表示保留调试符号,-O0表示不要把整型等小变量优化掉了-march 后面那一串是说我用到了一些向量化的函数库,c906是我的开发板的主核心芯片型号,这个经过玄铁定制的编译器可能做了一些硬件优化,-static表示静态编译(独立应用程序)。

riscv64-unknown-linux-gnu-gcc \-g -O0 -mcpu=c906fdv  \-march=rv64imafdcv0p7_zfh_xtheadc \-mabi=lp64d -mtune=c906 -static hellomain.c -o build/test

Target端:基于RISC-V架构的单核开发板(全志D1-H 哪吒)

开发板需要配置好网络,我的Host端是通过局域网(Wifi或者网线)连接到了Target端。

中转端: Windows 

这个环境是可选的,直接在Linux环境也能全部搞定(实际情况比较复杂,比如,可能有些开发板厂商的emmc/nand刷机程序仅支持Windows,所以Windows环境虽然烂,但是办公和工作都需要)。

我的情况是:通过 adb 协议(可能需要安装硬件厂家的USB驱动才行)把编译好的二进制拷贝到开发板,如果开发板不支持这个协议,也可以通过U盘拷贝、ftp协议传输,甚至scp,但是这些服务可能需要单独在开发板的编译环境开启才行。

需要注意的是,各种ELF文件在windows 躺一遍之后,权限莫名其妙的消失了,所以需要在开发板追加需要的权限

adb push gdbserver /usr/bin/adb shellchmod +x /usr/bin/gdbserver

ssh也好,adb也罢,容易掉线,保险一点,还是把串口接上,可以通过Putty或者 MobaXterm软件和开发板交互,当然,又涉及到了驱动(需要安装串口线里面那颗控制芯片的厂家的驱动)。

六、八哥/BUG

不知道是什么原因,我这里的gdb 里面无法打印某些变量的值,AI告诉我说gdb 10.1版本太老了,不识别RISC-V架构的一些寄存器,试了一下确实找不到v0~v31这些向量寄存器,但是整型变量也无法打印,感觉难以理解。

riscv64-unknown-linux-gnu-gdb ./build/testb maintarget remote 192.168.0.100:2234cdemo_rvv_vxrm () at hellomain.c:218218     int16_t src[4] = {103,107,111,115};(gdb) n220     size_t vl = 4;(gdb) p src$4 = <unavailable>(gdb) p $v0$5 = void

参考链接

https://aosabook.org/en/v2/gdb.html


如果觉得今天这篇“夸自己聪明”的摸鱼干货对你有启发,别忘了顺手点个【赞】和【在看】,或者赶紧【收藏】起来,下次搬砖时直接复制粘贴!

最新文章

随机文章