简体   繁体   中英

Compile Static Go Binary with Debug Symbols in Separate File?

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?

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/

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. Eg

 $ 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 (eg a small production binary, but also a backup binary with symbols for debugging problems in production).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM