DLV 调试问题转到在 docker 容器中运行的应用程序

DLV debug issue to go application running in docker container

提问人:Michael Odumosu 提问时间:6/14/2023 最后编辑:Michael Odumosu 更新时间:6/14/2023 访问量:310

问:

我目前面临与将根令牌 ID 设置为 HashiCorp Vault Go 代码中的先前值相关的问题。我尝试在 Docker 容器中使用 dlv debug 调试应用程序。但是,当尝试在我的 Windows 计算机上运行应用程序时,它挂起。尽管应用程序最终在 Docker 计算机上运行,但我在设置断点时遇到了调试器无法正常运行的问题。

问题是,当应用程序在 docker 容器中运行时,我如何让 delve 调试器在断点处正确停止

为了更好地理解这个问题,我在 GitHub 上附上了该问题的最小复制。

我试过什么

  • 尝试在 Windows 本地上运行应用程序,但它挂起
  • 试图确保 Go 版本匹配仍然没有运气
Docker Go HashiCorp Delve DLV

评论

1赞 James Z 6/14/2023
请在这里提出问题。不要指望人们会去其他地方找到你的问题。

答:

0赞 Zeke Lu 6/14/2023 #1

如果你仔细查看日志,你会看到这样的内容:

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"

它无法在文件上设置断点 。正确的文件位置是 。/usr/src/app/minimal_repro/main.go/usr/src/app/main.go

这是您的文件:.vscode/launch.json

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

这是目录结构:

├── minimal_repro
│   ├── Dockerfile
│   ├── go.mod
│   └── main.go
└── .vscode
    ├── launch.json
    └── tasks.json

替换为将解决该问题。"cwd": "${workspaceFolder}""cwd": "${workspaceFolder}/minimal_repro"


根据 vscode-go 调试,已弃用。请改用。使用 ,如下所示:remotePathsubstitutePathsubstitutePath.vscode/launch.json

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

关于此代码:

fmt.Println("dont print the next line")
log.Print("dont print the next line")
fmt.Println("starting web server")
log.Print("starting web server")

生成以下输出:

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

这很可能是由于写入缓存造成的。这个问题应该在其他地方讨论。我没有手动讨论的链接,由于它对这个问题的主要问题并不重要,所以我暂时忽略它。


这是你的: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"]

请注意,编译并开始调试当前目录中的主包。它不执行由 生成的那个。如果要调试预编译的可执行文件,请改用。dlv debugRUN go build -gcflags="all=-N -l" -v -o /usr/local/bin/app ./...dlv exec