Linux 下使用 VS Code 远程 GDB 调试 ARM 程序

发布于:2025-07-13 ⋅ 阅读:(15) ⋅ 点赞:(0)

Linux 下使用 VS Code 远程 GDB 调试 ARM 程序

在嵌入式 Linux 开发中,调试是开发过程中至关重要的一环。由于嵌入式设备资源有限,直接在设备上进行调试往往不方便。因此,远程调试成为了一种高效的调试方式。

本文将详细介绍如何在 Linux 环境下使用 VS Code 进行远程 GDB 调试 ARM 程序,包括:

  1. 使用 gdbserver 和交叉 GDB 进行远程调试
  2. 使用本地模拟的根文件系统(rootfs)解决环境差异问题
  3. 在 VS Code 中配置图形化调试界面
  4. 如何根据系统字节数选择模拟器
  5. 提供完整的调试流程、常见问题解答和实用建议
  6. 一个完整的自动化脚本(build + deploy + debug)
  7. 一个最小可运行的示例项目结构
  8. VS Code 配置模板

一、远程调试原理

远程调试的基本原理是:

目标设备(Target):运行 gdbserver,负责启动被调试程序,接收 GDB 客户端的调试命令。

主机(Host):运行 GDB 客户端,负责发送调试命令,显示调试信息。

[主机] <—> [网络] <—> [目标设备]

GDB客户端 gdbserver

二、准备工作

1. 安装 VS Code

2. 安装插件:

  • C/C++ Extension Pack
  • CMake Tools(可选)
  • GDB Debug

3. 安装交叉编译工具链

sudo apt install gcc-<arch>-linux-gnu

4.验证安装:

<arch>-linux-gnu-gcc --version

3. 准备目标设备的 rootfs

你可以从以下途径获取:

  • 从设备厂商提供的 SDK 中提取
  • 使用 debootstrap 或 multistrap 构建最小系统
  • 从设备的固件镜像中提取

假设你获得了 rootfs.tar.xz,解压:

tar -xJf rootfs.tar.xz
cd rootfs

4. 安装 QEMU 模拟器

sudo apt install qemu-user-static

1.根据目标系统的字节数选择模拟器:

  • 32位 ARM 系统:使用 qemu-arm-static
  • 64位 ARM 系统:使用 qemu-aarch64-static

2.将对应的模拟器拷贝到 rootfs 中:

# 对于 64 位系统
cp /usr/bin/qemu-aarch64-static ./usr/bin/

# 对于 32 位系统
cp /usr/bin/qemu-arm-static ./usr/bin/

3.验证 QEMU:

qemu-aarch64-static --version
# 或
qemu-arm-static --version

三、配置远程调试环境

1. 在目标设备上启动 gdbserver

gdbserver :1234 ./your_app

2. 在本地主机上启动 GDB 并连接

<arch>-linux-gnu-gdb ./your_app
(gdb) target remote <设备IP>:1234

四、使用 VS Code 进行远程调试

1. 配置 launch.json

在项目根目录下创建 .vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Remote Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/your_app",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "/usr/bin/<arch>-linux-gnu-gdb",
            "miDebuggerServerAddress": "192.168.1.100:1234",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

2. 配置 tasks.json(可选)

用于自动编译:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "<arch>-linux-gnu-gcc",
            "args": [
                "-g",
                "-o",
                "${workspaceFolder}/build/your_app",
                "${workspaceFolder}/src/main.c"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

3. 启动调试

  • 按 F5 或点击"运行和调试"
  • 选择"Remote Debug"配置
  • VS Code 将连接远端 gdbserver 并开始调试

五、使用本地模拟的 rootfs 进行调试(chroot + QEMU)

适用于本地与远端环境差异较大的情况。

1. 进入模拟环境

sudo chroot ./rootfs /usr/bin/qemu-aarch64-static /bin/sh
# 或
sudo chroot ./rootfs /usr/bin/qemu-arm-static /bin/sh

2. 挂载工具链(可选)

mount --bind /opt/toolchain ./toolchain
export PATH=$PATH:/toolchain/bin

3. 编译并调试

<arch>-linux-gnu-gcc -g -o your_app main.c
gdbserver :1234 ./your_app

4.在主机上连接:

<arch>-linux-gnu-gdb ./your_app
(gdb) target remote localhost:1234

5. 退出模拟环境

exit

6. 卸载挂载:

sudo umount ./dev ./proc ./sys ./toolchain

六、常见问题与解决方案

1. GDB 提示 “remote target does not support run”

  • 原因:远程调试不支持 run 命令,程序已由 gdbserver 启动。
  • 解决:使用 continue 替代 run。

2. 断点无效或无法命中

  • 原因:
    • 本地文件与远端文件不一致
    • 本地文件未带 -g 编译
    • 文件被 strip
  • 解决:
    • 确保本地文件带 -g
    • 使用 md5sum 或 file 命令比对文件
    • 本地使用未 strip 文件,远端可用 strip 文件

3. 连接失败或中断

  • 原因:
    • 网络不通
    • 防火墙阻止端口
    • gdbserver 未启动
  • 解决:
    • 检查 IP 和端口
    • 使用 ping 和 telnet 测试连接
    • 确保 gdbserver 正常运行

七、实用建议

1.使用自动化脚本

建议写一个脚本自动完成:

  1. 编译
  2. 拷贝到远端
  3. 启动 gdbserver
  4. 启动 GDB 并连接

使用 rsync 替代 scp

2.更高效同步文件:

rsync -avz ./build/ root@<ip>:/home/root/build/

3.使用 tmux 保持远端会话

避免 SSH 断开导致 gdbserver 中断:

tmux new -s debug
gdbserver :1234 ./your_app

八、总结

调试方式 适用场景 优点 缺点
远程调试(gdbserver) 真实设备调试 真实硬件环境 上传慢、环境不一致
模拟调试(chroot + QEMU) 本地模拟调试 环境一致、调试快 性能低、硬件功能受限
VS Code 图形化调试 提高开发效率 可视化、易用性强 需配置插件和JSON

使用 VS Code + 交叉 GDB + gdbserver,可以在本地高效调试远端 ARM 程序,结合模拟 rootfs 可解决环境差异问题,提升开发体验。

九、附录

A. 自动化脚本(build + deploy + debug)

#!/bin/bash

# 配置
TARGET_IP="192.168.1.100"
TARGET_USER="root"
TARGET_PATH="/home/root"
APP_NAME="your_app"
CROSS_COMPILE="<arch>-linux-gnu-"

# 编译
echo "Building..."
${CROSS_COMPILE}gcc -g -o build/${APP_NAME} src/main.c

# 部署
echo "Deploying..."
rsync -avz build/${APP_NAME} ${TARGET_USER}@${TARGET_IP}:${TARGET_PATH}/

# 启动 gdbserver
echo "Starting gdbserver on target..."
ssh ${TARGET_USER}@${TARGET_IP} "cd ${TARGET_PATH} && gdbserver :1234 ./${APP_NAME}" &

# 等待 gdbserver 启动
sleep 2

# 启动 GDB
echo "Starting GDB..."
${CROSS_COMPILE}gdb build/${APP_NAME} -ex "target remote ${TARGET_IP}:1234"

B. 最小可运行示例项目结构

my_project/
├── src/
│   └── main.c
├── build/
├── .vscode/
│   ├── launch.json
│   └── tasks.json
├── rootfs/
│   ├── bin/
│   ├── lib/
│   └── ...
├── debug.sh
└── README.md

src/main.c 示例:

#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;
    int sum = a + b;
    printf("Sum: %d\n", sum);
    return 0;
}

C. VS Code 配置模板

.vscode/launch.json:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Remote Debug",
            "type": "cppdbg",
            "request": "launch",
            "program": "${workspaceFolder}/build/your_app",
            "args": [],
            "stopAtEntry": false,
            "cwd": "${workspaceFolder}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "miDebuggerPath": "/usr/bin/<arch>-linux-gnu-gdb",
            "miDebuggerServerAddress": "192.168.1.100:1234",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                }
            ]
        }
    ]
}

.vscode/tasks.json:

{
    "version": "2.0.0",
    "tasks": [
        {
            "label": "build",
            "type": "shell",
            "command": "<arch>-linux-gnu-gcc",
            "args": [
                "-g",
                "-o",
                "${workspaceFolder}/build/your_app",
                "${workspaceFolder}/src/main.c"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            }
        }
    ]
}

网站公告

今日签到

点亮在社区的每一天
去签到