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

cmd/link: linker fails on linux/amd64 when gcc's annobin plugin is used #58620

Closed
jcajka opened this issue Feb 21, 2023 · 11 comments
Closed

cmd/link: linker fails on linux/amd64 when gcc's annobin plugin is used #58620

jcajka opened this issue Feb 21, 2023 · 11 comments
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@jcajka
Copy link
Contributor

jcajka commented Feb 21, 2023

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

$ go version
go version devel go1.21-7f59bea53c Tue Feb 21 05:09:21 2023 +0000 linux/amd64

Does this issue reproduce with the latest release?

yes, seems to be reproducible at least as far back as go1.18

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

go env Output
GO111MODULE=""
GOARCH="amd64"
GOBIN=""
GOCACHE="/root/.cache/go-build"
GOENV="/root/.config/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GOMODCACHE="/root/go/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="linux"
GOPATH="/root/go"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/go/pkg/tool/linux_amd64"
GOVCS=""
GOVERSION="devel go1.21-7f59bea53c Tue Feb 21 05:09:21 2023 +0000"
GCCGO="gccgo"
GOAMD64="v1"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/loki/go.mod"
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 -pthread -Wl,--no-gc-sections -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build3131861800=/tmp/go-build -gno-record-gcc-switches"

This is with gcc-13.0.1, binutils-2.40 and glibc-2.37

What did you do?

git clone https://github.com/grafana/loki
cd loki
export CGO_CFLAGS="-fplugin=gcc-annobin"
go build -o logcli ./cmd/logcli

What did you expect to see?

Build finishing successfully or more clear error message being displayed.

What did you see instead?

go build -o logcli ./cmd/logcli
# github.com/grafana/loki/cmd/logcli
panic: unexpected empty container symbol

goroutine 1 [running]:
cmd/link/internal/loader.(*Loader).AddInteriorSym(0xc000004300, 0x16c72f, 0x16c73a)
	/go/src/cmd/link/internal/loader/loader.go:1681 +0x21e
cmd/link/internal/loader.(*SymbolBuilder).AddInteriorSym(...)
	/go/src/cmd/link/internal/loader/symbolbuilder.go:212
cmd/link/internal/loadelf.Load(0xc000004300, 0x842820, 0xbbb07?, 0xc0004fe070, {0x7f9f86b0694f, 0x3}, 0x19a8, {0xc000026b40, 0x2d}, 0x0)
	/go/src/cmd/link/internal/loadelf/ldelf.go:622 +0x207d
cmd/link/internal/ld.ldobj.func1(0xc0000ce000, 0xc0026801b0?, {0x7f9f86b0694f?, 0xc0018b9420?}, 0x7?, {0xc000026b40?, 0x12?})
	/go/src/cmd/link/internal/ld/lib.go:2096 +0x79
cmd/link/internal/ld.hostobjs(0xc0000ce000)
	/go/src/cmd/link/internal/ld/lib.go:1185 +0x18d
cmd/link/internal/ld.(*Link).loadlib(0xc0000ce000)
	/go/src/cmd/link/internal/ld/lib.go:602 +0x5b7
cmd/link/internal/ld.Main(_, {0x20, 0x20, 0x1, 0x7, 0x10, 0x0, {0xc00001a3b1, 0x1, 0x1}, ...})
	/go/src/cmd/link/internal/ld/main.go:269 +0xecb
main.main()
	/go/src/cmd/link/main.go:72 +0xdbb

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Feb 21, 2023
@thanm
Copy link
Contributor

thanm commented Feb 21, 2023

Thanks for the report.

I don't have a copy of the annobin plugin on my system, and it does not seem to be especially easy to build from source.

Something seems fishy with your stack trace however -- the Go linker is trying to read host objects, which it only does in internal linking mode. The program that you are building uses CGO, however, and normally we use the external linker for CGO programs. Is there anything special you are doing to force internal linking? Thanks.

@thanm thanm added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Feb 21, 2023
@thanm
Copy link
Contributor

thanm commented Feb 21, 2023

@golang/compiler

@thanm
Copy link
Contributor

thanm commented Feb 21, 2023

Whoops, on closer inspection it looks like there isn't any CGO use in the application itself, just in the various Go libraries (e.g. os/user, net) being linked in.

FYI, you should be able to work around this issue by adding "ldflags=linkmode=external" to your "go build" invocation.

@jcajka
Copy link
Contributor Author

jcajka commented Feb 22, 2023

You can easily reproduce this in the fedora:rawhide container. Fedora have annobin plugin built for its gcc and it is installed by default. For bit of context both issues discovery lays in the default C flags that Fedora uses.

I haven't been able to easily reduce the reproducer for both. I was able to only reproduce it in the build of the loki's logcli. So I think that the size of the binary objects might be a factor or some (Go's?) compiler heuristics.

Forcing the external linker is the workaround for both of the issues, I can confirm that.

Thank you for a quick reply.

@gopherbot
Copy link

Change https://go.dev/cl/470298 mentions this issue: cmd/link: default to external linking with cgo std packages

@gopherbot
Copy link

Change https://go.dev/cl/470835 mentions this issue: Revert "cmd/link: default to external linking with cgo std packages"

gopherbot pushed a commit that referenced this issue Feb 23, 2023
This reverts CL 470298.

Reason for revert: causes issues with Google internal testing.

Updates #58619.
Updates #58620.

Change-Id: Ic6601820ba8758ef96b71e32d9ffc549c36d5c98
Reviewed-on: https://go-review.googlesource.com/c/go/+/470835
Reviewed-by: Russ Cox <rsc@golang.org>
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Than McIntosh <thanm@google.com>
Reviewed-by: Than McIntosh <thanm@google.com>
Reviewed-by: Cherry Mui <cherryyz@google.com>
@gopherbot
Copy link

Change https://go.dev/cl/471055 mentions this issue: cmd/go: request external linking for all CGO use

@gopherbot
Copy link

Change https://go.dev/cl/475375 mentions this issue: cmd/go,cmd/link: prefer external linking when strange cgo flags seen

gopherbot pushed a commit that referenced this issue Mar 14, 2023
This patch changes the Go command to examine the set of compiler
flags feeding into the C compiler when packages that use cgo are built.
If any of a specific set of strange/dangerous flags are in use,
then the Go command generates a token file ("preferlinkext") and
embeds it into the compiled package's archive.

When the Go linker reads the archives of the packages feeding into the
link and detects a "preferlinkext" token, it will then use external
linking for the program by default (although this default can be
overridden with an explicit "-linkmode" flag).

The intent here is to avoid having to teach the Go linker's host object
reader to grok/understand the various odd symbols/sections/types that
can result from boutique flag use, but rather to just boot the objects
in question over to the C linker instead.

Updates #58619.
Updates #58620.
Updates #58848.

Change-Id: I56382dd305de8dac3841a7a7e664277826061eaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/475375
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
@thanm
Copy link
Contributor

thanm commented Mar 14, 2023

OK, this issue should now be resolved by CL 475375, just submitted this morning. Thanks.

@thanm thanm closed this as completed Mar 14, 2023
@gopherbot
Copy link

Change https://go.dev/cl/476576 mentions this issue: cmd/go,cmd/link: prefer external linking when strange cgo flags seen

@gopherbot
Copy link

Change https://go.dev/cl/476577 mentions this issue: cmd/go,cmd/link: prefer external linking when strange cgo flags seen

gopherbot pushed a commit that referenced this issue Mar 17, 2023
… strange cgo flags seen

This patch changes the Go command to examine the set of compiler
flags feeding into the C compiler when packages that use cgo are built.
If any of a specific set of strange/dangerous flags are in use,
then the Go command generates a token file ("preferlinkext") and
embeds it into the compiled package's archive.

When the Go linker reads the archives of the packages feeding into the
link and detects a "preferlinkext" token, it will then use external
linking for the program by default (although this default can be
overridden with an explicit "-linkmode" flag).

The intent here is to avoid having to teach the Go linker's host object
reader to grok/understand the various odd symbols/sections/types that
can result from boutique flag use, but rather to just boot the objects
in question over to the C linker instead.

Fixes #59051.
Updates #58619.
Updates #58620.
Updates #58848.

Change-Id: I56382dd305de8dac3841a7a7e664277826061eaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/475375
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 035db07)
Reviewed-on: https://go-review.googlesource.com/c/go/+/476577
gopherbot pushed a commit that referenced this issue Mar 17, 2023
… strange cgo flags seen

This patch changes the Go command to examine the set of compiler
flags feeding into the C compiler when packages that use cgo are built.
If any of a specific set of strange/dangerous flags are in use,
then the Go command generates a token file ("preferlinkext") and
embeds it into the compiled package's archive.

When the Go linker reads the archives of the packages feeding into the
link and detects a "preferlinkext" token, it will then use external
linking for the program by default (although this default can be
overridden with an explicit "-linkmode" flag).

The intent here is to avoid having to teach the Go linker's host object
reader to grok/understand the various odd symbols/sections/types that
can result from boutique flag use, but rather to just boot the objects
in question over to the C linker instead.

Fixes #59050.
Updates #58619.
Updates #58620.
Updates #58848.

Change-Id: I56382dd305de8dac3841a7a7e664277826061eaa
Reviewed-on: https://go-review.googlesource.com/c/go/+/475375
Reviewed-by: Cherry Mui <cherryyz@google.com>
Reviewed-by: Bryan Mills <bcmills@google.com>
Run-TryBot: Than McIntosh <thanm@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
(cherry picked from commit 035db07)
Reviewed-on: https://go-review.googlesource.com/c/go/+/476576
@golang golang locked and limited conversation to collaborators Mar 14, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
compiler/runtime Issues related to the Go compiler and/or runtime. FrozenDueToAge NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
None yet
Development

No branches or pull requests

4 participants