Jia*_*Jia 7 containers go docker delve
我正在尝试使用 Golang 调试深入构建来容器化我自己的调试版本 Golang 应用程序。\n这是我如何在本地调试我的 Golang 应用程序,它是一个非常简单的 RSS 阅读器。它从我感兴趣的 RSS 提要中检索数据。
\n$on my local terminal$ dlv debug parsedata-xml-fp.go # launch my app with delve\nType 'help' for list of commands.\n(dlv) b main\nCommand failed: Location "main" ambiguous: main.main, runtime.main\xe2\x80\xa6\n(dlv) b main.main\nBreakpoint 1 set at 0x760252 for main.main() ./parsedata-xml-fp.go:50\n(dlv) c\n> main.main() ./parsedata-xml-fp.go:50 (hits goroutine(1):1 total:1) (PC: 0x760252)\n=> 50: func main() {\n 51: // [decode from response.Body]\n 52: url := "https://foreignpolicy.com/feed/"\n 53:\n 54: var URLset Rss\n 55: if xmlBytes, err := getXML(url); err != nil {\n(dlv) l\n> main.main() ./parsedata-xml-fp.go:50 (hits goroutine(1):1 total:1) (PC: 0x760252)\n=> 50: func main() {\n 51: // [decode from response.Body]\n 52: url := "https://foreignpolicy.com/feed/"\n 53:\n 54: var URLset Rss\n 55: if xmlBytes, err := getXML(url); err != nil {\n(dlv) \nRun Code Online (Sandbox Code Playgroud)\n在我的本地计算机上,我可以设置断点并单步执行我感兴趣的函数。
\n我试图在我构建的容器内做同样的事情。
\n选项1: \n下面是我的容器的 Dockerfile
\n#Dockerfile.dlv\nFROM golang:1.17 AS build\n\nWORKDIR /\nCOPY go/app/parsedata-xml-fp.go .\nCOPY go.mod .\nCOPY go.sum .\n \nRUN go install github.com/go-delve/delve/cmd/dlv@latest\nRUN go build -gcflags="all=-N -l" -o /feedme\nRUN echo $(ls /go/bin)\n\n# stage 2 build \nFROM ubuntu:18.04\nWORKDIR /\n\nEXPOSE 2345 \n\nCOPY --from=build /go/bin/dlv /dlv\nCOPY --from=build /feedme /feedme\nCOPY --from=build /parsedata-xml-fp.go /parsedata-xml-fp.go\nCMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"]\nRun Code Online (Sandbox Code Playgroud)\n当启动我的容器并登录时,出现错误:
\nexec: "go": executable file not found in $PATH\nRun Code Online (Sandbox Code Playgroud)\n以下是我的容器中的完整日志
\nsudo docker exec -it b1494552ef1d /bin/sh\n# which dlv\n# ls\nbin dev etc home lib64 mnt parsedata-xml-fp.go root sbin sys usr\nboot dlv feedme lib media opt proc run srv tmp var\n# ./dlv\nDelve is a source level debugger for Go programs.\n ......... # dismiss delve help info , just to confirm dlv is installed \n\nUse "dlv [command] --help" for more information about a command.\n# ./dlv debug parsedata-xml-fp.go\nexec: "go": executable file not found in $PATH\n# which go\n# (nothing)\nRun Code Online (Sandbox Code Playgroud)\n我的理解是ubuntu1804没有安装go?然后我尝试仅使用 go docker image
\n选项#2
\n更新的 Dockerfile 如下:使用golang:1.17作为基础镜像(Go 应该在那里):
\n# Dockerfile.localmod\nFROM golang:1.17 AS build\n\nWORKDIR /\nCOPY go/app/parsedata-xml-fp.go .\nCOPY go.mod .\nCOPY go.sum .\n\nRUN echo $(which shell)\n\nRUN go install github.com/go-delve/delve/cmd/dlv@latest\nRUN go build -gcflags="all=-N -l" -o /feedme\nRUN echo $(ls /go/bin)\n\nEXPOSE 2345 \nCMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"]\nRun Code Online (Sandbox Code Playgroud)\n这次错误发生在我启动容器时
\nsudo docker run 734129d1b1a2 \ndocker: Error response from daemon: failed to create shim: OCI runtime create failed: container_linux.go:380: starting container process caused: exec: "/dlv": stat /dlv: no such file or directory: unknown.\nERRO[0000] error waiting for container: context canceled\nRun Code Online (Sandbox Code Playgroud)\n任何人都可以建议什么是集成深入到我的 Go 容器并在容器终端上调试它的正确方法,就像本地调试一样?
\n问题在于您的dlv二进制文件是动态编译的。当您使用 下载二进制文件时go install,默认情况下它会下载CGO_ENABLED=1(除非覆盖),需要在运行时加载大多数运行时库(包括 glibc)。这在某些不存在库的容器映像中可能无法正常工作(例如从头开始构建的映像/无发行版静态映像)。
因此,为了避免与容器镜像的依赖关系,请始终通过将上述标志设置为 0 来下载静态编译的镜像。在 docker 上下文中使用下载的二进制文件
CGO_ENABLED=0 go install github.com/go-delve/delve/cmd/dlv@latest
Run Code Online (Sandbox Code Playgroud)
您还可以观察静态编译版本和动态编译版本之间的ldd输出。dlv前者不会列出需要动态加载的库,后者会列出它们。
| 归档时间: |
|
| 查看次数: |
2353 次 |
| 最近记录: |