从某个时候开始,需要调试无法在运行的计算机上调试的程序。就我而言,我需要在笔记本电脑上调试一个通过D-Bus与iwd进行通信的程序,该程序可以管理wi-fi连接。
VSCode具有专门为此类情况设计的Remote Development插件。他不适合我有以下几个原因:
- VSCode的自动签名GnuPG提交无效。
- SSH代理无效(可能是由于禁用了代理转发)。
- 似乎在RD中存在的远程计算机上的本地目录的打开似乎不起作用(版本控制中未包含一些必需的文件,并且我不想每次都通过网络进行手动复制)。
我用Go编写,所以我要描述的hack是针对Delve调试器的。无论编程语言如何,方法本身都不会改变。对于Python ptvsd中使用的VSCode和允许远程连接的任何其他调试器,可以执行类似的操作。
TL; DR帖子
- , , SCP Delve.
- VSCode , .
- VSCode , .1 .
脚本开发和运行
Delve可以在调试服务器模式下工作,从而允许客户端通过网络连接。
要完成整个构建/上传/运行dlv的过程,您可以编写一个简单的bash脚本或Makefile,但在这种情况下,我更喜欢Taskfile代替它们,因此,我将给出自己的Taskfile.yml
,与功能上的Shell脚本没有太大区别:
version: '2'
tasks:
killall:
cmds:
# Delve ,
# ,
#
- ssh target_machine killall dlv || true
push:
deps:
- killall
cmds:
#
- go build -gcflags="all=-N -l" -o ./build/debug_binary ./cmd/program
#
- scp ./build/debug_binary target_machine:/home/tdemin/Desktop/debug_binary
delve:
deps:
- push
cmds:
# dlv 64001;
# tmux ,
# dlv, & nohup
#
- ssh target_machine '(cd ~ && chmod +x Desktop/debug_binary && tmux new -d dlv --headless -l \[::\]:64001 exec ./Desktop/debug_binary)'
现在可以使用命令启动整个过程task delve
;放置在Taskfile.yml
依赖项中可确保终止Delve(此操作必须在SCP之前完成,因为此时scp
不允许dlv读取的二进制文件被覆盖),在目标计算机的后台构建/填充并启动新的Delve进程。
设置调试配置文件
.vscode/launch.json
定义调试配置文件的文件如下所示:
{
"version": "0.2.0",
"configurations": [
{
"name": "Attach to target",
// dlv API v1 ,
// --api-version
"apiVersion": 1,
"type": "go",
"request": "attach",
"mode": "remote",
// ; ,
// , ,
//
"remotePath": "${workspaceFolder}",
// ,
//
"preLaunchTask": "Run Delve on target",
"port": 64001,
"host": "target_machine"
}
]
}
文件中的相应组装任务.vscode/tasks.json
将如下所示:
{
"version": "2.0.0",
"tasks": [
{
// preLaunchTask launch.json
"label": "Run Delve on target",
"type": "shell",
// Taskfile
"command": "task delve",
"group": {
"kind": "test",
"isDefault": true
},
"presentation": {
//
// ,
"reveal": "silent"
}
}
]
}
调试
配置完所有内容后,您可以按F5,调试会话将开始:
此方法有效,但有一个很大的局限性:VSCode内置的终端不显示正在调试的进程的标准I / O。如果需要它们,则在开始调试后,可以SSH到程序在后台运行的tmux会话。