0%

远程调试环境搭建

由于平时一直使用Arch Linux环境写代码,但是公司只给用Windows,对Windows MinGW开发环境的场景觉得很不顺手。由于业务是Linux业务,在本地开发无法编译,需要使用远程编译机编译。这种模式使得调试程序只能远端编译后,在远端不使用GDB,而GDB命令行不仅难用还有高昂的学习成本。最近新发现一写远程开发/调试的方案,再次整理出来以应付C++跨平台开发的场景。

创建样例程序

  • 本机环境:Windows X64
  • 远端环境:Linux(Armbian)aarch64
  • 本地IDE: VSCode
    创建一个CMake项目用于演示:
    .
    ├── build/
    ├── CMakeLists.txt
    ├── include/
    │   └── Student.h
    └── src/
    ├── main.cpp
    └── Student.cpp

基于SSH远程开发

第一种方案就是使用Remote-Develop套件:它包含:

  • Remote-SSH 用于SSH链接到远端环境开发/调试
  • Remote-Container 用于链接到容器开发/调试
  • Remote-WSL 用于链接到WSL开发/调试

远端开发相当把整个工作环境搬到远端,项目在远端,编译调试也在远端,VSCode只充当一个VNC的角色。此时在VSCode上开发就好似拥有了一台本地ARM开发环境一样。

flowchart LR;
    subgraph Host [Host ARM Enviroment]
        remote_extension(Remote VSCode Extension) --control--> compiler
        remote_extension --control--> debugger
        remote_extension --edit--> project_source
        compiler(Compiler) --compile--> project_source
        project_source(Project Source) --> ELF[(Project Release ELF)]
        debugger(Debugger) --debug---> ELF
    end
    subgraph Local [Local]
      vscode(Local VSCode IDE)
    end
    remote_extension <-.SSH.-> vscode
  1. 第一步需要添加远端环境,配置IP,用户名,密码

  2. 配置完成后将项目上传到远端环境,VSCode打开远端目录。此时项目可以看到提示环境已经切换到远端,编译器已经切换为arm的编译器,项目目录提示这是远端目录。

  3. 由于是完全在远端开发,在远端环境需要重新安装项目相关的插件,点击按钮同步本地插件。

  4. 配置远端launch.json和本地版本无异:

    {
    "configurations": [
    {
    "name": "Remote Dev",
    "request": "launch",
    "type": "cppdbg",
    "cwd": "${fileDirname}",
    "program": "/home/xuranus/workspace/Demo/build/demo",
    "args": [],
    "stopAtEntry": false,
    "environment": [],
    "externalConsole": false,
    "MIMode": "gdb",
    "miDebuggerPath": "/usr/bin/gdb",
    "setupCommands": [
    {
    "description": "enable pretty print for gdb",
    "text": "-enable-pretty-print",
    "ignoreFailures": true
    }
    ],
    }
    ]
    }

这种开发模式是完全基于远端的,文件全部存在远端,每次修改代码直接在远端修改,网络延迟很大决定了实际的开发体验,建议在网络较好的内网环境下使用。远端开发需要在远端上安装VSCode插件,可能会污染远端环境。

远程编译,Attach调试

还有一种方式就是利用管道程序,Attach远端进程调试。这种方式在本地开发,远端编译,远端运行。与之前不同的是:项目存放在本地。需要将本地文件与远端文件同步,手动编译远端文件,启动远端进程,再Attach远端进程并在本地调试。

flowchart LR;
    subgraph Local [Local X86 Enviroment]
        vscode(VSCode IDE) <--> plink
        plink(plink.exe)
    end
    subgraph Remote [Remote ARM Enviroment]
        compiler(Compiler) --compile --> project_source(Project Source)
        project_source --> ELF[(Project Release ELF)] 
        debugger(Debugger) --debug--> Process
        ELF --run--> Process((Process))
    end
    plink <-.SSH.-> Process
    vscode -.SFTP.-> project_source
  1. 首先需要下载一个本地管道程序,它用于SSH链接到远端,Attach一个远端进程,在本地调试远端程序。建议使用Putty的plink作为管道程序。

  2. 本地安装SFTP插件。

SFTP是一个用于同步本地和远程目录的基于SSH的插件,首次使用时需要先配置,F1使用SFTP Sync: Local -> Remote将本地目录上传到远端。之后每次保存文件时,插件都会自动同步该文件。

配置SFTP sftp.json

{
"name": "My Remote ARM Compiler",
"host": "192.168.100.1",
"protocol": "sftp",
"password": "**********",
"port": 22,
"username": "xuranus",
"remotePath": "/home/xuranus/workspace/Demo",
"uploadOnSave": true
}

  1. 配置launch.json
    {
    "configurations": [
    {
    "name": "GDB Remote Attach",
    "request": "attach",
    "type": "cppdbg",
    "processId":"${command:pickRemoteProcess}",
    "cwd": "${workspaceFolder}",
    "program": "/home/xuranus/workspace/Demo/build/demo",
    "args": [],
    "stopAtEntry": true,
    "sourceFileMap": {
    "/home/xuranus/workspace/Demo": "C:\\Users\\XUranus\\Desktop\\Demo"
    },
    "environment": [],
    "externalConsole": false,
    "MIMode": "gdb",
    "miDebuggerPath": "/usr/bin/gdb",
    "setupCommands": [
    {
    "description": "enable pretty print for gdb",
    "text": "-enable-pretty-print",
    "ignoreFailures": true
    }
    ],
    "pipeTransport": {
    "pipeCwd": "",
    "pipeProgram": "C:\\Users\\XUranus\\Downloads\\plink.exe",
    "pipeArgs": ["-ssh", "root@192.168.1.6", "-pw", "********"],
    "debuggerPath": "/usr/bin/gdb"
    }
    }
    ]
    }
    其中要注意的是:
    • sourceFileMap 配置本地文件目录和远端目录的映射关系,用于打断点
    • processId 配置"${command:pickRemoteProcess}",在每次debug时手动选择远端要被Attach的进程
    • request 需要为attach,意味着附带Debug远端进程

由于每次启动本地plink attach debug必须让远端进程先跑起来才能选择remote的进程号,我解决方案是在程序入口sleep一段时间,在这个时间段内启动本地plink attach debug。虽然觉得这个方案比较蠢,但是目前没有想到更好的解决办法。

Disqus评论区没有正常加载,请使用科学上网