gdb 与 gdbserver 是 GNU 提供的远程调试工具,gdb 运行在主机上,gdbserver 运行在目标设备上,通过网络连接实现远程调试。本文介绍如何为开源鸿蒙哪吒开发板配置 gdbserver 进行程序调试,并在 vscode 中进行可视化调试。
NOTE被调试的程序需要是
debug模式编译的可执行文件,以包含调试信息,在编译时需要加入-g参数。
编译 gdbserver
首先依照 为开源鸿蒙哪吒开发板编写程序 中的步骤,下载并解压 剑池开发工具集 中的 GCC工具链-900系列。本文以 Linux 系统为例,使用 Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz。
打开终端,首先下载并解压 gdb 源码:
wget https://ftp.gnu.org/gnu/gdb/gdb-16.3.tar.xztar -xvf gdb-16.3.tar.xzNOTE也可以从 GNU FTP 站点 直接下载
gdb源码。下载速度较慢时,可以使用国内镜像站点,例如 清华大学开源软件镜像站。
因为 gdb 在之前下载的编译工具链中已经包含,我们只需要编译 gdbserver 部分。进入解压后的 gdb-16.3 目录,并新建 build 文件夹:
cd gdb-16.3mkdir buildcd build使用以下命令进行编译,注意替换 TOOL 路径为实际的编译器路径:
export TRIPLE=riscv64-unknown-linux-muslexport TOOL=/home/wely/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.2.0/bin/export CC="$TOOL$TRIPLE-gcc"export CXX="$TOOL$TRIPLE-g++"export AR="$TOOL$TRIPLE-ar"export RANLIB="$TOOL$TRIPLE-ranlib"export CFLAGS="-O2 -DELF_NFPREG=33"export CXXFLAGS="-O2 -DELF_NFPREG=33"export LDFLAGS="-static -Wl,--gc-sections -static-libgcc -static-libstdc++"../configure --host="$TRIPLE" --disable-gdb --disable-werror --without-python --without-guile --disable-inprocess-agentmake -j"$(nproc)" all-gdbserver编译完成后,gdbserver 可执行文件位于 gdb-16.3/build/gdbserver/gdbserver。
将 gdbserver 可执行文件传输到开源鸿蒙哪吒开发板上,作为服务端运行。建议复制到 /bin/ 目录下,以便全局使用。
使用 gdb 连接 gdbserver 进行调试
首先在开源鸿蒙哪吒开发板上启动 gdbserver,监听指定端口(例如 23456):
gdbserver --multi :23456在主机上,使用编译工具链中的 riscv64-unknown-linux-musl-gdb,连接到哪吒开发板上的 gdbserver,注意将 /host/test-cpp-debug 替换为主机实际的可执行文件路径,将 x.x.x.x 替换为哪吒开发板的实际 IP 地址,并设置远程执行文件路径为哪吒开发板上的实际路径 /remote/test-cpp-debug:
./riscv64-unknown-linux-musl-gdb /host/test-cpp-debug(gdb) target extended-remote x.x.x.x:23456(gdb) set remote exec-file /remote/test-cpp-debug现在可以使用 gdb 命令进行调试,例如设置断点、单步执行等:
(gdb) break main(gdb) continue(gdb) step(gdb) print variable_name在 vscode 中配置可视化调试
首先在开源鸿蒙哪吒开发板上启动 gdbserver,监听指定端口(例如 23456):
gdbserver --multi :23456在主机上,在 vscode 中安装 C/C++ 扩展,然后创建或修改项目中的 .vscode/launch.json 文件,添加以下配置,注意替换 program 为实际的主机可执行文件路径,替换 miDebuggerPath 为实际的 riscv64-unknown-linux-musl-gdb 路径,替换 -target-select extended-remote x.x.x.x:23456 中的 IP 地址和端口号为实际的哪吒开发板地址和端口号,替换 set remote exec-file /remote/test-cpp-debug 为实际的哪吒开发板可执行文件路径:
{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) 远程", "type": "cppdbg", "request": "launch", "program": "${workspaceFolder}/test-cpp-debug", "args": [], "stopAtEntry": true, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "riscv64-unknown-linux-musl-gdb", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "将反汇编风格设置为 Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true }, { "text": "-target-select extended-remote x.x.x.x:23456" }, { "text": "set remote exec-file /remote/test-cpp-debug" }, { "text": "skip file /musl/" }, { "text": "skip function exit" }, { "text": "skip function _Exit" } ] } ]}保存后,在 vscode 中启动调试,即可通过图形界面进行断点设置、单步执行和变量查看等操作。
进阶:在 vscode 中一键编译、上传与调试
可以在开发板上运行 ssh 服务,使 vscode 能够通过 scp 自动上传编译后的可执行文件,实现一键调试。
编译 dropbear
dropbear 是一个轻量级的 ssh 服务器,适合资源受限的嵌入式设备。
还是依照 为开源鸿蒙哪吒开发板编写程序 中的步骤,下载并解压 剑池开发工具集 中的 GCC工具链-900系列。本文以 Linux 系统为例,使用 Xuantie-900-gcc-elf-newlib-x86_64-V3.2.0-20250627.tar.gz。
获取 dropbear 源码:
git clone https://github.com/mkj/dropbear.gitcd dropbear创建 build 目录并进入:
mkdir buildcd build使用以下命令进行编译,注意替换 TOOL 路径为实际的编译器路径:
export TRIPLE=riscv64-unknown-linux-muslexport TOOL=/home/wely/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.2.0/bin/export CC="$TOOL$TRIPLE-gcc"export CXX="$TOOL$TRIPLE-g++"export AR="$TOOL$TRIPLE-ar"export RANLIB="$TOOL$TRIPLE-ranlib"export CFLAGS="-O2 -DELF_NFPREG=33"export CXXFLAGS="-O2 -DELF_NFPREG=33"export LDFLAGS="-static -Wl,--gc-sections -static-libgcc -static-libstdc++"../configure --host=riscv64-linux-musl --disable-pam --disable-zlib --disable-shadow --disable-lastlog --disable-wtmp --disable-utmpmake MULTI=1 PROGRAMS="dropbear dbclient dropbearkey scp" LDFLAGS="-static" -j$(nproc)编译完成后,dropbearmulti 可执行文件位于 dropbear/build/dropbearmulti,它是一个多合一可执行文件,包含 dropbear、dbclient、dropbearkey 和 scp 四个程序。
将 dropbearmulti 可执行文件传输到开源鸿蒙哪吒开发板上,作为 ssh 服务器运行。建议复制到 /bin/ 目录下,以便全局使用。
配置 dropbear 服务器
为方便使用,创建符号链接:
ln -s /bin/dropbearmulti /bin/dropbearln -s /bin/dropbearmulti /bin/dbclientln -s /bin/dropbearmulti /bin/dropbearkeyln -s /bin/dropbearmulti /bin/scp生成主机密钥:
mkdir -p /etc/dropbeardropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_keydropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key修改 root 用户配置使其可登录:
cp /etc/passwd /etc/passwd.baksed -i '/^root:/c root:x:0:0:root:/root:/bin/sh' /etc/passwd配置 root 用户密码,此时在本地生成密码的哈希值(注意不是在开发板上):
openssl passwd -6按提示输入两次你想要的密码,得到一串形如 $6$6$xxxxx$yyyy 的哈希,复制备用。在开发板上将此哈希值设置为变量:HASH='$6$......'(以下回到开发板上运行):
HASH='$6$......'将密码写入 /etc/passwd 文件:
sed -i "s#^root:[^:]*:#root:${HASH}:#" /etc/passwd创建 root 用户的家目录:
mkdir -p /root && chmod 700 /root创建 .ssh 目录并设置权限:
mkdir -p /root/.ssh && chmod 700 /root/.ssh此时可启动 dropbear 服务器,测试密码登录:
dropbear -E -F -R -p 22可在主机上使用 ssh 连接到哪吒开发板,输入密码测试登录。
配置密钥登录
在主机上生成 ssh 密钥对(注意不是在开发板上):
sh-keygen -t rsa运行后会提示输入文件名和密码,可直接回车使用默认文件名且不设置密码。生成的公钥文件为 ~/.ssh/id_rsa.pub,私钥文件为 ~/.ssh/id_rsa。
使用 ssh-copy-id 将公钥复制到哪吒开发板的 root 用户下(注意替换 x.x.x.x 为实际 IP 地址):
ssh-copy-id -i ~/.ssh/id_rsa.pub root@x.x.x.x注:也可以手动将公钥内容追加到哪吒开发板的 /root/.ssh/authorized_keys 文件中。
# 在客户端查看公钥cat ~/.ssh/id_rsa.pub
# 在服务器上添加到 authorized_keysmkdir -p root/.sshchmod 700 root/.sshecho "粘贴公钥内容" >> root/.ssh/authorized_keyschmod 600 root/.ssh/authorized_keys上传完成后,即可使用密钥登录:
ssh -i ~/.ssh/id_rsa root@x.x.x.x在 vscode 中配置一键上传与调试
配置 .vscode/launch.json 文件,注意修改 miDebuggerPath、x.x.x.x 以及 set remote exec-file 中的 IP 地址和可执行文件路径:
{ // 使用 IntelliSense 了解相关属性。 // 悬停以查看现有属性的描述。 // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", "configurations": [ { "name": "(gdb) 远程", "type": "cppdbg", "request": "launch", "program": "${fileDirname}/${fileBasenameNoExtension}-debug", "args": [], "stopAtEntry": true, "cwd": "${fileDirname}", "environment": [], "externalConsole": false, "MIMode": "gdb", "miDebuggerPath": "riscv64-unknown-linux-musl-gdb", "preLaunchTask": "build+upload", "setupCommands": [ { "description": "为 gdb 启用整齐打印", "text": "-enable-pretty-printing", "ignoreFailures": true }, { "description": "将反汇编风格设置为 Intel", "text": "-gdb-set disassembly-flavor intel", "ignoreFailures": true }, { "text": "-target-select extended-remote x.x.x.x:23456" }, { "text": "set remote exec-file ${fileBasenameNoExtension}-debug" }, { "text": "skip file /musl/" }, { "text": "skip function exit" }, { "text": "skip function _Exit" } ] } ]}配置 .vscode/tasks.json 文件,添加编译与上传任务,注意修改 riscv64-unknown-linux-musl-g++ 编译器路径与 scp 使用的 id_rsa 私钥、x.x.x.x IP 和 / 上传路径:
{ "version": "2.0.0", "tasks": [ { "label": "build-static-riscv", "type": "shell", "command": "riscv64-unknown-linux-musl-g++", "args": [ "${fileBasename}", "-static", "-g", "-o", "${fileBasenameNoExtension}-debug" ], "options": { "cwd": "${fileDirname}" }, "group": "build", "problemMatcher": ["$gcc"] }, { "label": "upload-to-target", "type": "shell", "command": "scp", "args": [ "-i", "id_rsa", "-O", "${fileDirname}/${fileBasenameNoExtension}-debug", "root@x.x.x.x:/" ] }, { "label": "build+upload", "dependsOrder": "sequence", "dependsOn": [ "build-static-riscv", "upload-to-target" ] }
// 可选:调试结束后清理远端文件 // { // "label": "cleanup-remote", // "type": "shell", // "command": "ssh", // "args": ["root@192.168.31.200", "rm -f /test/${fileBasenameNoExtension}-debug"] // } ]}在开发板上启动 dropbear 和 gdbserver:
dropbear -p 22 -Rgdbserver --multi :23456现在在 vscode 中启动调试,选择 (gdb) 远程,即可实现一键编译、上传与调试功能,大大提升开发效率。