upvote
> split Glibc into 3 parts: syscalls, dynamic loader and the actual C library.

What is left of the C standard library, if you remove syscall wrappers?

> ABI hell

Is that really the case? From my understanding the problem is more, that Linux isn't an OS, so you can't rely on any *.so being there.

reply
> > split Glibc into 3 parts: syscalls, dynamic loader and the actual C library.

> What is left of the C standard library, if you remove syscall wrappers?

Still quite a bit actually. Stuff like malloc, realloc, free, fopen, FILE, getaddrinfo, getlogin, math functions like cos, sin tan, stdatomic implementations, some string functions are all defined in C library. They are not direct system calls unlike: open, read, write, ioctl, setsockopt, capget, capset ....

> > ABI hell

> Is that really the case? From my understanding the problem is more, that Linux isn't an OS, so you can't rely on any *.so being there.

That's why I used more specific term GNU/Linux at the start. There is no guarantee of any .so file can be successfully loaded even if it is there. Glibc can break anything. With the Steam bug I linked this is exactly what happened. Shared object files were there, Glibc stopped supporting a certain ELF file field.

There is only and only one guarantee with Linux-based systems: syscalls (and other similar ways to talk with kernel like ioctl struct memory layouts etc) always keep working.

There is so much invisible dependence on Glibc behavior. Glibc also controls how the DNS works for the programs for example. That also needs to be split into a different library. Same for managing user info like `getlogin`. Moreover all this functionality is actually implemented as dynamic library plugins in Glibc (NSSwitch) that rely on ld.so that's also shipped by Glibc. It is literally a Medusa head of snakes that bite multiple tails. It is extremely hard to test ABI breakages like this.

reply
> malloc, realloc, free

Wrapper around sbrk, mmap, etc. whatever the modern variant is.

> fopen, FILE

Wrapper around open, write, read, close.

> stdatomic implementations

You can argue, these are wrappers around thread syscalls.

> math functions like cos, sin tan, some string functions are all defined in C library

True for these, but they are so small, they could just be inlined directly, on their own they wouldn't necessarily deserve a library.

> That's why I used more specific term GNU/Linux at the start.

While GNU/Linux does describe a complete OS, it doesn't describe any specific OS. Every Distro does it's own thing, so I think these is what you actually need to call an OS. But everything is built so that the user can take the control over the architecture and which components the OS consists of, so every installation can be a snowflake, and then it is technically its own OS.

I personally consider libc and the compiler (which both make a C implementation) to be part of the OS. I think this is both grounded in theory and in practice. Only in some weird middle ground between theory and practice you can consider them to not be.

reply
> malloc, realloc, free > Wrapper around sbrk, mmap, etc. whatever the modern variant is.

I don't think that's correct. While `malloc` uses `brk` syscall to allocate large memory areas, it uses non-trivial algorithms and data-structures to further divide that areas into smaller chunks which actually returned. Using syscall for every `malloc`/`free` is quite an overhead.

> fopen, FILE

> Wrapper around open, write, read, close.

They're not just wrappers. They implement internal buffering, some transformations (for example see "binary" mode, "text" mode.

> stdatomic implementations

> You can argue, these are wrappers around thread syscalls.

No, they're wrappers around compiler intrinsics which emit specific assembly instructions. At least for any sane architecture.

> I personally consider libc and the compiler (which both make a C implementation) to be part of the OS. I think this is both grounded in theory and in practice. Only in some weird middle ground between theory and practice you can consider them to not be.

C is used a lot in embedded projects. I even think that's the majority of C code nowadays. These projects usually don't use libc (as there's no operating system, so concept of file or process just doesn't make sense). So it's very important to separate C compiler and libc and C compiler must be able to emit code with zero dependencies.

reply
Yeah sure they do more things than only doing the syscall, that's the point of an abstraction. But they still provide the functionality of the syscalls, just in the abstraction that you want it to be exposed as in the programming language. That's what I would consider a wrapper.

> C is used a lot in embedded projects.

Sure that's a freestanding implementation, which primary distinction is that it doesn't rely on the libc. The notion of the libc being part of the OS in the wider sense, still holds water here, since here no OS corresponds to no libc.

reply
mmap and sbrk would be very poor implementations of malloc.
reply
We are talking of wrappers on top of mmap and sbrk. Of course you wouldn't use mmap and sbrk instead of the abstraction. It's really the same as the difference between fread and read.
reply
> Glibc broke certain games / Steam by removing some parts of their ELF implementation: https://sourceware.org/bugzilla/show_bug.cgi?id=32653 . They backed due to huge backlash from the community.

It would be better if you specified which part was removed: support for executable code on stack. This is used in 99% cases by malware so it is better to break 1% of broken programs and have other 99% run safer.

reply
The comments on that bug report mention several language runtimes getting broken. Preventing languages that are generally safer than C from working seems rather counterproductive to overall security.
reply
> If "the year of Linux desktop" would ever happen, they need to either do an Android and change the definition of what a software package is, or split Glibc into 3 parts: syscalls, dynamic loader and the actual C library.

The dynamic loader used to be its own library, FWIW. It got merged into the main one recently.

reply
I'm sick of glibc compatibility problems. Are there any recommended replacements?
reply
For non-graphical apps, you can link statically against musl to produce a binary that only depends on the Linux kernel version and not the version or type of libc on the system. You may take a performance hit as musl isn't optimized for speed, and a size hit for shipping your own libc, and a feature hit because musl is designed to be minimal, but for many command line tools all of these downsides are acceptable.
reply
.interp to a glibc/libc you ship or static linking. These days it’s probably faster (in dev time) to just run a container than setting up a bespoke interp and a parallel set of libraries (and the associated toolchain changes or binary patching needed to support it).
reply
Running a container is exactly my current solution as well.

Are there any other solutions that don't depend on glibc?

reply
Guix (and I assume Nix as well, but I only know Guix) can create a package that is completely self contained including glibc. You can even have it be an AppImage https://guix.gnu.org/manual/devel/en/html_node/Invoking-guix...
reply
Glibc is half of GNU/Linux. You can of course use another libc, but it will be a different OS.
reply
Yeah, even library loading relies on glibc, so we can't really escape glibc on GNU/Linux.
reply
I don't really know why people expect to be able to bypass the OS and not have problems. It seems to come from people who think a "Linux OS" only consists of the Linux kernel.
reply
I wonder if anyone implemented loading shared libraries without glibc? It shouldn't be that hard, just need to implement ELF parser and glibc-compatible relocation mechanism.
reply
I don't think nobody has done, that. It is just that vendoring your own OS comes with a lot of work.
reply