2006 字
10 分钟
开源鸿蒙哪吒开发板使用gdbserver调试程序

gdbgdbserver 是 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.xz
tar -xvf gdb-16.3.tar.xz
NOTE

也可以从 GNU FTP 站点 直接下载 gdb 源码。下载速度较慢时,可以使用国内镜像站点,例如 清华大学开源软件镜像站

因为 gdb 在之前下载的编译工具链中已经包含,我们只需要编译 gdbserver 部分。进入解压后的 gdb-16.3 目录,并新建 build 文件夹:

cd gdb-16.3
mkdir build
cd build

使用以下命令进行编译,注意替换 TOOL 路径为实际的编译器路径:

export TRIPLE=riscv64-unknown-linux-musl
export 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-agent
make -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.git
cd dropbear

创建 build 目录并进入:

mkdir build
cd build

使用以下命令进行编译,注意替换 TOOL 路径为实际的编译器路径:

export TRIPLE=riscv64-unknown-linux-musl
export 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-utmp
make MULTI=1 PROGRAMS="dropbear dbclient dropbearkey scp" LDFLAGS="-static" -j$(nproc)

编译完成后,dropbearmulti 可执行文件位于 dropbear/build/dropbearmulti,它是一个多合一可执行文件,包含 dropbeardbclientdropbearkeyscp 四个程序。

dropbearmulti 可执行文件传输到开源鸿蒙哪吒开发板上,作为 ssh 服务器运行。建议复制到 /bin/ 目录下,以便全局使用。

配置 dropbear 服务器#

为方便使用,创建符号链接:

ln -s /bin/dropbearmulti /bin/dropbear
ln -s /bin/dropbearmulti /bin/dbclient
ln -s /bin/dropbearmulti /bin/dropbearkey
ln -s /bin/dropbearmulti /bin/scp

生成主机密钥:

dropbearkey -t rsa -f /etc/dropbear/dropbear_rsa_host_key
dropbearkey -t ecdsa -f /etc/dropbear/dropbear_ecdsa_host_key

修改 root 用户配置使其可登录:

cp /etc/passwd /etc/passwd.bak
sed -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$......'

计算 最后修改日期(单位为天,自 1970-01-01 起):

DAYS=$(($(date +%s)/86400))

重建 /etc/shadow 文件:

printf 'root:%s:%s:0:99999:7:::\n' "$HASH" "$DAYS" > /etc/shadow
chmod 600 /etc/shadow
chown 0:0 /etc/shadow

同时写入 /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_keys
mkdir -p root/.ssh
chmod 700 root/.ssh
echo "粘贴公钥内容" >> root/.ssh/authorized_keys
chmod 600 root/.ssh/authorized_keys

上传完成后,即可使用密钥登录:

ssh -i ~/.ssh/id_rsa root@x.x.x.x

vscode 中配置一键上传与调试#

配置 .vscode/launch.json 文件,注意修改 miDebuggerPathx.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"]
    // }
  ]
}

在开发板上启动 dropbeargdbserver

dropbear -p 22 -R
gdbserver --multi :23456

现在在 vscode 中启动调试,选择 (gdb) 远程,即可实现一键编译、上传与调试功能,大大提升开发效率。

开源鸿蒙哪吒开发板使用gdbserver调试程序
https://blog.wely.fun/posts/开源鸿蒙哪吒开发板使用gdbserver调试程序/
作者
Wely
发布于
2025-10-29
许可协议
CC BY-NC-SA 4.0