Skip to content

Patch all packages that are using GCC libraries older than the stdenv libraries #1856

Open
@gcurtis

Description

@gcurtis

Patch the Python interpreter to use the user stdenv’s glibc instead of a hardcoded one. Rebuild the patched package whenever the stdenv changes.

This would be a comprehensive, but also very involved fix. Many of the errors we see seem to be caused by old packages (especially python and ruby) depending on an old glibc. This causes issues because a process can only load glibc once, and the first thing to need it determines the version.

For example, Python 3.5 is no longer maintained in nixpkgs. The last version of glibc that it was built with was 2.34. This means that before the interpreter even runs any Python code, glibc 2.34 has already been loaded into the process by the linker. If at any point there’s Python code that attempts to use a newer version of glibc, it will always crash.

This is easy to run into when using pip to install Python packages that have native code extensions. Either pip downloads a cached binary that needs a newer glibc (some packages no longer offer prebuilt binaries for this reason), or it compiles one itself by calling gcc. The gcc compiler comes from the Nix stdenv, which is usually added by the Nix installer and is therefore almost always newer than a Python from 2015.

The diagram below attempts to illustrate the problem:

graph TD
  python[Python 3.5] -->|depends on| glibc234[glibc 2.34]
  python -->|runs| app[MyApp]
  app -->|imports| psycopg2 -->|loads| psycopg.so

  pip[pip install psycopg2] -->|calls| gcc["gcc (stdenv)"] -->|builds| psycopg.so -->|depends on| glibc2.38["glibc 2.38 (stdenv)"]
Loading

The same thing happens with Ruby (see #1772).

Also note that although this bug most commonly occurs with Python and Ruby, it can occur with any program that attempts to load shared libraries not known by Nix at build-time. For example, a program that supports plugins or one that happens to call dlopen at runtime.

Patching a package (most likely python or ruby) to use the stdenv glibc ensures that any compiled C extensions will be linked against the same glibc as the interpreter. This is in contrast to what we do today where will patch an arbitrarily chosen and hard-coded glibc version.

Metadata

Metadata

Assignees

No one assigned

    Labels

    featureNew feature or requestglibcRelated to linking against glibclinkerRelated to linking (ld, ld.so or dyld)linuxLinux systems

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions