我试图用Golang调试深入构建我自己的调试版本Golang应用程序。这里是我如何在本地调试我的Golang应用程序,它是一个非常简单的RSS阅读器。它从我感兴趣的RSS提要中检索数据。
$on my local terminal$ dlv debug parsedata-xml-fp.go # launch my app with delve
Type 'help' for list of commands.
(dlv) b main
Command failed: Location "main" ambiguous: main.main, runtime.main…
(dlv) b main.main
Breakpoint 1 set at 0x760252 for main.main() ./parsedata-xml-fp.go:50
(dlv) c
> main.main() ./parsedata-xml-fp.go:50 (hits goroutine(1):1 total:1) (PC: 0x760252)
=> 50: func main() {
51: // [decode from response.Body]
52: url := "https://foreignpolicy.com/feed/"
53:
54: var URLset Rss
55: if xmlBytes, err := getXML(url); err != nil {
(dlv) l
> main.main() ./parsedata-xml-fp.go:50 (hits goroutine(1):1 total:1) (PC: 0x760252)
=> 50: func main() {
51: // [decode from response.Body]
52: url := "https://foreignpolicy.com/feed/"
53:
54: var URLset Rss
55: if xmlBytes, err := getXML(url); err != nil {
(dlv) 在我的本地机器上,我可以设置断点并进入我感兴趣的函数。
我也想在我做的容器里做同样的事。
选项1:下面的是我的容器的Dockerfile
#Dockerfile.dlv
FROM golang:1.17 AS build
WORKDIR /
COPY go/app/parsedata-xml-fp.go .
COPY go.mod .
COPY go.sum .
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -gcflags="all=-N -l" -o /feedme
RUN echo $(ls /go/bin)
# stage 2 build
FROM ubuntu:18.04
WORKDIR /
EXPOSE 2345
COPY --from=build /go/bin/dlv /dlv
COPY --from=build /feedme /feedme
COPY --from=build /parsedata-xml-fp.go /parsedata-xml-fp.go
CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"]当启动我的容器并登录时,我会出错:
exec: "go": executable file not found in $PATH下面是我的集装箱中的完整日志
sudo docker exec -it b1494552ef1d /bin/sh
# which dlv
# ls
bin dev etc home lib64 mnt parsedata-xml-fp.go root sbin sys usr
boot dlv feedme lib media opt proc run srv tmp var
# ./dlv
Delve is a source level debugger for Go programs.
......... # dismiss delve help info , just to confirm dlv is installed
Use "dlv [command] --help" for more information about a command.
# ./dlv debug parsedata-xml-fp.go
exec: "go": executable file not found in $PATH
# which go
# (nothing)我的理解是ubuntu1804没有安装go?然后,我尝试只使用go码头图像。
选项2
更新后的Dockerfile如下:使用golang:1.17作为基本映像(Go应该在那里):
# Dockerfile.localmod
FROM golang:1.17 AS build
WORKDIR /
COPY go/app/parsedata-xml-fp.go .
COPY go.mod .
COPY go.sum .
RUN echo $(which shell)
RUN go install github.com/go-delve/delve/cmd/dlv@latest
RUN go build -gcflags="all=-N -l" -o /feedme
RUN echo $(ls /go/bin)
EXPOSE 2345
CMD ["/dlv", "--listen=:2345", "--headless=true", "--api-version=2", "--accept-multiclient", "exec", "/feedme"]这一次错误发生在我引导我的容器时。
sudo docker run 734129d1b1a2
docker: 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.
ERRO[0000] error waiting for container: context canceled任何人都可以建议什么是正确的集成方式,深入研究我的Go容器,并在容器终端上调试它,就像在本地调试一样?
发布于 2022-06-09 10:43:58
问题在于动态编译dlv二进制文件。当您用go install下载二进制文件时,默认情况下它是用CGO_ENABLED=1下载的(除非是overriden),这需要在运行时加载大多数运行时库(包括glibc)。在一些没有库的容器映像中,这可能不能很好地工作(例如,从零开始构建的图像/无发行版的静态映像)。
因此,为了避免与容器映像的依赖关系,始终通过将上述标志设置为0来下载静态编译的依赖项。在docker上下文中使用下载的二进制文件。
CGO_ENABLED=0 go install github.com/go-delve/delve/cmd/dlv@latest您还可以在静态版本和动态编译版本之间观察ldd在dlv上的输出。前者将列出不需要动态加载的库,后者将列出它们。
https://stackoverflow.com/questions/72539868
复制相似问题