编译静态 Go 二进制文件,并在单独的文件中使用调试符号?

我不记得我在哪里看到它,我以为它是在Datadog或NewRelic上,或者CloudFlare上?但是我记得有人提到Golang,他们在生产中运行发布二进制文件(当然),在他们的Docker容器中,它们还包括一个单独的文件,其中包含调试符号,以防万一发生崩溃,以便能够看到发生了什么。


背景

我正在使用这样的Dockerfile在Docker中构建和运行:


# do all of our docker building in one image

FROM golang:latest as build


WORKDIR /usr/src/api


COPY go.mod go.sum ./

RUN go mod download


COPY . .


# build the application with relevant flags to make it completely self-contained for a scratch container

RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-s" -a -installsuffix cgo -o app


# and then copy the built binary to an empty image

FROM ubuntu:latest


COPY --from=build /usr/src/api/app /

COPY --from=build /usr/src/api/config.defaults.json /config.json

COPY --from=build /usr/src/api/logo.png /


# default to running in a dev environment

ENV ENV=dev


EXPOSE 8080


ENTRYPOINT ["/bin/bash"]

如果我不使用上面的标志,二进制文件将无法在和基本映像中执行:alpinescratch


standard_init_linux.go:219: exec user process caused: no such file or directory

运行此程序只是工作,因此上面的编译标志似乎可以解决 和 的问题。ubuntu:latestalpinescratch


问题

考虑到此环境,是否可以将调试符号发出到单独的文件中,以便与 Docker 映像中的静态二进制文件一起存在?go build


猛跑小猪
浏览 108回答 2
2回答

慕姐8265434

在使用 CGO_ENABLED=0 进行构建时,您不需要使用 “ -a -installsendfix cgo” 标志 -- 只需设置环境变量即可解决问题。您正在使用“-ldflags -s”进行构建,这将去除所有调试符号和ELF符号表信息。与其这样做,不如进行常规构建,存档该可执行文件(以防以后需要符号),然后使用 strip 删除符号。例如: $ CGO_ENABLED=0 GOOS=linux go build -o app.withsymbols $ cp app.withsymbols /my/archive/for/debugging/production/issues $ strip app.withsymbols -o app.stripped $ cp app.stripped /production/bin这应该给你你所要求的行为(例如,一个小的生产二进制文件,但也是一个备份二进制文件,其中包含用于调试生产中问题的符号)。

侃侃无极

使用标志到 。这是你需要的吗?go tool compile-EDebug symbol export$ go tool compile -E *.go类型:go tool compile以获取有关如何使用它以及可用选项的更多帮助。参考:https://golang.org/cmd/compile/
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go