2

After some package upgrade on my Ubuntu 24.04 I stumbled upon inability to build/install/work with almost any of golang packages.

So, I'm trying to install staticcheck and get the following error:

$ go install -v honnef.co/go/tools/cmd/staticcheck@latest
go: downloading honnef.co/go/tools v0.6.1
go: downloading golang.org/x/tools v0.30.0
go: downloading github.com/BurntSushi/toml v1.4.1-0.20240526193622-a339e1f7089c
go: downloading golang.org/x/exp/typeparams v0.0.0-20231108232855-2478ac86f678
go: downloading golang.org/x/sync v0.11.0
go: downloading golang.org/x/mod v0.23.0
go: downloading golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa
runtime/cgo
# runtime/cgo
/tmp/ccyaXynT.s: Assembler messages:
/tmp/ccyaXynT.s: Internal error (Segmentation fault).
Please report this bug.

My go env is:

$ go env
AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/user/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/user/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=/tmp/go-build3918232214=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/user/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/user/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/user/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.1'
GOWORK=''
PKG_CONFIG='pkg-config'

Removing ~/.cache/go-build doesn't help. After some digging in I figured out exact command causes the error:

WORK=/tmp/go-build94545583
cd /usr/local/go/src/runtime/cgo
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x003.o -c gcc_context.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x004.o -c gcc_fatalf.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x005.o -c gcc_libinit.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x006.o -c gcc_linux_amd64.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x007.o -c gcc_mmap.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x008.o -c gcc_setenv.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x009.o -c gcc_sigaction.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x010.o -c gcc_stack_unix.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x011.o -c gcc_traceback.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x012.o -c gcc_util.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x013.o -c linux_syscall.c
TERM='dumb' gcc -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o $WORK/b331/_x014.o -c gcc_amd64.S
# runtime/cgo
/tmp/ccuohmsg.s: Assembler messages:
/tmp/ccuohmsg.s: Internal error (Segmentation fault).
Please report this bug.

GCC version is 13.3.0. The interesting thing is it's compiled with gcc-9:

$ gcc-9 -I . -fPIC -m64 -pthread -fmessage-length=0 -ffile-prefix-map=$WORK/b331=/tmp/go-build -gno-record-gcc-switches -I $WORK/b331/ -O2 -g -Wall -Werror -fno-stack-protector -Wdeclaration-after-statement -ffile-prefix-map=/usr/local/go=/_/GOROOT -frandom-seed=LT5_d3ncbMuqN3lN9Xk7 -o ~/_x014.o -c gcc_amd64.S

$ echo $?
0

This is go1.25.1 install from go.dev.

What is it? GCC bug? Ubuntu bug? How to solve it?

UPDATE: Both version of gcc produce temporary assembly file and then try to compile it with as utility. I saved this temporary file (added -save-temps option to gcc invocation) and used strace utility to know how this compilers call as on it.

So, gcc version is:

$ as --debug-prefix-map /tmp/go-build94545583/b331=/tmp/go-build --debug-prefix-map usr/local/go=/_/GOROOT -I . -I /tmp/go-build94545583/b331/ --gdwarf-5 --64 -o ~/_x014.o ~/_x014.s 
/home/user/_x014.s: Assembler messages:
/home/user/_x014.s: Internal error (Segmentation fault).
Please report this bug.

And gcc-9 version is:

$ as --gdwarf2 -I . -I /tmp/go-build94545583/b331/ --64 -o ~/_x014.o ~/_x014.s

$ echo $?
0

Since they both use the same version of as compiler the main difference is in -gdwarf2 and -gdwarf5 options. Indeed, if I swap it the file compiles!

Any suggestions? Please.

PS: I uploaded the content of _x014.s to https://gist.github.com/naughtyfox/7e26d52e63b78b60246349b7553c9784

7
  • That github gist is a minimal reproducible example of the _x014.s the GNU assembler chokes on? It's already pretty tiny, so I guess no need to edit it down further, although in general that's something people can do even without knowing assembly, since GNU assembler assumes undefined symbols are external, and the effect of each line is usually pretty much local. (Compiler output doesn't define macros etc.). Commented Oct 6 at 12:22
  • Can't repro with as --version GNU assembler (GNU Binutils) 2.45.0 on my desktop, using as --gdwarf-5 --64 segfault.sor --gdwarf2. (Or with the full copy/pasted command, but my system doesn't have the tmp or usr/local/go directories it references, in case that matters. The -I options shouldn't matter since the .s file doesn't use .include, but I don't know what --debug-prefix-map does.) Anyway, probably this was a GAS bug which has since been fixed. If you look at reporting it upstream, check for duplicates. Or just try out the latest stable Binutils yourself. Commented Oct 6 at 12:26
  • Have you complied with the request to report the assembler bug? Posting a question about it here does not achieve that. Commented Oct 6 at 12:26
  • 2
    Note well that even if the Go assembly code were complete rubbish, the assembler segfaulting is a problem with the assembler itself. Commented Oct 6 at 12:28
  • 2
    @PeterCordes Indeed I found something in binutils bugtracker that looks like what I'm struggling with - sourceware.org/bugzilla/show_bug.cgi?id=33029. It was fixed in 2.45 but I have GNU assembler (GNU Binutils) 2.34.50.20200426. This is the latest binutils available on this version of Ubuntu though... Commented Oct 6 at 13:29

2 Answers 2

1

This looks like https://sourceware.org/bugzilla/show_bug.cgi?id=33029
It was fixed in 2.45, which is the current stable. (I tried as --gdwarf-5 --64 segfault.s with your source on my Arch GNU/Linux desktop which has that version, and it succeeds with your test file. Thanks for finding that bug report after I tested.)

To use new Binutils on a stable Ubuntu, there's probably a third-party repo somewhere (or maybe even an official Canonical if backports repo if that's still a thing) with the latest packages built for your Ubuntu version, since it's a very mainstream package and your Ubuntu version isn't too old.

Or just install the Binutils package manually from a .deb, although then it won't get updated until your next dist-upgrade, since your local will be a higher version number than any security updates. Unlikely for binutils, though. Using a newer binutils (gdb, as, ld, objdump, etc) with your existing GCC versions and other toolchain stuff should just work, although I wouldn't 100% guarantee there aren't any gotchas.


You could also try using Clang's built-in assembler: it's generally compatible with the GNU assembler, although IDK if it supports the same debug-prefix-map stuff if that your build was using.

clang -gdwarf-5 -c foo.s. (One - instead of two since this is a Clang compiler command line, not an assembler command line. The default output file for clang -c is foo.o so I could leave out the -o option, unlike with as where it's a.out. But -o does work the same as for as so you can leave that in.)


That bug report you found suggests a way to avoid triggering the bug: include a .file 0 directive or something like that. If you can tweak the build scripts to prepend or append that line, that might work. Or it might break something, IDK. The bug tracker comment about the commit which fixes the bug is:

Specifying --gdwarf-5 with a source lacking a ".file 0" directive results in this segfault.

  • dwarf2dbg.c (out_debug_str):
    Use files[1] if files[0] is empty regardless of dwarf level.
Sign up to request clarification or add additional context in comments.

Comments

0

THE ANSWER:

I messed up with my system packages. About 5 years ago I placed as and ld utilities to /usr/local/bin for some weird reason. Since /usr/local/bin takes precedence over /usr/bin (where system binutils are located) in my $PATH GO tried to use very old version of as with newer version of GCC. This screw up whole GO ecosystem on my Ubuntu. The solution is to delete it from /usr/local/bin

SOME INTERESTING DETAILS:

There was https://sourceware.org/bugzilla/show_bug.cgi?id=33029 bug indeed. It resulted in segfault while compiling assembler file. Since GO toolchain used custom binary from /usr/local/bin directory updating binutils package didn't help. The most funny thing is I'd never meet this bug if I updated correctly :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.