douyin8813 2019-05-08 09:15
浏览 244
已采纳

vscode(Win 10)中的断点“未验证”,并且在Linux Docker容器(Hyper-V)中进行远程调试Go app时未击中

I am developing a Go (1.12.0) api-server using vscode (1.34.0 insider and stable builds) for Windows 10. The source code is located on the Windows machine in the defined %GOPATH%. Delve (dlv.exe - version 1.2.0) is also installed in %GOPATH%\bin and %GOPATH%\bin is also in the Windows %PATH%.

The go app is then built in a Docker (Docker Desktop Version 2.0.0.3 (31259)) container with docker-compose (as some other services such as Database and web-server are running in other containers). The final go app binary is then copied to an Alpine-Linux container together with the delve executable and the delve server is started in headless mode. No source code is copied over to the Alpine-Linux container, just the binaries.

I have not managed to get remote debugging set up properly in vscode with this set-up. The debugger does start my app but any breakpoints immediately turn grey and become "unverified". They are also not hit when the app (api server) runs.

Debugging with this set-up works perfectly (debugger starts, breakpoints can be set and are hit) when using the Goland IDE from Jetbrains for remote debugging.

I have tried to find a solution over the last couple of days, finding forum posts with similar problems for Chrome debugging, Node.js debugging etc. and this post on Go, specifically:

Remote debugging - Unverified breakpoint

I also found this sample config:

https://github.com/lukehoban/webapp-go/blob/debugging/.vscode/launch.json

I think the main problem I had is that nowhere could I find any examples of how to properly set the path of the program in launch.json for the remote debug config on a Windows machine (nor could I find any documentation referring to this). The source code is only on the Windows machine in GOPATH, not in the final container the app and delve run in (and this, again, works fine with Goland debugger)

My project path/directory structure (simplified):

%GOPATH%\github.com\myuser\project_dir\
   .vscode\
      launch.json
   cmd\
      my_api\
          main.go
      another_app\
          main.go
   package1\
      package1.go (this is where I am setting the breakpoint, this package is imported in cmd\my_api\main.go)
   Dockerfile
   ... (.gitignore, GoPkg etc.)

My current launch.json config (see some variants I tried below)

launch.json - remote config

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

Notes: project_folder/cmd/my_api is where the main.go for the api server is located. However, some of the packages for this app are located under the project folder directly, i.e. project_folder/package1/package1.go

I have tried with just

"program": "${workspaceFolder}",

and

"program": "${workspaceFolder}\\cmd\\my_api",

and

"program": "${workspaceFolder}/cmd/my_api",

and

"program": "${workspaceFolder}\\cmd\\my_api\\main.go",

and

"program": "${workspaceFolder}/cmd/my_api/main.go",

I also tried to change this (with no discern-able change):

"remotePath": "/",

without success.

My multi-stage Dockerfile for building the app and launching delve in headless mode:

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"]

I set a breakpoint in one of the packages (not in project_dir/cmd/my_api/main.go, but for example in project_dir/package1/package1.go). This turns grey and "unverified" as soon as I launch the debugger in vscode and the breakpoint is not hit.

I may be doing something wrong on a really simple level, but I can't seem to figure out what.

UPDATE I have finally found the debugger log and see this:

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

I am not sure it helps me really figure out the problem with vscode though. Could this be a bug? I found a reference to an older MacOS bug:

https://github.com/Microsoft/vscode-go/issues/1859

and

https://github.com/go-delve/delve/issues/1282

but these are old and fixed(?).

With the exception of the windows path separators ("\") being converted to Unix-style path separators "/" by vscode(?), the path is correct, the file exists and the lines to set the breakpoints on are in the middle of the file (and correct)...

In vscode, if I CTRL-click on the path shown in "could not find.." (made into a link by vscode), it takes me right to the file (so vscode can find/see it no problem).

This connects no problem on the Windows host (but only if called from within this directory):

%GOPATH%\...\project_dir\cmd\my_api\dlv debug -l 127.0.0.1:40400

and

(dlv) funcs any_function_in_package1 

finds this function, so the (source) code seems to be visible to delve.

Setting the breakpoint I want in Delve directly also works:

(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-style path also works the same way on the command line:

(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

Is this a Windows/Unix path-style issue in vscode? Any suggestions?

UPDATE 2 Just found this bug report from late 2018, which seems to describe a similar problem between Delve and vscode:

https://github.com/bazelbuild/rules_go/issues/1844

However, as I posted above, Delve seems to have no problem being passed absolute (Windows) paths for breakpoints in my case, so I am unsure the above bug applies to this situation? Also, why would it work in Delve directly and not via vscode? Or could it be a Windows path / Unix path issue after all?

Thank you for any help!

  • 写回答

2条回答 默认 最新

  • doulu8537 2019-05-09 11:09
    关注

    I have finally found a bug report on this, so it appears to be an open bug for now. Leaving this here for anybody searching as this bug was not easy to find (for me at least).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 sqlite 附加(attach database)加密数据库时,返回26是什么原因呢?
  • ¥88 找成都本地经验丰富懂小程序开发的技术大咖
  • ¥15 如何处理复杂数据表格的除法运算
  • ¥15 如何用stc8h1k08的片子做485数据透传的功能?(关键词-串口)
  • ¥15 有兄弟姐妹会用word插图功能制作类似citespace的图片吗?
  • ¥200 uniapp长期运行卡死问题解决
  • ¥15 请教:如何用postman调用本地虚拟机区块链接上的合约?
  • ¥15 为什么使用javacv转封装rtsp为rtmp时出现如下问题:[h264 @ 000000004faf7500]no frame?
  • ¥15 乘性高斯噪声在深度学习网络中的应用
  • ¥15 关于docker部署flink集成hadoop的yarn,请教个问题 flink启动yarn-session.sh连不上hadoop,这个整了好几天一直不行,求帮忙看一下怎么解决