Skip to content

cmd/link: panic on riscv64 with CGO enabled due to empty container symbol #72840

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

Open
imguoguo opened this issue Mar 13, 2025 · 14 comments
Open
Labels
arch-riscv Issues solely affecting the riscv64 architecture. compiler/runtime Issues related to the Go compiler and/or runtime. help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Milestone

Comments

@imguoguo
Copy link

Go version

go version go1.24.1 linux/riscv64

Output of go env in your module/workspace:

AR='ar'                                                                                                                                                  
CC='gcc'
CGO_CFLAGS='-gdwarf-5 -O2'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE='on'
GOARCH='riscv64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/builddir/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/builddir/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build74935071=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='riscv64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/builddir/build/BUILD/golang-1.24.1-build/go/src/go.mod'
GOMODCACHE='/builddir/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/builddir/go'
GOPRIVATE=''
GOPROXY='https://goproxy.cn'
GORISCV64='rva20u64'
GOROOT='/builddir/build/BUILD/golang-1.24.1-build/go'
GOSUMDB='off'
GOTELEMETRY='local'
GOTELEMETRYDIR='/builddir/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='local'
GOTOOLDIR='/builddir/build/BUILD/golang-1.24.1-build/go/pkg/tool/linux_riscv64'
GOVCS=''
GOVERSION='go1.24.1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Built Go (version 1.24.1) on a riscv64 system on Fedora 42 with CGO enabled. Ran the full Go check suite and also attempted a minimal reproduction by isolating tests in the internal/poll directory. In the minimal test setup, I removed others test files in internal/poll and only the test files error_linux_test.go, error_stub_test.go, and error_test.go remained. Furthermore, I experimented with a workaround by commenting out the following code in error_test.go:

import (
        "fmt"
        "io/fs"
//      "net"
        "os"
)

// ...

// if nerr, ok := err.(*net.OpError); ok {
//     err = nerr.Err
// }

and trying to run

cd /builddir/build/BUILD/golang-1.24.1-build/go/src
./run.bash  --no-rebuild -v -v -v -k internal/poll

What did you see happen?

The build fails during the linking phase with a panic. Key parts of the error log include:

panic: unexpected empty container symbol

loadelf: $WORK/b304/_pkg_.a(_x001.o): 183065: sym#47 (".LVUS0"): ignoring symbol in section 8 (".debug_loclists") (type 0)
...

This panic in the linker (cmd/link/internal/loader.(*Loader).AddInteriorSym) prevents the test suite from completing. The workaround of commenting out the code in error_test.go allowed the tests to pass, indicating that the issue might be related to the handling of certain symbols.

And I also tried with CGO disabled(by set CGO_ENABLED=0), test complete successfully without panics.

full build log: http://openkoji.iscas.ac.cn/kojifiles/work/tasks/8787/7038787/build.log
golang spec file: https://src.fedoraproject.org/rpms/golang/blob/rawhide/f/golang.spec

What did you expect to see?

I expected the Go build and test suite to complete successfully without panics, even with CGO enabled on the riscv64 platform. The behavior should be consistent with other architectures where the build passes without the need to modify test files.

@gopherbot gopherbot added the compiler/runtime Issues related to the Go compiler and/or runtime. label Mar 13, 2025
@imguoguo
Copy link
Author

cc @golang/riscv64

@dr2chase dr2chase added the NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one. label Mar 14, 2025
@dr2chase
Copy link
Contributor

When you say "handling of certain symbols", is it possible to be more specific?

@dr2chase
Copy link
Contributor

@golang/compiler

@cherrymui
Copy link
Member

sym#47 (".LVUS0"): ignoring symbol in section 8 (".debug_loclists") (type 0)

Reading the error message, it looks like the error is from loading a symbol from an empty section in a C object. Perhaps we should just ignore it, especially that it is not a loadable section. Perhaps we can ignore the entire debug sections from C object?

@thanm do you know if we use the debug info from C objects in internal linking mode? I think we probably don't. (It may be a good thing to do for the future. But that needs a good amount of effort beyond just loading the symbols. If currently we load the symbols but not doing anything with them, we may as well not load them at all.)

@thanm
Copy link
Contributor

thanm commented Mar 15, 2025

@thanm do you know if we use the debug info from C objects in internal linking mode? I think we probably don't. (It may be a good thing to do for the future. But that needs a good amount of effort beyond just loading the symbols. If currently we load the symbols but not doing anything with them, we may as well not load them at all.)

From looking at the code, it does appear that we're loading up .debug_* sections in the host object loader but then never integrating them into the final debug gen, which I agree is not ideal.

@mknyszek mknyszek added this to the Backlog milestone Mar 19, 2025
@mknyszek mknyszek added arch-riscv Issues solely affecting the riscv64 architecture. help wanted labels Mar 19, 2025
@imguoguo
Copy link
Author

I attempted the following build process and still failed with the same reason:

git clone https://github.com/golang/go
cd go
git checkout go1.24.1
cd src
./all.bash

It is worth noting that I am using the following versions of gcc and ar:

gcc --version
# gcc (GCC) 15.0.1 20250114 (Red Hat 15.0.1-0)

ar --version
# GNU ar version 2.43.50.20250106

Please let me know if any additional details are required.

@luhenry
Copy link

luhenry commented Apr 2, 2025

cc @markdryan @4a6f656c @mengzhuo

@markdryan
Copy link
Contributor

markdryan commented Apr 11, 2025

I've been able to reproduce the issue in a VM with the images here. I used the Fedora-Cloud-Base-Generic-42.20250403-8635a3a5bfcd.riscv64.qcow2 image.

I booted the image, installed gcc-15 and the distro supplied version of go(go1.24rc1). I then cloned Go and built the master branch (ecc06f0). I was able to reproduce the issue with the following simple test case.

package main

import "os/user"

func main() {
        if u, err := user.Current(); err == nil {
                print(u.Name, "\n")
        }
}

Adding some logs into ldelf.go I can see the panic seems to be caused by the presence of the symbol .Letext0 in the _cgo_export.o object file. IIUC correctly, the failure occurs because _cgo_export.o contains the symbol .Letext0 even though the size of its text section is 0. When I build the same reproducer on my VF2 which has gcc-13.3.0 the .Letext0 is not present in the _cgo_export.o file. Nor is it present when I build with go1.24rc1 on an X86 VM running Fedora 42 and gcc-15.

It appears the .Letext0 symbol is present in the symbol table because it is referenced by a data directive in the assembly code generated by gcc-15, i.e., in the disassembly of _cgo_export.s I see

.section        .debug_line,"",@progbits
...
.LELTP0:
        .byte   0
        .uleb128 0x9
        .byte   0x2
        .8byte  .Letext0

There is a comment in the code that generates the panic suggesting that the check might be too strict and could be relaxed.

So I tried disabling the check locally. It fixed the panic but the link of my test program still failed due to unresolved symbols. I'll try to dig a little deeper to understand why that is. I may well have messed up somewhere.

@markdryan
Copy link
Contributor

markdryan commented Apr 11, 2025

Here are the linker errors I'm getting

# repro
loadelf: /home/.cache/go-build/b6/b6183e72d60c0ac39a049dbdd60e3e5e72f15628dae74fccd5bafd6653862cab-d(_x002.o): 107524: sym#80 (".LVUS38"): ignoring symbol in section 8 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/b6/b6183e72d60c0ac39a049dbdd60e3e5e72f15628dae74fccd5bafd6653862cab-d(_x003.o): 107560: sym#45 (".LVUS0"): ignoring symbol in section 8 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x003.o): 107638: sym#45 (".LVUS0"): ignoring symbol in section 8 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x004.o): 107718: sym#88 (".LVUS0"): ignoring symbol in section 9 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x005.o): 107939: sym#229 (".LVUS0"): ignoring symbol in section 9 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x006.o): 108020: sym#89 (".LVUS0"): ignoring symbol in section 9 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x007.o): 108053: sym#41 (".LVUS1"): ignoring symbol in section 8 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x008.o): 108100: sym#55 (".LVUS0"): ignoring symbol in section 8 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x009.o): 108133: sym#41 (".LVUS0"): ignoring symbol in section 7 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x010.o): 108220: sym#95 (".LVUS0"): ignoring symbol in section 10 (".debug_loclists") (type 0)
loadelf: /home/.cache/go-build/1c/1c87991ac6c19ee97971dd0095e4477d2e3bb97b754171033e6852edda482bff-d(_x011.o): 108311: sym#99 (".LVUS16"): ignoring symbol in section 8 (".debug_loclists") (type 0)
os/user._cgo_9bef24737d87_Cfunc_mygetpwuid_r: relocation target _cgo_9bef24737d87_Cfunc_mygetpwuid_r not defined
os/user._cgo_9bef24737d87_Cfunc_sysconf: relocation target _cgo_9bef24737d87_Cfunc_sysconf not defined
runtime.cgo_yield: relocation target _cgo_yield not defined
_cgo_init: relocation target x_cgo_init not defined
_cgo_thread_start: relocation target x_cgo_thread_start not defined
_cgo_notify_runtime_init_done: relocation target x_cgo_notify_runtime_init_done not defined
_cgo_pthread_key_created: relocation target x_cgo_pthread_key_created not defined
_cgo_bindm: relocation target x_cgo_bindm not defined
_cgo_getstackbound: relocation target x_cgo_getstackbound not defined
runtime._cgo_setenv: relocation target x_cgo_setenv not defined
/home/code/go/pkg/tool/linux_riscv64/link: too many errors

If I modify the existing check for riscvc64 and s390 to also skip symbols with a ".LVUS" prefix I'm able to link the simple test program above.

I'll try a full test run with these two changes applied on Fedora42.

@markdryan
Copy link
Contributor

markdryan commented Apr 11, 2025

To summarize, by

  1. Commenting out the first if statement in Loader.AddInteriorSym
  2. Updating the check in ldelf.go to also skip symbols that start with the prefix ".LVUS".

I'm able to get a clean test run of main on a Fedora42 riscv64 VM (with gcc-15).

I can submit a patch but it's not clear to me whether removing the first check in Loader.AddInteriorSym is the correct thing to do. As a reminder, the symbol triggering this panic is .Letext0 in _cgo_export.o (b002/_x001.o) which has a text section of size 0. @cherrymui, @thanm any advice on how to proceed here? I still have the VM so if you need any further information, please let me know.

dustymabe added a commit to dustymabe/coreos-assembler that referenced this issue Apr 22, 2025
This fails with a symbol error. Error reported upstream
in golang/go#72840
dustymabe added a commit to dustymabe/coreos-assembler that referenced this issue Apr 22, 2025
This fails with a symbol error. Error reported upstream
in golang/go#72840
dustymabe added a commit to dustymabe/coreos-assembler that referenced this issue Apr 22, 2025
This fails with a symbol error. Error reported upstream
in golang/go#72840
@markdryan
Copy link
Contributor

A few updates. Unsurprisingly, I can build the test program shown above with

go build -ldflags=-linkmode=external

I've also uploaded two object files that contain the symbols that are upsetting the linker.

  • _x001.o contains the .Letext0 symbol which is defined in an empty .text section
  • _x002.o contains examples of the new LVUS* symbols.

xobjs.tgz

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/668275 mentions this issue: cmd/link: fix cgo on riscv64 when building with gcc-15

@markdryan
Copy link
Contributor

Please ignore that first patch. It's been abandoned. A new patch is coming shortly.

@gopherbot
Copy link
Contributor

Change https://go.dev/cl/668276 mentions this issue: cmd/link: fix cgo on riscv64 when building with gcc-15

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
arch-riscv Issues solely affecting the riscv64 architecture. compiler/runtime Issues related to the Go compiler and/or runtime. help wanted NeedsInvestigation Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.
Projects
Development

No branches or pull requests

8 participants