vscode(Win 10)中的断点;“未经核实”;在Linux Docker容器(Hyper-V)中远程调试Go应用程序时未命中
我正在使用vscode(1.34.0内部版本和稳定版本)为Windows10开发一个Go(1.12.0)api服务器。源代码位于Windows计算机上定义的%GOPATH%中。Delve(dlv.exe-1.2.0版)也安装在%GOPATH%\bin中,%GOPATH%\bin也安装在Windows%PATH%中 go应用程序随后构建在Docker(Docker Desktop Version 2.0.0.3(31259))容器中,其中包含Docker compose(因为其他容器中正在运行数据库和web服务器等其他服务)。最后的go应用程序二进制文件与delve可执行文件一起复制到Alpine Linux容器中,delve服务器以无头模式启动。没有源代码被复制到Alpine Linux容器中,只有二进制文件 使用此设置,我无法在vscode中正确设置远程调试。调试器确实会启动我的应用程序,但任何断点都会立即变为灰色并变为“未验证”。当应用程序(api服务器)运行时,它们也不会被击中 当使用Jetbrains的Goland IDE进行远程调试时,使用此设置进行调试工作非常完美(调试器启动,可以设置断点并命中断点) 在过去的几天里,我试图找到一个解决方案,在Chrome调试、Node.js调试等论坛上找到了类似问题的帖子,这篇帖子正在进行中,特别是: 我还发现了以下示例配置: 我认为我遇到的主要问题是,我在任何地方都找不到如何在launch.json中为Windows机器上的远程调试配置正确设置程序路径的示例(我也找不到任何与此相关的文档)。源代码仅在GOPATH中的Windows计算机上,而不在应用程序和delve运行的最终容器中(同样,这在Goland调试器中也可以正常工作) 我的项目路径/目录结构(简化): 我当前的launch.json配置(请参阅我在下面尝试的一些变体) launch.json-远程配置vscode(Win 10)中的断点;“未经核实”;在Linux Docker容器(Hyper-V)中远程调试Go应用程序时未命中,docker,go,docker-compose,vscode-debugger,delve,Docker,Go,Docker Compose,Vscode Debugger,Delve,我正在使用vscode(1.34.0内部版本和稳定版本)为Windows10开发一个Go(1.12.0)api服务器。源代码位于Windows计算机上定义的%GOPATH%中。Delve(dlv.exe-1.2.0版)也安装在%GOPATH%\bin中,%GOPATH%\bin也安装在Windows%PATH%中 go应用程序随后构建在Docker(Docker Desktop Version 2.0.0.3(31259))容器中,其中包含Docker compose(因为其他容器中正在运行数据
{
"name": "RemoteDockerAPI",
"type": "go",
"request": "launch",
"mode": "remote",
"program": "${workspaceFolder}/cmd/my_api",
"env": {},
"args": [],
"remotePath": "/my_api",
"port": 40400, // Port
"host": "127.0.0.1", // Docker IP
"showLog": true
}
注意:project_folder/cmd/my_api是api服务器的main.go所在的位置。但是,此应用程序的某些软件包直接位于project文件夹下,即project_文件夹/package1/package1.go
我刚试过
"program": "${workspaceFolder}",
及
及
及
及
我还试图改变这一点(没有明显的改变):
没有成功
我的多阶段Dockerfile,用于构建应用程序并在无头模式下启动delve:
FROM golang:1.11.6-alpine3.9 AS builder
RUN wget -O /usr/bin/dep 'https://github.com/golang/dep/releases/download/v0.5.1/dep-linux-amd64' \
&& chmod +x /usr/bin/dep
# For debugging: conmpile Delve
RUN apk add --no-cache git
RUN go get github.com/derekparker/delve/cmd/dlv
# Copy Code and build it:
WORKDIR $GOPATH/src/github.com/myuser/my_api/
COPY Gopkg.toml Gopkg.lock ./
RUN dep ensure --vendor-only
COPY . ./
# Compile with necessary flags for delve
RUN CGO_ENABLED=0 GOOS=linux go build -gcflags "all=-N -l" -a -installsuffix nocgo -o /my_api ./cmd/my_api
FROM alpine:3.9 AS runtime-base
# DEBUGGING: Allow delve to run on Alpine based containers.
RUN apk add --no-cache libc6-compat
# App container
FROM runtime-base
WORKDIR /
# Copy certificates
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/
# Copy app
COPY --from=builder /my_api ./
# Copy delve
COPY --from=builder /go/bin/dlv /
# 40400 for delve
EXPOSE 40400
CMD ["/dlv","--listen=:40400","--headless=true","--api-version=2", "exec", "./my_api"]
我在其中一个包中设置了断点(不是在project_dir/cmd/my_api/main.go中,而是在project_dir/package1/package1.go中)。当我在vscode中启动调试器且未命中断点时,这将变为灰色且“未验证”
我可能在一个非常简单的层面上做错了什么,但我似乎不知道是什么
更新
我终于找到了调试器日志并看到了以下内容:
From client: setBreakpoints({"source":{"name":"package1.go","path":"c:\\Users\\myuser\\go\\src\\github.com\\githubaccount\\project_dir\\package1\\package1.go"},"lines":[165,170],"breakpoints":[{"line":165},{"line":170}],"sourceModified":false})
SetBreakPointsRequest
All cleared
Creating on: C:\Users\myuser\go\src\github.com\githubaccount\project_dir\package1\package1.go (C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go) :165
Creating on: C:\Users\myuser\go\src\github.com\githubaccount\project_dir\package1\package1.go (C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go) :170
Error on CreateBreakpoint: could not find C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:165
Error on CreateBreakpoint: could not find C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
不过,我不确定它是否能帮助我真正解决vscode的问题。这可能是一只虫子吗?我发现了一个旧MacOS bug的引用:
及
但这些都是旧的和固定的(?)
除了Windows路径分隔符(“\”)被VSCODE(?)转换为UNIX风格的路径分隔符“/”之外,路径是正确的,文件存在,并且设置断点的行位于文件的中间(并且正确)…
在vscode中,如果我按CTRL键单击“找不到…”(由vscode生成链接)中显示的路径,它将直接指向该文件(因此vscode可以找到/查看它,没有问题) 这在Windows主机上没有问题(但仅当从该目录中调用时): 及 查找此函数,因此(源)代码似乎对delve可见 直接在Delve中设置断点也可以:(dlv) break C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
Breakpoint 1 set at 0xad8dd8 for github.com/githubaccount/project_dir/package1.(*Struct).Function() C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
Windows样式路径在命令行上的工作方式也相同:
(dlv) break C:\Users\myuser\go\src\github.com\githubaccount\project_dir\package1\package1.go:170
Breakpoint 1 set at 0xad8dd8 for github.com/githubaccount/project_dir/package1.(*Struct).Function() C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
这是vscode中的Windows/Unix路径样式问题吗?有什么建议吗
更新2
刚刚发现了2018年末的这个bug报告,它似乎描述了Delve和vscode之间的类似问题:
然而,正如我在上面所发布的,在我的例子中,Delve在为断点传递绝对(Windows)路径方面似乎没有问题,所以我不确定上述错误是否适用于这种情况?另外,为什么它直接在Delve中工作,而不是通过vscode?或者这到底是Windows路径/Unix路径问题吗
谢谢你的帮助 我终于在这方面找到了一个漏洞,所以现在看来它是一个开放性漏洞。将此错误留给搜索此错误的任何人(至少对我来说)都不容易找到。我刚刚遇到了相同的问题,在本地Windows 10计算机上(没有Docker,只需连接到运行Go程序的本地主机)使用最新(2019年7月)的1.37.0 VSCode、dlv 1.2.0和Go 1.12.7 在我的例子中,
project\.vscode\launch.json
是:
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Remote Debug",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "C:\\Users\\VonC\\git\\go-gitea\\gitea.exe",
"cwd": "C:\\Users\\VonC\\git\\go-gitea",
"port": 2345,
"host": "127.0.0.1",
"showLog": true,
"trace": "verbose",
}
]
}
通过激活日志和详细跟踪,我清楚地看到了根本原因:
Error on CreateBreakpoint: could not find C:\Users\VonC\git\go-gitea\gitea.exe\models\repo.go:230
我混淆了可执行文件的remotePath
"remotePath": "C:\\Users\\VonC\\git\\go-gitea",
有了路径,同样的配置可以完美地工作,我的断点被识别(并在执行过程中遇到断点时停止)
当尝试远程附加到Docker容器中的程序时,可能仍然有效
更新日期:2020年3月:现已关闭,从 在Windows上远程调试交叉编译的二进制文件时,我们不考虑用户在
remotePath
字段中使用的分隔符
这应该出现在2020年3月版的VSCode 1.44中。该错误报告刚刚结束:请参阅我的
From client: setBreakpoints({"source":{"name":"package1.go","path":"c:\\Users\\myuser\\go\\src\\github.com\\githubaccount\\project_dir\\package1\\package1.go"},"lines":[165,170],"breakpoints":[{"line":165},{"line":170}],"sourceModified":false})
SetBreakPointsRequest
All cleared
Creating on: C:\Users\myuser\go\src\github.com\githubaccount\project_dir\package1\package1.go (C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go) :165
Creating on: C:\Users\myuser\go\src\github.com\githubaccount\project_dir\package1\package1.go (C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go) :170
Error on CreateBreakpoint: could not find C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:165
Error on CreateBreakpoint: could not find C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
%GOPATH%\...\project_dir\cmd\my_api\dlv debug -l 127.0.0.1:40400
(dlv) funcs any_function_in_package1
(dlv) break C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
Breakpoint 1 set at 0xad8dd8 for github.com/githubaccount/project_dir/package1.(*Struct).Function() C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
(dlv) break C:\Users\myuser\go\src\github.com\githubaccount\project_dir\package1\package1.go:170
Breakpoint 1 set at 0xad8dd8 for github.com/githubaccount/project_dir/package1.(*Struct).Function() C:/Users/myuser/go/src/github.com/githubaccount/project_dir/package1/package1.go:170
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Remote Debug",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "C:\\Users\\VonC\\git\\go-gitea\\gitea.exe",
"cwd": "C:\\Users\\VonC\\git\\go-gitea",
"port": 2345,
"host": "127.0.0.1",
"showLog": true,
"trace": "verbose",
}
]
}
Error on CreateBreakpoint: could not find C:\Users\VonC\git\go-gitea\gitea.exe\models\repo.go:230
"remotePath": "C:\\Users\\VonC\\git\\go-gitea",