Does Nix prevent unintended use of multiple versions of a library in a single process?

Hi there,

During dynamic linking, if two or more versions of the same library is loaded into a single process, it is usually a sign of trouble (there are exceptions of course). I feel that this is more likely to happen in systems managed by Nix compared to those managed by conventional package managers. With conventional managers, most likely only one version of a library is installed in the system. But with Nix, there can be many. For example, assume AppX depends on LibA and LibB, and both LibA and LibB depends on LibC. If the version of LibC that LibA uses (through RPATH) is different from the version that LibB uses (say they were compiled with different compile time options), then when AppX is run, two versions of LibC will be loaded and bad things can happen. Is there any mechanism in Nix to prevent this from happening? For example, when building a package, will Nix (by default) try to make sure that only one version of a library is used (directly or indirectly) by an executable?

There’s no prevention to these issues, I believe. If there are multiple libs with the same SONAME on the search paths, basically any of them might win (it’s better not to assume anything) and get loaded for that name (but only one of them is loaded for the given process).

This is actually a practical problem when you insert libraries impurely, e.g. what we do with OpenGL libs – their runtime dependencies may come from a different nixpkgs version than your executable and use different library versions even for different reasons. We even had periods of binaries failing to start for some version combinations when libwayland (IIRC) was changing something in its symbols. There were some suggestions of using libcapsule for avoiding library interactions in this case, but I haven’t seen that really working yet (maybe I’ve missed something but probably not).

A similar problem causing pain in major openssl upgrades IIRC: libraries with different SONAME may export symbols with the same name, so you can’t really use those libs at once in one process. As with the previous issue, I don’t think it’s possible to find a reasonably simple general solution to this. C just isn’t designed to accomodate such things transparently.

For libraries that are inserted impurely, I can see that there is no good solutions. But for the more common pure cases, will it help to do some sort of sanity check when an executable is built? For example, follow the dependency graph of the executable to see if there are conflicting libraries (same SONAME, or SONAMEs that differ only in the version number).

Yes, similar checks certainly wouldn’t hurt, though I expect the occurrences to be very rare (in pure cases). We try to keep the number of package versions (and configurations) to minimum.