Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

go build: produces broken static pie files when build with go build instead of go build -o outfile source.go #62173

Closed
bluec0re opened this issue Aug 21, 2023 · 3 comments

Comments

@bluec0re
Copy link

What version of Go are you using (go version)?

$ go version
go version go1.20.7 linux/amd64

Does this issue reproduce with the latest release?

No. While filing this bug, I noticed that it works with go 1.21 (build pipelines are still using 1.20) and I figured would be still worth reporting

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GO111MODULE=""
GOARCH="amd[6](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:7)4"
GOBIN=""
GOCACHE="/home/runner/.cache/go-build"
GOENV="/home/runner/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/runner/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/runner/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/hostedtoolcache/go/1.20.[7](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:8)/x64"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/hostedtoolcache/go/1.20.7/x64/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.7"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="0"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build57144[9](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:10)650=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Compiling a static PIE binary with forced external linking. (-tags netgo,osusergo,static_build -buildmode=pie -trimpath -ldflags '-extldflags -static-pie -extld gcc -linkmode external').

Note: The bug only manifests if the binary was build with go build $FLAGS, not when build with go build $FLAGS -o outfile main.go

What did you expect to see?

Compiles successfully and runs.

What did you see instead?

Sometimes an error/warning loadinternal: cannot find runtime/cgo but build ends successfully. The binary then crashes on startup

build output
go version go1.20.7 linux/amd64
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/runner/.cache/go-build"
GOENV="/home/runner/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/home/runner/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/home/runner/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/opt/hostedtoolcache/go/1.20.7/x64"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/opt/hostedtoolcache/go/1.20.7/x64/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="go1.20.7"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="0"
GOMOD="/dev/null"
GOWORK=""
CGO_CFLAGS="-O2 -g"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-O2 -g"
CGO_FFLAGS="-O2 -g"
CGO_LDFLAGS="-O2 -g"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build[5](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:6)71449[6](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:7)50=/tmp/go-build -gno-record-gcc-switches"
# mod
 # build
# github.com/bluec0re/go-static-pie-bug
loadinternal: cannot find runtime/cgo
 # build -o foo.go main.go
# path
 # build
# github.com/bluec0re/go-static-pie-bug
loadinternal: cannot find runtime/cgo
 # build -o foo.go main.go
# file
mod/go-static-pie-bug:  ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), static-pie linked, BuildID[sha1]=cf3f6d[7](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:8)9942b40e6eb0467ba[8](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:9)[9](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:10)d34a19b646c033, for GNU/Linux 3.2.0, with debug_info, not stripped
path/go-static-pie-bug: ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), static-pie linked, BuildID[sha1]=cf5db9dc6c43af4e3f243d5fc4486f637281514e, for GNU/Linux 3.2.0, with debug_info, not stripped
mod/foo:                ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), static-pie linked, BuildID[sha1]=f57a846177a64196a35318f6865cf0eda8615a7c, for GNU/Linux 3.2.0, with debug_info, not stripped
path/foo:               ELF 64-bit LSB pie executable, x86-64, version 1 (GNU/Linux), static-pie linked, BuildID[sha1]=5d1c[11](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:12)d6dc66b7b56bb81f279b99f2bb1ccab33d, for GNU/Linux 3.2.0, with debug_info, not stripped
# ldd
mod/go-static-pie-bug:
	statically linked
path/go-static-pie-bug:
	statically linked
mod/foo:
	statically linked
path/foo:
	statically linked
# deadcode
mod/main.go:	fmt.Println("This is not used")
# exec
./mod/go-static-pie-bug
./test.sh: line 45:  30[17](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:18) Trace/breakpoint trap   (core dumped) $b
./path/go-static-pie-bug
./test.sh: line 45:  30[19](https://github.com/bluec0re/go-static-pie-bug/actions/runs/5923174296/job/16058323972#step:4:20) Trace/breakpoint trap   (core dumped) $b
./mod/foo
Hello world
./path/foo
Hello world
@bcmills
Copy link
Contributor

bcmills commented Aug 21, 2023

You are overriding cmd/go's choice of linker flags to request something incompatible: your go env reports CGO_ENABLED="0" but setting -linkmode external in your -ldflags requests that the build use a C linker.

You cannot safely link a Go program using a C linker without Go runtime support for the things that the C linker may incorporate into the binary.

@bcmills
Copy link
Contributor

bcmills commented Aug 21, 2023

Duplicate of #46330

@bcmills bcmills marked this as a duplicate of #46330 Aug 21, 2023
@bcmills bcmills closed this as not planned Won't fix, can't repro, duplicate, stale Aug 21, 2023
@bluec0re
Copy link
Author

Yes, that is intended. The goal is to have a fully static pie binary, ideally build with pure go.

Without forcing gcc as linker, the binary will not be PIE, just static.

Please note that

CGO_ENABLED=0 go build -tags=netgo,osusergo,static_build -buildmode=pie -trimpath -ldflags -extldflags -static-pie -extld gcc -linkmode external -o some_binary main.go

doesn't seem to require cgo, while

CGO_ENABLED=0 go build -tags=netgo,osusergo,static_build -buildmode=pie -trimpath -ldflags -extldflags -static-pie -extld gcc -linkmode external

does.

A binary compiled with the first version works fine (I'm using this variant since go 1.13 now without a single crash or bug outside of my very own). I just recently changed something in the build pipeline , using the variant without explicit -o and source files, and that is what caused cgo dependencies and crashes.

@golang golang locked and limited conversation to collaborators Aug 24, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants