If you look carefully in the log, you will see something like this:
2023-06-14T00:58:37Z debug layer=rpc <- RPCServer.CreateBreakpoint(rpc2.CreateBreakpointIn{"Breakpoint":{"id":0,"name":"","addr":0,"addrs":null,"addrpid":null,"file":"/usr/src/app/minimal_repro/main.go","line":15,"Cond":"","HitCond":"","HitCondPerG":false,"continue":false,"traceReturn":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},"WatchExpr":"","WatchType":0,"hitCount":null,"totalHitCount":0,"disabled":false},"LocExpr":"","SubstitutePathRules":null,"Suspended":false})
2023-06-14T00:58:37Z debug layer=rpc -> *rpc2.CreateBreakpointOut{"Breakpoint":{"id":0,"name":"","addr":0,"addrs":null,"addrpid":null,"file":"","line":0,"Cond":"","HitCond":"","HitCondPerG":false,"continue":false,"traceReturn":false,"goroutine":false,"stacktrace":0,"LoadArgs":null,"LoadLocals":null,"WatchExpr":"","WatchType":0,"hitCount":null,"totalHitCount":0,"disabled":false}} error: "could not find file /usr/src/app/minimal_repro/main.go"
It could not set the breakpoint on the file /usr/src/app/minimal_repro/main.go
. The correct file location is /usr/src/app/main.go
.
This is your .vscode/launch.json
file:
{
"version": "0.2.0",
"configurations": [
{
"name": "Connect to server",
"type": "go",
"request": "attach",
"mode": "remote",
"remotePath": "/usr/src/app/",
"port": 2345,
"host": "127.0.0.1",
"cwd": "${workspaceFolder}",
"trace": "verbose"
}
]
}
And this is the directory structure:
├── minimal_repro
│ ├── Dockerfile
│ ├── go.mod
│ └── main.go
└── .vscode
├── launch.json
└── tasks.json
Replace "cwd": "${workspaceFolder}"
with "cwd": "${workspaceFolder}/minimal_repro"
will address the issue.
According to vscode-go debugging, remotePath
is deprecated. Use substitutePath
instead. With substitutePath
, .vscode/launch.json
looks like this:
{
"version": "0.2.0",
"configurations": [
{
"name": "Connect to server",
"type": "go",
"request": "attach",
"mode": "remote",
"port": 2345,
"host": "127.0.0.1",
"substitutePath": [
{
"from": "${workspaceFolder}/minimal_repro",
"to": "/usr/src/app"
}
],
"trace": "verbose"
}
]
}
Regarding that this code:
fmt.Println("dont print the next line")
log.Print("dont print the next line")
fmt.Println("starting web server")
log.Print("starting web server")
Generates this output:
dont print the next line
starting web server
2023/06/14 01:20:31 dont print the next line
2023/06/14 01:20:31 starting web server
This is most likely due to the write cache. This issue should have been discussed somewhere else. I don't have the link to the discussion by hand, and since it's not important to the main issue in this question, I will ignore it for now.
This is your Dockerfile
:
FROM golang:1.20.5-buster
WORKDIR /usr/src/app
COPY go.mod go.* ./
RUN go mod download && go mod verify
RUN go install github.com/go-delve/delve/cmd/dlv@latest
COPY . .
RUN go build -gcflags="all=-N -l" -v -o /usr/local/bin/app ./...
EXPOSE 2345
EXPOSE 5001
CMD ["dlv","debug","--listen=:2345","--headless=true","--api-version=2","--accept-multiclient","--log","--log-output=rpc,dap"]
# CMD ["dlv","debug","--api-version=2"]
# ENTRYPOINT ["bash"]
Please note that dlv debug
compiles and begins debugging main package in current directory. It does not exec the one generated by RUN go build -gcflags="all=-N -l" -v -o /usr/local/bin/app ./...
. Use dlv exec
instead if you want to debug a pre-compiled executable.