Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!

Bug 940197

Summary: sys-apps/fd-10.2.0: segfault on musl system
Product: Gentoo Linux Reporter: Wolfgang Müller <wolf>
Component: Current packagesAssignee: James Le Cuirot <chewi>
Status: RESOLVED FIXED    
Severity: critical CC: chewi, mgorny, wolf
Priority: Normal    
Version: unspecified   
Hardware: AMD64   
OS: Linux   
See Also: https://bugs.gentoo.org/show_bug.cgi?id=922372
https://bugs.gentoo.org/show_bug.cgi?id=938847
https://bugs.gentoo.org/show_bug.cgi?id=937470
Whiteboard:
Package list:
Runtime testing required: ---
Attachments: readelf -a for the segfaulting binary
readelf -a for the working binary

Description Wolfgang Müller 2024-09-24 09:21:50 UTC
I'm seeing a weird segfault with sys-apps/fd-10.2.0 on my musl system:

(gdb) run
Starting program: /usr/bin/fd 

Program received signal SIGSEGV, Segmentation fault.
memcpy () at ../src_musl/src/string/x86_64/memcpy.s:18
warning: 18	../src_musl/src/string/x86_64/memcpy.s: No such file or directory
(gdb) bt
#0  memcpy () at ../src_musl/src/string/x86_64/memcpy.s:18
#1  0x00007ffff7ab7177 in __copy_tls () at ../src_musl/src/env/__init_tls.c:66
#2  0x00007ffff7ab730d in static_init_tls () at ../src_musl/src/env/__init_tls.c:149
#3  0x00007ffff7aae89d in __init_libc () at ../src_musl/src/env/__libc_start_main.c:39
#4  0x00007ffff7aae9c0 in __libc_start_main () at ../src_musl/src/env/__libc_start_main.c:80
#5  0x00007ffff74107f6 in _start ()

Curiously, when building the same version of fd from source, this segfault does not happen. A binary compiled with `ebuild compile`, however, will segfault. If I then run `cargo build --release` in the workdir, it will produce a working binary at `target/release/fd`.

Reproducible: Always

Steps to Reproduce:
1. emerge sys-apps/fd-10.2.0
2. execute /usr/bin/fd
Actual Results:  
'/usr/bin/fd' terminated by signal SIGSEGV (Address boundary error)

Expected Results:  
The program executes correctly.

Portage 3.0.65 (python 3.12.6-final-0, default/linux/amd64/23.0/split-usr/musl/hardened, gcc-13, musl-1.2.4-r2, 6.6.48-gentoo x86_64)
=================================================================
System uname: Linux-6.6.48-gentoo-x86_64-AMD_FX-tm-6300_Six-Core_Processor-with-libc
KiB Mem:    16374644 total,   2060932 free
KiB Swap:   16777208 total,  16774880 free
Timestamp of repository gentoo: Sun, 22 Sep 2024 16:19:06 +0000
Head commit of repository gentoo: 660d63bd7d5970d66acb2cb32afc91aa22957dbb

Timestamp of repository guru: Sat, 21 Sep 2024 09:23:00 +0000
Head commit of repository guru: 7297cb2cbe883f5cd0e830be0633785919f56e0e

Head commit of repository musl: 3f3ac3a07ce7edef0ff88317c22bc056d63d1b2c

Head commit of repository pramantha: 781e68ac5ae03c7d764216f92fc512b2587c49c9

sh bash 5.2_p26-r6
ld GNU ld (Gentoo 2.42 p3) 2.42.0
app-misc/pax-utils:        1.3.7::gentoo
app-shells/bash:           5.2_p26-r6::gentoo
dev-build/autoconf:        2.71-r7::gentoo
dev-build/automake:        1.16.5-r2::gentoo
dev-build/cmake:           3.30.2::gentoo
dev-build/libtool:         2.4.7-r4::gentoo
dev-build/make:            4.4.1-r1::gentoo
dev-build/meson:           1.5.1::gentoo
dev-lang/perl:             5.40.0::gentoo
dev-lang/python:           3.12.6_p2::gentoo
dev-lang/rust-bin:         1.80.1::gentoo
sys-apps/baselayout:       2.15::gentoo
sys-apps/openrc:           0.54.2::gentoo
sys-apps/sandbox:          2.39::gentoo
sys-devel/binutils:        2.42-r1::gentoo
sys-devel/binutils-config: 5.5.2::gentoo
sys-devel/gcc:             13.3.1_p20240614::gentoo
sys-devel/gcc-config:      2.11::gentoo
sys-kernel/linux-headers:  6.6-r1::gentoo (virtual/os-headers)
sys-libs/musl:             1.2.4-r2::gentoo
Repositories:

gentoo
    location: /var/portage/repos/gentoo
    sync-type: git
    sync-uri: https://anongit.gentoo.org/git/repo/sync/gentoo.git
    priority: -1000
    volatile: True
    sync-git-verify-commit-signature: true

guru
    location: /var/portage/repos/guru
    sync-type: git
    sync-uri: https://github.com/gentoo-mirror/guru.git
    masters: gentoo
    volatile: True

musl
    location: /var/portage/repos/musl
    sync-type: git
    sync-uri: https://anongit.gentoo.org/git/proj/musl.git
    masters: gentoo
    volatile: True

pramantha
    location: /var/portage/repos/pramantha
    sync-type: git
    sync-uri: https://git.oriole.systems/pramantha
    masters: gentoo guru
    volatile: True

Installed sets: @kernel, @portage
ACCEPT_KEYWORDS="amd64"
ACCEPT_LICENSE="@FREE"
CBUILD="x86_64-pc-linux-musl"
CFLAGS="-O2 -march=native -mtune=native -pipe"
CHOST="x86_64-pc-linux-musl"
CONFIG_PROTECT="/etc /usr/share/gnupg/qualified.txt"
CONFIG_PROTECT_MASK="/etc/ca-certificates.conf /etc/env.d /etc/gconf /etc/gentoo-release /etc/php/apache2-php8.2/ext-active/ /etc/php/cgi-php8.2/ext-active/ /etc/php/cli-php8.2/ext-active/ /etc/php/fpm-php8.2/ext-active/ /etc/php/phpdbg-php8.2/ext-active/ /etc/revdep-rebuild /etc/sandbox.d /etc/terminfo"
CXXFLAGS="-O2 -march=native -mtune=native -pipe"
DISTDIR="/var/portage/distfiles"
EMERGE_DEFAULT_OPTS="--color=n --ask --alert --autounmask-write=n --jobs 3 --load-average 4"
ENV_UNSET="CARGO_HOME DBUS_SESSION_BUS_ADDRESS DISPLAY GDK_PIXBUF_MODULE_FILE GOBIN GOPATH PERL5LIB PERL5OPT PERLPREFIX PERL_CORE PERL_MB_OPT PERL_MM_OPT XAUTHORITY XDG_CACHE_HOME XDG_CONFIG_HOME XDG_DATA_HOME XDG_RUNTIME_DIR XDG_STATE_HOME"
FCFLAGS="-O2 -pipe"
FEATURES="assume-digests binpkg-docompress binpkg-dostrip binpkg-logs buildpkg-live clean-logs compress-build-logs config-protect-if-modified distlocks downgrade-backup ebuild-locks fixlafiles ipc-sandbox merge-sync merge-wait network-sandbox news parallel-fetch parallel-install pid-sandbox pkgdir-index-trusted preserve-libs protect-owned qa-unresolved-soname-deps sandbox sfperms split-elog split-log strict unknown-features-warn unmerge-logs unmerge-orphans userfetch userpriv usersandbox usersync xattr"
FFLAGS="-O2 -pipe"
GENTOO_MIRRORS="http://distfiles.gentoo.org"
INSTALL_MASK="/usr/share/bash-completion /usr/lib/charset.alias"
LANG="en_IE.UTF-8"
LDFLAGS="-Wl,-O1 -Wl,--as-needed -Wl,-z,pack-relative-relocs"
LEX="flex"
MAKEFLAGS="-j6"
MAKEOPTS="-j6"
PKGDIR="/var/portage/packages"
PORTAGE_COMPRESS=""
PORTAGE_CONFIGROOT="/"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --omit-dir-times --compress --force --whole-file --delete --stats --human-readable --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages --exclude=/.git"
PORTAGE_TMPDIR="/var/tmp"
SHELL="/bin/ksh"
USE="acl amd64 bzip2 caps cet crypt fish-completion hardened iconv icu iproute2 ipv6 libtirpc ncurses nls openmp pam pcre pic pie readline seccomp split-usr ssl ssp test-rust threads unicode xattr xtpax zlib" ABI_X86="64" ADA_TARGET="gcc_12" APACHE2_MODULES="authn_core authz_core socache_shmcb unixd actions alias auth_basic authn_anon authn_dbm authn_file authz_dbm authz_groupfile authz_host authz_owner authz_user autoindex cache cgi cgid dav dav_fs dav_lock deflate dir env expires ext_filter file_cache filter headers include info log_config logio mime mime_magic negotiation rewrite setenvif speling status unique_id userdir usertrack vhost_alias" CALLIGRA_FEATURES="karbon sheets words" COLLECTD_PLUGINS="df interface irq load memory rrdtool swap syslog" CPU_FLAGS_X86="aes avx fma3 fma4 mmx mmxext popcnt sse sse2 sse3 sse4_1 sse4_2 sse4a ssse3 xop" ELIBC="musl" GPSD_PROTOCOLS="ashtech aivdm earthmate evermore fv18 garmin garmintxt gpsclock greis isync itrax mtk3301 ntrip navcom oceanserver oncore rtcm104v2 rtcm104v3 sirf skytraq superstar2 tsip tripmate tnt ublox" GUILE_SINGLE_TARGET="3-0" GUILE_TARGETS="3-0" INPUT_DEVICES="libinput" KERNEL="linux" LCD_DEVICES="bayrad cfontz glk hd44780 lb216 lcdm001 mtxorb text" LUA_SINGLE_TARGET="lua5-1" LUA_TARGETS="lua5-4" OFFICE_IMPLEMENTATION="libreoffice" PHP_TARGETS="php8-2" POSTGRES_TARGETS="postgres15" PYTHON_SINGLE_TARGET="python3_12" PYTHON_TARGETS="python3_12" RUBY_TARGETS="ruby31 ruby32" VIDEO_CARDS="amdgpu fbdev intel nouveau radeon radeonsi vesa dummy" XTABLES_ADDONS="quota2 psd pknock lscan length2 ipv4options ipp2p iface geoip fuzzy condition tarpit sysrq proto logmark ipmark dhcpmac delude chaos account"
Unset:  ADDR2LINE, AR, ARFLAGS, AS, ASFLAGS, CC, CCLD, CONFIG_SHELL, CPP, CPPFLAGS, CTARGET, CXX, CXXFILT, ELFEDIT, EXTRA_ECONF, F77FLAGS, FC, GCOV, GPROF, LC_ALL, LD, LFLAGS, LIBTOOL, LINGUAS, MAKE, NM, OBJCOPY, OBJDUMP, PORTAGE_BINHOST, PORTAGE_BUNZIP2_COMMAND, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS, PYTHONPATH, RANLIB, READELF, RUSTFLAGS, SIZE, STRINGS, STRIP, YACC, YFLAGS
Comment 1 Wolfgang Müller 2024-09-28 23:00:32 UTC
I investigated some more (mainly comparing build environments) and was able to narrow it down to the ebuild environment setting `-Wl,-z,pack-relative-relocs`.

If I use filter-flags to remove those flags from the build, fd works correctly again.
Comment 2 Wolfgang Müller 2024-09-29 10:51:10 UTC
Created attachment 904173 [details]
readelf -a for the segfaulting binary

Since I'm out of my depth here I'm attaching the readelf output for both the working and the segfaulting binary. It seems that in the one that was built with pack-relative-relocs the entire .relr.dyn section is empty (or corrupted?)
Comment 3 Wolfgang Müller 2024-09-29 10:51:44 UTC
Created attachment 904174 [details]
readelf -a for the working binary
Comment 4 Wolfgang Müller 2024-09-29 19:29:51 UTC
Okay, one more piece of information... I don't think sys-apps/fd is dynamically linked. In fact, trying to build sys-apps/ripgrep-14.1.1 (I still have 14.1.0-r1 installed from 2024-07-29, which is dynamically linked) fails with

  = note: /usr/lib/gcc/x86_64-pc-linux-musl/13/../../../../x86_64-pc-linux-musl/bin/ld: cannot find -lpcre2-8: No such file or directory
          collect2: error: ld returned 1 exit status
error: could not compile `ripgrep` (bin "rg") due to 1 previous error

even though https://bugs.gentoo.org/922372 should have been fixed. At this point I'm very confused as to what exactly is going on.
Comment 5 Wolfgang Müller 2024-09-30 05:51:38 UTC
I think I finally found the underlying issue. A recent change to cargo.eclass [1] changed it such that 

local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}"

is run even outside of a cross-compiling environment, overriding the value set in /etc/env.d/50rust-bin-1.80.1, which disables support for static compilation:

CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS="-C target-feature=-crt-static"

Ever since [1], rust packages on musl have been built statically and not dynamically. This should explain all related issues as well (some of which seem to have been solved by setting `-C target-feature=-crt-static` locally in the ebuild.)

After editing the eclass to contain `-C target-feature=-crt-static` in 
CARGO_TARGET_X86_64_UNKNOWN_LINUX_MUSL_RUSTFLAGS, both sys-apps/fd and sys-apps/ripgrep build again, are linked dynamically, and run without issue.

[1] https://gitweb.gentoo.org/repo/gentoo.git/commit/eclass/cargo.eclass?id=27d469a2114b4ad0b3e682854c50c806753eb472
Comment 6 James Le Cuirot gentoo-dev 2024-09-30 23:03:48 UTC
My apologies. I was vaguely aware that musl defaults to static, but I didn't know we changed that default like this. I thought about adding this flag to the eclass unconditionally because I doubt we ever want crt-static. I thought we could even drop the variable from the Rust packages, but that would assume that Cargo is the only way to build Rust code. Let's just respect the variable by appending to it instead since I don't think there's any harm in that. Please could you test the following tiny change.

> @@ -585,7 +585,7 @@ cargo_env() {
>         local -x CARGO_BUILD_TARGET=$(rust_abi)
>         local TRIPLE=${CARGO_BUILD_TARGET//-/_}
>         local TRIPLE=${TRIPLE^^} LD_A=( $(tc-getCC) ${LDFLAGS} )
> -       local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}"
> +       local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" -C strip=none -C linker=${LD_A[0]}"
>         [[ ${#LD_A[@]} -gt 1 ]] && local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")"
>         local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" ${RUSTFLAGS}"
Comment 7 James Le Cuirot gentoo-dev 2024-10-01 09:00:14 UTC
Sorry, it was late and I messed that up. Try tihs.

> --- a/eclass/cargo.eclass
> +++ b/eclass/cargo.eclass
> @@ -584,10 +584,10 @@ cargo_env() {
>         # into link-args along with LDFLAGS.
>         local -x CARGO_BUILD_TARGET=$(rust_abi)
>         local TRIPLE=${CARGO_BUILD_TARGET//-/_}
> -       local TRIPLE=${TRIPLE^^} LD_A=( $(tc-getCC) ${LDFLAGS} )
> -       local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}"
> -       [[ ${#LD_A[@]} -gt 1 ]] && local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")"
> -       local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" ${RUSTFLAGS}"
> +       local CTTR_VAR=CARGO_TARGET_${TRIPLE^^}_RUSTFLAGS LD_A=( $(tc-getCC) ${LDFLAGS} )
> +       local -x "${CTTR_VAR}"="${!CTTR_VAR} -C strip=none -C linker=${LD_A[0]}"
> +       [[ ${#LD_A[@]} -gt 1 ]] && local "${CTTR_VAR}"+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")"
> +       local "${CTTR_VAR}"+=" ${RUSTFLAGS}"
>  
>         (
>                 # These variables will override the above, even if empty, so unset them
Comment 8 Wolfgang Müller 2024-10-01 09:12:54 UTC
Yeah, the previous change wouldn't work because the local command shadows previous scopes completely and the environment variable is not inherited. You can make local inherit the existing variable with the -I flag however. No need for a more complicated setup. I've successfully tested the following on my system:

> @@ -585,7 +585,7 @@ cargo_env() {
>         local -x CARGO_BUILD_TARGET=$(rust_abi)
>         local TRIPLE=${CARGO_BUILD_TARGET//-/_}
>         local TRIPLE=${TRIPLE^^} LD_A=( $(tc-getCC) ${LDFLAGS} )
> -       local -x CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS="-C strip=none -C linker=${LD_A[0]}"
> +       local -Ix CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" -C strip=none -C linker=${LD_A[0]}"
>         [[ ${#LD_A[@]} -gt 1 ]] && local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+="$(printf -- ' -C link-arg=%s' "${LD_A[@]:1}")"
>         local CARGO_TARGET_"${TRIPLE}"_RUSTFLAGS+=" ${RUSTFLAGS}"
Comment 9 Larry the Git Cow gentoo-dev 2024-10-01 20:40:19 UTC
The bug has been closed via the following commit(s):

https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=b4ca7760f8bb83e8d6180d6be48dcbd7af8b3498

commit b4ca7760f8bb83e8d6180d6be48dcbd7af8b3498
Author:     James Le Cuirot <chewi@gentoo.org>
AuthorDate: 2024-10-01 20:37:51 +0000
Commit:     James Le Cuirot <chewi@gentoo.org>
CommitDate: 2024-10-01 20:37:51 +0000

    cargo.eclass: Respect existing CARGO_TARGET_${TRIPLE}_RUSTFLAGS
    
    This variable is used to disable crt-static with musl.
    
    Closes: https://bugs.gentoo.org/940197
    Signed-off-by: James Le Cuirot <chewi@gentoo.org>

 eclass/cargo.eclass | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
Comment 10 James Le Cuirot gentoo-dev 2024-10-01 20:40:55 UTC
Nice trick, thank you! I've given talks on Bash before, but that had escaped me.