在单独的文件中编译带有调试符号的静态Go二进制文件?

huangapple go评论88阅读模式
英文:

Compile Static Go Binary with Debug Symbols in Separate File?

问题

我记不清我在哪里看到的了,我想可能是在Datadog、NewRelic或者CloudFlare上?但我记得有人提到使用Golang时,在生产环境中运行发布的二进制文件,并在Docker容器中还包含一个单独的文件,其中包含调试符号,以防发生崩溃,以便能够查看发生了什么。

背景

我正在使用以下Dockerfile构建和运行:

# 在一个镜像中进行所有的Docker构建
FROM golang:latest as build

WORKDIR /usr/src/api

COPY go.mod go.sum ./
RUN go mod download

COPY . .

# 使用相关的标志构建应用程序,使其完全自包含以用于scratch容器
RUN CGO_ENABLED=0 GOOS=linux go build -ldflags "-s" -a -installsuffix cgo -o app

# 然后将构建的二进制文件复制到一个空镜像中
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 /

# 默认在开发环境中运行
ENV ENV=dev

EXPOSE 8080

ENTRYPOINT ["/bin/bash"]

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

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

ubuntu:latest中运行就可以正常工作,所以上述编译标志似乎修复了alpinescratch的问题。

问题

在这种环境下,是否可能让go build将调试符号输出到一个单独的文件中,与我的静态二进制文件一起存在于Docker镜像中?

英文:

I can't remember where I saw it, I thought it was on Datadog or on NewRelic or maybe CloudFlare? but I remember someone mentioning that with Golang, they run release binaries in production (of course), and within their Docker containers, they also include a separate file containing debug symbols in case a crash occurs so as to be able to see what happened.

Background

I'm building and running in Docker with a Dockerfile like this:

# 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"]

If I don't use the flags above, the binary will fail to execute in alpine and scratch base images:

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

Running this in ubuntu:latest just works, so the above compile flags seem to fix the issue for alpine and scratch.

Question

With this environment in mind, is it possible to have go build emit debug symbols into a separate file to live alongside my static binary in the Docker image?

答案1

得分: 3

在使用CGO_ENABLED=0构建时,您不需要使用"-a -installsuffix 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

这样应该可以实现您所要求的行为(例如,一个小的生产二进制文件,但也有一个带有符号的备份二进制文件,用于在生产环境中调试问题)。

英文:

You don't need to use " -a -installsuffix cgo" flags when building with CGO_ENABLED=0 -- just setting the environment variable will do the trick.

You are building with "-ldflags -s", which is going to strip out all debug symbols and ELF symbol table information. Instead of doing that, do a regular build, archive that executable (in case you need the symbols later) and then remove symbols using strip. E.g.

 $ 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

That should give you the behavior you're asking for (e.g. a small production binary, but also a backup binary with symbols for debugging problems in production).

答案2

得分: 2

使用go tool compile命令,并使用-E标志来进行调试符号导出。这是你需要的吗?

$ go tool compile -E *.go

输入以下命令获取更多关于如何使用以及可用选项的帮助:

go tool compile

参考链接:

  1. https://golang.org/cmd/compile/
英文:

Use go tool compile using -E flag to Debug symbol export. Is that what you need?

$ go tool compile -E *.go

Type:

go tool compile

for more help regarding how to use it and what are the options available.

Reference:

  1. https://golang.org/cmd/compile/

huangapple
  • 本文由 发表于 2021年5月18日 03:40:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/67576084.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定