在 Visual Studio Code 中远程调试 Rust 程序

Cra*_*een 3 remote-debugging rust visual-studio-code

我正在开发一个 Rust 程序,在基于 64 位 ARM 处理器的嵌入式 Linux 板上运行。目标的嵌入式 Linux 是使用 Yocto (dunfell) 构建的。我的 Rust 开发环境是在 Linux (Ubuntu) 上运行的 Visual Studio Code。如何设置才能远程调试目标板上的程序?

我预计顺序会是这样的:

  • 为目标编译 Rust 程序(用于调试)。
  • 将调试 bin 文件复制到目标。
  • 使用 gdbserver 或 lldb-server 在目标上运行它。
  • VS Code 连接到远程 gdb/lldb,并控制程序进行常规调试。

Cra*_*een 7

扩展

\n
    \n
  • 我正在使用rust-analyzer扩展进行代码分析。它比Rust扩展更好。
  • \n
  • CodeLLDB扩展,可使用 lldb 调试 Rust 程序。
  • \n
\n

交叉编译

\n

目标板有64位ARM处理器,所以我想使用Rust来交叉编译目标aarch64-unknown-linux-gnu

\n

我正在使用 Ubuntu 18.04 LTS(它很旧,但我必须使用它来支持使用旧 Yocto 版本构建的旧项目)。我曾经apt安装Ubuntu软件包gcc-8-aarch64-linux-gnu。在更新的 Ubuntu 上,也许我可以安装更现代的软件包,例如gcc-11-aarch64-linux-gnu.

\n

在我的~/.cargo/config

\n
[target.aarch64-unknown-linux-gnu]\nlinker = "aarch64-linux-gnu-gcc-8"\n
Run Code Online (Sandbox Code Playgroud)\n

然后,我可以使用cargo以下命令手动进行交叉编译:

\n
cargo build --target=aarch64-unknown-linux-gnu\n
Run Code Online (Sandbox Code Playgroud)\n

然后在 VS Code \xe2\x80\x94 中进行交叉编译 在 myapp 的 VS Code 工作区中,在.vscode/tasks.json

\n
{\n    ...\n    "tasks": [\n        ...\n        {\n            "label": "rust: cargo build ARM"\n            "type": "cargo",\n            "command": "build",\n            "args": ["--target=aarch64-unknown-linux-gnu"],\n            "problemMatcher": [\n                "$rustc"\n            ],\n            "group": "build",\n        },\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然后,我只需执行 Shift-Ctrl-B,然后选择“rust:cargo build ARM”构建任务。

\n

远程调试

\n

目标是作为低权限用户(而不是 root)myapp运行。targetboard.localtargetuser

\n

在 VS Code 中,CodeLLDB 扩展使用 lldb 来调试 Rust 程序。但是,lldb 是 Yocto 中针对目标硬件的大型编译。但是,连接到gdbserver目标板上运行效果很好。目标板上运行的嵌入式Linux 映像只需要存在gdbserver即可。

\n

目标板还需要在其上运行 SSH 服务器,并支持rsync普通 SSH 复制。rsync很好,因为将可执行文件复制到目标可以更快。

\n

在 myapp 的 VS Code 工作区中,位于.vscode/launch.json

\n
{\n    ...\n    "configurations": [\n        ...\n        {\n            "type": "lldb",\n            "request": "custom",\n            "name": "Remote executable 'myapp'",\n            "preLaunchTask": "rust: remote ARM debug setup",\n            "targetCreateCommands": ["target create ${workspaceFolder}/target/aarch64-unknown-linux-gnu/debug/myapp"],\n            "processCreateCommands": ["gdb-remote targetboard.local:17777"]\n        }\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 myapp 的 VS Code 工作区中,位于.vscode/tasks.json

\n
{\n    ...\n    "tasks": [\n        ...\n        {\n            "label": "rust: remote ARM debug setup",\n            "type": "shell",\n            "command": "${workspaceFolder}/scripts/remote_debug.sh",\n            "args": [ "${workspaceFolder}", "targetboard.local", "17777" ],\n            "group": "none",\n            "dependsOn": [\n                "rust: cargo build ARM",\n            ],\n        },\n    ]\n}\n
Run Code Online (Sandbox Code Playgroud)\n

在 myapp 的 VS Code 工作区中,我创建了脚本scripts/remote_debug.sh

\n
#!/bin/bash\n\nVSCODE_WS="$1"\nSSH_REMOTE="$2"\nGDBPORT="$3"\n\nAPP="myapp"\nTARGET_ARCH="aarch64-unknown-linux-gnu"\nBUILD_BIN_FILE="${VSCODE_WS}/target/${TARGET_ARCH}/debug/${APP}"\nTARGET_USER="targetuser"\nTARGET_BIN_FILE="/home/targetuser/${APP}"\nTARGET_CWD="/var/lib/myapp"\n\nssh "${TARGET_USER}@${SSH_REMOTE}" "killall gdbserver ${APP}"\n\nif ! rsync -avz "${BUILD_BIN_FILE}" "${TARGET_USER}@${SSH_REMOTE}:${TARGET_BIN_FILE}"; then\n    # If rsync doesn't work, it may not be available on target. Fallback to trying SSH copy.\n    if ! scp "${BUILD_BIN_FILE}" "${TARGET_USER}@${SSH_REMOTE}:${TARGET_BIN_FILE}"; then\n        exit 2\n    fi\nfi\n\nssh -f "${TARGET_USER}@${SSH_REMOTE}" "sh -c 'cd ${TARGET_CWD}; nohup gdbserver *:${GDBPORT} ${TARGET_BIN_FILE} > /dev/null 2>&1 &'"\n
Run Code Online (Sandbox Code Playgroud)\n

目标 CWD/var/lib/myapp需要以正确的用户权限存在targetuser。我可以直接指定/home/targetuser

\n

设置完毕后,我只需在 VS Code 中按 F5,它就会编译、将文件复制到目标板,并通过gdbserver.

\n

  • 很不错!该脚本实际上并不需要,也可以定义为 3 个任务(gdbserver 终止、exe 复制和 gdbserver 启动)。 (2认同)