-
Notifications
You must be signed in to change notification settings - Fork 648
Breakpoints set in VS Code not hit (docker remote debugging) #2010
Description
I can't seem to hit breakpoints set in VS Code when remotely debugging my go app (which is running in Docker).
I've set up my launch.json:
{
"version": "0.2.0",
"configurations": [
{
"name": "Remote debug in Docker",
"type": "go",
"request": "launch",
"mode": "remote",
"program": "${workspaceRoot}",
"env": {},
"args": [],
"remotePath": "${workspaceRoot}",
"port": 40000, // Port
"host": "127.0.0.1", // Docker IP
"showLog": true,
"trace": "verbose"
}
]
}
This is my go.delveConfig
(user settings in VS Code):
{
"useApiV1": false,
"dlvLoadConfig": {
"followPointers": true,
"maxVariableRecurse": 3,
"maxStringLen": 400,
"maxArrayValues": 400,
"maxStructFields": -1
}
}
It attaches fine, and even hits breakpoints set via runtime.Breakpoint()
but will not hit any breakpoints set via VS Code. Debugging the same project in GoLand works fine, I can set and hit breakpoints with no issue.
I have done a lot of googling, and checking documentation, playing with configurations (launch.json, dockerfile, dlv etc) but can't seem to find a fix. Not sure what's wrong, but I have noticed a difference in the VS Code CreateBreakpoint request compared to the GoLand one by looking at the dlv log output (by adding --log --log-output=rpc
).
Here's the dlv log (via docker) when debugging via GoLand:
testapp_1 | time="2018-10-15T04:59:46Z" level=debug msg="<- RPCServer.CreateBreakpoint(rpc2.CreateBreakpointIn{\"Breakpoint\":{\"id\":0,\"name\":\"\",\"addr\":0,\"file\":\"C:/Users/<username>/Dev/go/src/testApp/main.go\",\"line\":7,\"Cond\":\"\",\"continue\":false,\"goroutine\":false,\"stacktrace\":0,\"LoadArgs\":null,\"LoadLocals\":null,\"hitCount\":null,\"totalHitCount\":0}})" layer=rpc
testapp_1 | time="2018-10-15T04:59:46Z" level=debug msg="-> *rpc2.CreateBreakpointOut{\"Breakpoint\":{\"id\":1,\"name\":\"\",\"addr\":4833364,\"file\":\"C:/Users/<username>/Dev/go/src/testApp/main.go\",\"line\":7,\"functionName\":\"main.main\",\"Cond\":\"\",\"continue\":false,\"goroutine\":false,\"stacktrace\":0,\"LoadArgs\":null,\"LoadLocals\":null,\"hitCount\":{},\"totalHitCount\":0}} error: \"\"" layer=rpc
But here's the dlv log (via docker) when debugging via VS Code:
testapp_1 | time="2018-10-15T04:52:59Z" level=debug msg="<- RPCServer.CreateBreakpoint(rpc2.CreateBreakpointIn{\"Breakpoint\":{\"id\":0,\"name\":\"\",\"addr\":0,\"file\":\"C:\\\\Users\\\\<username>\\\\Dev\\\\go\\\\src\\\\testApp\\\\main.go\",\"line\":7,\"Cond\":\"\",\"continue\":false,\"goroutine\":false,\"stacktrace\":0,\"LoadArgs\":{\"FollowPointers\":true,\"MaxVariableRecurse\":1,\"MaxStringLen\":64,\"MaxArrayValues\":64,\"MaxStructFields\":-1},\"LoadLocals\":{\"FollowPointers\":true,\"MaxVariableRecurse\":1,\"MaxStringLen\":64,\"MaxArrayValues\":64,\"MaxStructFields\":-1},\"hitCount\":null,\"totalHitCount\":0}})" layer=rpc
testapp_1 | time="2018-10-15T04:52:59Z" level=debug msg="-> *rpc2.CreateBreakpointOut{\"Breakpoint\":{\"id\":0,\"name\":\"\",\"addr\":0,\"file\":\"\",\"line\":0,\"Cond\":\"\",\"continue\":false,\"goroutine\":false,\"stacktrace\":0,\"LoadArgs\":null,\"LoadLocals\":null,\"hitCount\":null,\"totalHitCount\":0}} error: \"could not find C:\\\\Users\\\\<username>\\\\Dev\\\\go\\\\src\\\\testApp\\\\main.go:7\"" layer=rpc
Notice all the extra escapes in the file path for the VS Code call?
They aren't there for the GoLand equivalent call. Are those escapes the problem? Are they preventing dlv from finding the file?
Steps to Reproduce:
- Create go app (see below)
- Set up launch.json and delveConfig (as per above)
- Run go app in docker
e.g../build.sh && docker-compose -f docker-compose.yml up --build
- Debug the app in VS Code (F5)
main.go:
package main
import "fmt"
func main() {
v := "test"
fmt.Println(v)
fmt.Println("Hello World!")
}
build.sh:
#!/usr/bin/env bash
set -e
echo removing old build artifact
rm testapp || true
echo "building"
GOOS=linux GOARCH=amd64 go build -gcflags "all=-N -l"
echo "build done"
docker-compose.yml:
version: '3.7'
services:
testapp:
image: some/testapp:dev
privileged: true
build:
context: .
dockerfile: ./Dockerfile_dev
ports:
- "40000:40000" # delve
- "8080:8080"
volumes:
- ./:/code
- ${GOPATH}/bin/dlv:/code/dlv
cap_add:
- SYS_PTRACE
security_opt:
- seccomp:unconfined
- apparmor:unconfined
restart: always
healthcheck:
test: curl --silent --fail localhost:8080/static/version.txt?healthcheck || exit 1
interval: 10s
retries: 5
timeout: 2s
Dockerfile_dev:
FROM ubuntu
RUN apt-get update && apt install -y tzdata zip ca-certificates curl
# Bring in timezone info; this may not be necessary if go is built inside the container?
WORKDIR /usr/share/zoneinfo
# -0 means no compression. Needed because go's
# tz loader doesn't handle compressed data.
RUN zip -r -0 /zoneinfo.zip .
ENV ZONEINFO /zoneinfo.zip
WORKDIR /code
#CMD ["./testapp"]
CMD ["./dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--log", "--log-output=rpc", "exec", "./testapp"]
VS Code debug console output:
3:52:59 PM, 10/15/2018
InitializeRequest
InitializeResponse
Using GOPATH: C:\Users\<username>\Dev\go
InitializeEvent
SetBreakPointsRequest
All cleared
Creating on: C:\Users\<username>\Dev\go\src\testApp\main.go (C:\Users\<username>\Dev\go\src\testApp\main.go) :7
Error on CreateBreakpoint: could not find C:\Users\<username>\Dev\go\src\testApp\main.go:7
All set:[null]
SetBreakPointsResponse
ConfigurationDoneRequest
ContinueRequest
ContinueResponse
continue state {"Running":false,"Threads":null,"NextInProgress":false,"exited":true,"exitStatus":0,"When":""}
TerminatedEvent
DisconnectRequest
HaltRequest
DisconnectRequest to parent
DisconnectResponse
Bash console output:
$ ./build.sh && docker-compose -f docker-compose.yml up --build
removing old build artifact
building
build done
The Docker Engine you're using is running in swarm mode.
Compose does not use swarm mode to deploy services to multiple nodes in a swarm. All containers will be scheduled on the current node.
To deploy your application across the swarm, use `docker stack deploy`.
Building testapp
Step 1/7 : FROM ubuntu
---> cd6d8154f1e1
Step 2/7 : RUN apt-get update && apt install -y tzdata zip ca-certificates curl
---> Using cache
---> ad36719bc090
Step 3/7 : WORKDIR /usr/share/zoneinfo
---> Using cache
---> b603d79ea208
Step 4/7 : RUN zip -r -0 /zoneinfo.zip .
---> Using cache
---> a4af1a1ad54a
Step 5/7 : ENV ZONEINFO /zoneinfo.zip
---> Using cache
---> fe54a7095b71
Step 6/7 : WORKDIR /code
---> Using cache
---> 4491a3030a0e
Step 7/7 : CMD ["./dlv", "--listen=:40000", "--headless=true", "--api-version=2", "--log", "--log-output=rpc", "exec", "./testapp"]
---> Using cache
---> 5199945d66fa
Successfully built 5199945d66fa
Successfully tagged some/testapp:dev
Starting testapp_testapp_1 ... done
Attaching to testapp_testapp_1
testapp_1 | API server listening at: [::]:40000
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="<- RPCServer.GetVersion(api.GetVersionIn{})" layer=rpc
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="-> *api.GetVersionOut{\"DelveVersion\":\"Version: 1.1.0\\nBuild: $Id: 1990ba12450cab9425a2ae62e6ab988725023d5c $\",\"APIVersion\":2} error: \"\"" layer=rpc
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="<- RPCServer.CreateBreakpoint(rpc2.CreateBreakpointIn{\"Breakpoint\":{\"id\":0,\"name\":\"\",\"addr\":0,\"file\":\"C:\\\\Users\\\\<username>\\\\Dev\\\\go\\\\src\\\\testApp\\\\main.go\",\"line\":7,\"Cond\":\"\",\"continue\":false,\"goroutine\":false,\"stacktrace\":0,\"LoadArgs\":{\"FollowPointers\":true,\"MaxVariableRecurse\":1,\"MaxStringLen\":64,\"MaxArrayValues\":64,\"MaxStructFields\":-1},\"LoadLocals\":{\"FollowPointers\":true,\"MaxVariableRecurse\":1,\"MaxStringLen\":64,\"MaxArrayValues\":64,\"MaxStructFields\":-1},\"hitCount\":null,\"totalHitCount\":0}})" layer=rpc
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="-> *rpc2.CreateBreakpointOut{\"Breakpoint\":{\"id\":0,\"name\":\"\",\"addr\":0,\"file\":\"\",\"line\":0,\"Cond\":\"\",\"continue\":false,\"goroutine\":false,\"stacktrace\":0,\"LoadArgs\":null,\"LoadLocals\":null,\"hitCount\":null,\"totalHitCount\":0}} error: \"could not find C:\\\\Users\\\\<username>\\\\Dev\\\\go\\\\src\\\\testApp\\\\main.go:7\"" layer=rpc
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="(async 3) <- RPCServer.Command(api.DebuggerCommand{\"name\":\"continue\",\"ReturnInfoLoadConfig\":null})" layer=rpc
testapp_1 | test
testapp_1 | Hello World!
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="(async 3) -> rpc2.CommandOut{\"State\":{\"Running\":false,\"Threads\":null,\"NextInProgress\":false,\"exited\":true,\"exitStatus\":0,\"When\":\"\"}} error: \"\"" layer=rpc
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="(async 4) <- RPCServer.Command(api.DebuggerCommand{\"name\":\"halt\",\"ReturnInfoLoadConfig\":null})" layer=rpc
testapp_1 | time="2018-10-15T05:04:58Z" level=debug msg="(async 4) -> <nil>null error: \"Process 12 has exited with status 0\"" layer=rpc
Stopping testapp_testapp_1 ... done
Gracefully stopping... (press Ctrl+C again to force)
Note: all output and config has been slightly santised (with <username>
)
System info:
VS Code 1.28.1 (user setup)
Windows 10 Enterprise 1803
Docker 18.06.1-ce-win73
Edit: added system info