nix-rust / nix

Rust friendly bindings to *nix APIs
MIT License
2.66k stars 666 forks source link

nix 0.26 can't work on ubuntu16.04 #1972

Open rise0chen opened 1 year ago

rise0chen commented 1 year ago
fn main() {
    println!("{:?}", nix::unistd::gethostname());
}
= note: /root/build/release/deps/libnix-fca8cee73dd370df.rlib(nix-fca8cee73dd370df.nix.9961a42b-cgu.2.rcgu.o): In function `nix::sys::memfd::memfd_create::hbef039c9926ba4f0':
          nix.9961a42b-cgu.2:(.text._ZN3nix3sys5memfd12memfd_create17hbef039c9926ba4f0E+0x5): undefined reference to `memfd_create'
          collect2: error: ld returned 1 exit status

  = help: some `extern` functions couldn't be found; some native libraries may need to be installed or have their path specified
  = note: use the `-l` flag to specify native libraries to link
  = note: use the `cargo:rustc-link-lib` directive to specify the native libraries to link with Cargo (see https://doc.rust-lang.org/cargo/reference/build-scripts.html#cargorustc-link-libkindname)
root@f0fca0e971de:~/rc3.1# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/5/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 5.4.0-6ubuntu1~16.04.12' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs --enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-5 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.12) 
asomers commented 1 year ago

According to the online man pages, that function should be available in Ubuntu 16.04. Could you please do objdump -T /lib/x86_64-linux-gnu/libc.so.6 | grep memfd and paste the results? https://manpages.ubuntu.com/manpages/xenial/man2/memfd_create.2.html

rise0chen commented 1 year ago
root@f0fca0e971de:~/rc3.1# objdump -T /lib/x86_64-linux-gnu/libc.so.6 | grep memfd
root@f0fca0e971de:~/rc3.1# 

It is empty. You can test it in docker image. https://hub.docker.com/_/ubuntu

rise0chen commented 1 year ago

The problem is caused by this commit https://github.com/nix-rust/nix/commit/cf15c2bb5505231bc3128ef61522336e315e2169

asomers commented 1 year ago

Even if memfd_create isn't included in your libc, I don't understand why the compile would fail. Normally the Rust linker eliminates unused code, so it's no problem if a symbol like memfd_create is undefined, if you don't use it. Are you using any weird compiler settings? And what version of Rust are you using anyway?

rise0chen commented 1 year ago

You can test this code in ubuntu:16.04 with docker.

rustc 1.65.0 (897e37553 2022-11-02)

rise0chen commented 1 year ago

I have updated to the latest stable rust. It also can't work. stable-x86_64-unknown-linux-gnu updated - rustc 1.67.1 (d5a82bbd2 2023-02-07) (from rustc 1.65.0 (897e37553 2022-11-02))

jszwedko commented 1 year ago

We are seeing this as well for https://github.com/vectordotdev/vector when building on CentOS 7 which has:

$ ldd --version ldd
ldd (GNU libc) 2.17
Copyright (C) 2012 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Written by Roland McGrath and Ulrich Drepper.

We build on CentOS 7 specifically to link against an older libc version for broader platform support.

asomers commented 1 year ago

Ubuntu 16.04 is EoL. Is CentOS 7?

jszwedko commented 1 year ago

I don't think Ubuntu 16.04 is EoL. It seems to be supported through April of 2026 (see https://ubuntu.com/about/release-cycle).

CentOS 7 appears to be supported through 2024-06-30 (see https://wiki.centos.org/About/Product).

asomers commented 1 year ago

But only in Expanded Security Maintenance, it seems.

Anyway, I can reproduce your problem only if I use RUSTFLAGS=-C link-dead-code. I think your linker probably has different default behavior. If you pass --as-needed to the linker, I think it will fix your problem.

jszwedko commented 1 year ago

Thanks for the tip! I tried --as-needed, but am still seeing the same error. For reference, we are using ld as the linker:

$ ld --version
GNU ld version 2.27-44.base.el7
Copyright (C) 2016 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

To reproduce, you can checkout https://github.com/vectordotdev/vector at 2b28408eae2b3c43a9e88d701e57fc50cd25fad7 and run cargo build --no-default-features --features target-x86_64-unknown-linux-gnu.

Would it be useful for me to bisect nix down to the commit that introduces the issue? Or do you already have an idea of what the change is?

jszwedko commented 1 year ago

Notably, we are actually already using nix 0.26.2 in https://github.com/vectordotdev/vector. It was only with upgrade of rustyline to 11.0.0 (that includes a bump in dependency on nix) that introduces the issue: https://github.com/vectordotdev/vector/pull/16517. I'm guessing due to feature flag unification.

jszwedko commented 1 year ago

The problem is caused by this commit cf15c2b

Aha, nevermind, I see the commit was already identified 😄

asomers commented 1 year ago

@jszwedko how did you enable as-needed ?

jszwedko commented 1 year ago

@jszwedko how did you enable as-needed ?

I ran:

RUSTFLAGS="-C linkarg=-Wl,--as-needed" cargo build --no-default-features --features target-x86_64-unknown-linux-gnu

Does that seem right to you?

jszwedko commented 1 year ago

Reading https://wiki.gentoo.org/wiki/Project:Quality_Assurance/As-needed it isn't clear to me how --as-needed is supposed to resolve the issue but I might be missing something. That flag seems to be intended to be used to exclude entire libraries when symbols are unused rather than symbols within linked libraries. It is also possible thatmemfd_create is being called?

asomers commented 1 year ago

No, memfd_create definitely isn't being called. And it could be that --as-needed isn't the right flag to use.

jszwedko commented 1 year ago

Hey all,

I just wanted to check in if there were any other suggested work-arounds we could try here. For now we are maintaining a fork of nix to maintain compatibility with glibc 2.17, but this adds a bit of maintenance overhead for us.

asomers commented 1 year ago

On Fri, Mar 24, 2023 at 2:48 PM Jesse Szwedko @.***> wrote:

Hey all,

I just wanted to check in if there were any other suggested work-arounds we could try here. For now we are maintaining a fork of nix to maintain compatibility with glibc 2.17, but this adds a bit of maintenance overhead for us.

— Reply to this email directly, view it on GitHub https://github.com/nix-rust/nix/issues/1972#issuecomment-1483456876, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA7VOKT5R3IAVIJDBYQYT3W5YJDZANCNFSM6AAAAAAT4I3HDU . You are receiving this because you commented.

Have you tried asking on https://internals.rust-lang.org/ ? That community might know what linker option you need.

Message ID: @.***>

jszwedko commented 1 year ago

Will do. I want to try to whittle this down to an MRE first.

I actually can't reproduce using your repo, @rise0chen. I tried with Rust 1.67.1 on ubuntu:16.04. Was there anything else special you were doing? Are you still able to reproduce?

I can still reproduce using https://github.com/vectordotdev/vector at f4043524b on using cargo build --no-default-features --features target-x86_64-unknown-linux-gnu and Rust 1.66.1:

  = note: /home/ubuntu/vector/target/debug/deps/libnix-dfb69d4a57123ca8.rlib(nix-dfb69d4a57123ca8.nix.d6c48679-cgu.15.rcgu.o): In function `nix::sys::memfd::memfd_create::h5767f84c9448a5b9':
          /home/ubuntu/.cargo/registry/src/github.com-1ecc6299db9ec823/nix-0.26.2/src/sys/memfd.rs:56: undefined reference to `memfd_create'
          collect2: error: ld returned 1 exit status

It still seems odd that Vector was already depending on nix 0.26.2 already but it wasn't until we bumped rustyline, which included a bump of its dependency on nix from 0.25.1 to 0.26.2, that we started to see the build error.

rise0chen commented 1 year ago

It can work when I set

[profile.dev]
lto = true

[profile.release]
lto = true

in Cargo.toml

Ralith commented 12 months ago

LTO does not (reliably) solve this. This should be fixed in nix by making a syscall directly rather than relying on the glibc binding. Alternatively, it could be feature gated.