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

问题描述 投票:0回答:1

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

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

为了更好地理解该问题,我在 GitHub 上附上了该问题的最小重现。

我尝试过的事情

  • 尝试在 Windows 本地运行该应用程序,但它挂起
  • 试图确保 go 版本匹配仍然没有运气
docker go hashicorp delve
1个回答
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 调试

remotePath
已弃用。请使用
substitutePath
代替。对于
substitutePath
.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 debug
编译并开始调试当前目录中的主包。它不会执行
RUN go build -gcflags="all=-N -l" -v -o /usr/local/bin/app ./...
生成的那个。如果您想调试预编译的可执行文件,请使用
dlv exec

© www.soinside.com 2019 - 2024. All rights reserved.