DLV debug issue to go application running in docker container

819 Views Asked by At

I am currently facing an issue related to setting the root token ID to a previous value in the HashiCorp Vault Go code. I have tried debugging the application using dlv debug within a Docker container. However, when attempting to run the application on my Windows machine, it hangs. Although the application eventually runs on the Docker machine, I encountered an issue with the debugger not functioning properly when setting breakpoints.

The question is how can I get delve debugger to properly stop at breakpoints as the application is running in the docker container

To provide a better understanding of the problem, I have attached a minimal reproduction of the issue on GitHub.

What I've tried

  • tried to run the application on windows local but it hangs
  • tried to make sure the go versions match still no luck
1

There are 1 best solutions below

0
On

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.