vscode(Win 10)中的断点;“未经核实”;在Linux Docker容器(Hyper-V)中远程调试Go应用程序时未命中

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(因为其他容器中正在运行数据

我正在使用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-远程配置

{
         "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",