5 ms·
The problem with sonames for libc is that libc is too foundational of a library to really have multiple incompatible versions running around [1]. There is no wa
by jcranmer 5y ago
The problem with sonames for libc is that libc is too foundational of a library to really have multiple incompatible versions running around [1]. There is no way for an application to have multiple versions of libc in its memory space. When you live in a modern world where applications will pull in multiple third-party packages that all depend on core packages, those core packages better be extremely good about backwards compatibility or there is immense pain on adopting new versions (see also Python 2->3 transition).
[1] Or, perhaps more accurately, an incompatible version of libc requires the creation of an entire distinct target triple. You can have multiple incompatible versions if you've got a multiarch setup of some kind (like 32-bit and 64-bit x86 code on the same system), but an application can't simultaneously use both in the same process in such systems still.
- Arnavion 5y agoIt's partly a Linux-specific problem. Windows programs are fine with having multiple copies of MSVCRT loaded into the same process. It's often unavoidable; any process that loads plugin libraries will have its own CRT plus other CRTs pulled in by the plugins in its address space. Just open up some process in procexp and see how many msvcrt##.dll you find loaded. It means every library has to be careful about providing both malloc and free calls in their API. Eg if a library has a `Foo *create_foo(void)` it has to provide a `void delete_foo(Foo*)`, instead of expecting the user to call `free(the_foo)` because that `free` might be from the wrong CRT. With Linux libraries I often find that you have a `create_foo` but no `delete_foo`, and you're expected to just `free` it. I assume Linux libraries never took this much care historically because software was generally open-source, so everyone was getting their software from distro repos that rebuilt the world to link to a single libc.
- yjftsjthsd-h 5y agoYou should know that HN lets you prefix stars with a backslash to escape them, so your text ends up saying, ex. foo*bar and bar*baz rather than foobar and barbaz
- Arnavion 5y agoI know. I fixed it shortly after I posted the comment.
- jcranmer 5y agoglibc serves multiple purposes, and these purposes are broken up into separate libraries on Windows. One of those purposes is to act as the C standard library, which is what is provided by msvcrt.dll. But another purpose is to act as the library of system services, which is provided by kernel32.dll instead. The actual functionality that glibc broke in this specific ABI break is really the sort of functionality that is provided by kernel32.dll (i.e.., that's where the SEH functions live) on Windows. And you can't provide multiple copies of kernel32.dll on Windows, just like you can't have multiple copies of glibc.
- Arnavion 5y agosetjmp, longjmp, jmp_buf are defined in the CRT, not in kernel32. Of course their implementations will eventually depend on kernel32, but that's not relevant to the callers of setjmp/longjmp.
- jcranmer 5y agoIf glibc were set up to have a kernel32/CRT divide like Windows does, I suspect the ABI breakage would have impacted the kernel32 side of the divide, given that the rationale was for better support of hardware stuff in s390. Of course, in Windows, setjmp/longjmp/jmp_buf being the C way of doing things, the implementations live in CRT-land, but the underlying implementation (being essentially SEH/unwind) actually lives in kernel32.
- Arnavion 5y agoSure? My point is, even if it impacted the CRT side of the divide, it would likely have not been a problem, because it would be a new version of the CRT with the breaking API and would not have affected existing code linking to the old CRT. And because libraries are generally more hygienic about not leaking CRT details across their own API boundaries, it would not have been a problem for old and new CRTs to be mixed in the same process.
- jancsika 5y agoIn keeping with my confidently-wrong-on-the-internet theme: Nobody is trying to run multiple incompatible versions of glibc in a single application. The point is to run multiple different versions of the same application on a single OS, where each version uses a different version of glibc. NixOS is wildly over-engineered for this purpose. Just use lib.so.versionNumber, full stop. And, scene. :)
- assbuttbuttass 5y agoIf some library e.g. libpng depends on a particular version of glibc, and your application depends on libpng and glibc, you better hope they want the same version
- jancsika 5y agoI'm still not getting it. Doesn't libpng use the soname.someVersion, too?
- assbuttbuttass 5y agoWell suppose to libpng depends on glibc version 6.0, but when you try to link your app it will find the latest glibc 6.1. Only one of these versions is going to get loaded at runtime. The compiler's not going to check compatibility between all the different libraries.
- jancsika 5y agoIf the highest number always gets chosen then what's the point of libname.so.versionNumber in the first place?
- rlpb 5y agoThe point is for runtime. At build time generally the latest available version is used (via a symlink) and then that version gets locked in to the resulting binary.