Skip to content
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

Minimum Supported glibc version #1412

Open
2 tasks
gnzlbg opened this issue Jun 27, 2019 · 3 comments
Open
2 tasks

Minimum Supported glibc version #1412

gnzlbg opened this issue Jun 27, 2019 · 3 comments
Labels
O-gnu S-waiting-on-decision version-support This is a discussion related to supported versions that may require a decision.
Milestone

Comments

@gnzlbg
Copy link
Contributor

gnzlbg commented Jun 27, 2019

IIRC, the current minimum supported glibc version on x86_64-unknown-linux-gnu is 2.26. We offer APIs that are only available in glibc 2.27 and 2.28 though. When used, those API would crash on glibc 2.26, but if they are not used, everything is ok.

That is, we support glibc >= 2.26, where some APIs are "backward-compatible" extensions.

However, some new features in newer glibc versions (e.g. shadow stack in glibc 2.28, see #1410 ) are ABI incompatible with older glibc versions (e.g. the layout of a struct changes). That is, adding support for these features introduces undefined behavior in Rust programs that are dynamically linked against older glibc versions. These types of changes happen super often, e.g., glibc adds a new field to a struct, and newer glibc versions support code compiled against older versions, but the opposite is not true. Essentially, libc is like a C header file of a particular libc version, but with stuff mixed in from future versions on top.

We should:

  • document the minimum glibc version
  • have a policy for bumping the minimum supported glibc version (cc @rust-lang/libs)

Most crates use libc via crates.io, and not via the Rust toolchain, so we can't use crater to test breaking changes AFAIK. Upgrading the minimum glibc version is bad, because it introduces undefined behavior silently into working Rust programs. Not upgrading the minimum glibc version is bad, because we can't expose newer features to users, and because code that uses newer backward-compatible features has undefined behavior if the minimum supported version is dynamically linked. It also has the downside that when the distros that use that particular glibc version go end-of-life, testing libc becomes harder (e.g. CI needs to work around this, and force Rust programs to be linked to the minimum supported glibc version even if the system has a newer one).

I don't know of any solution that does not have serious downsides. Right now, the policy for upgrading the minimum glibc version is "try it out, and if nobody complains, then the upgrade was ok". But since the UB is introduced silently, it takes a while for people to notice when it happens.

The only safe solution I know would be to just support glibc 2.0, and not add any APIs that are not available there, ever. Right now this means that we would need to remove a lot of APIs, which would also be a significant breaking change. We could layer backward compatible APIs on top, and like we do right now, lay the burden of proving that the dynamically linked glibc version is new enough to users.

The way some libraries try to solve this problem is by using cargo features to pick a library version. So, e.g., if we had a glibc crate, we could have a version 2.0 of it, and then use features like cargo build --feature v2.28 or cargo build --feature v2.0, etc. to pick up the minimum glibc version that should be targeted (a build.rs figures out the version required from the passed features - e.g. the latest version passed). If a glibc 3.0 is ever released, we would release a breaking version to crates.io and linking both would be incompatible. This would mean that somehow, the glibc version used by libstd, would need to be transparently overridden if a different one is required by the dependency graph, and libstd recompiled with it (solutions to these problem are being discussed in #570) .

Doing this for libc would be a mess, because libc supports dozens of C libraries, so we'd need to add features for all of those. We'd probably need to split libc into smaller crates, wrapping a single library each (glibc, musl, libSystem, ...).

@elichai
Copy link
Contributor

elichai commented Oct 18, 2019

Adding to the docs the minimum supported linux kernel could also help.
currently glib 2.26 implies minimum of Linux kernel 3.2.
https://sourceware.org/ml/libc-alpha/2017-08/msg00010.html

@xhebox
Copy link

xhebox commented Dec 24, 2020

Anything new? I would like to mention a similar case like #1412: recently musl may introduce pthread_getname_np. Then rust can have that pthread_[set/get]name_np on musl, too, getting tikv/pprof-rs compilable on musl.

But yes, it will break the old builds on older musl.

@namazso
Copy link

namazso commented Aug 29, 2022

Was this issue solved in the meantime? This recent post on the rust blog implies it was.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
O-gnu S-waiting-on-decision version-support This is a discussion related to supported versions that may require a decision.
Projects
None yet
Development

No branches or pull requests

6 participants