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
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.
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?)
Created attachment 904174 [details] readelf -a for the working binary
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.
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
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}"
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
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}"
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(-)
Nice trick, thank you! I've given talks on Bash before, but that had escaped me.