Andreas
Andreas

Reputation: 10157

Understanding glibc

I'd like to distribute my program as a binary, not in source code form. I have two test systems: An older Linux (openSUSE 11.2 with glibc 2.10) and a recent one (LinuxMint 13 with glibc 2.15). Now when I compile my program on the LinuxMint system with glibc 2.15 and then try to start the binary on the openSUSE system with glibc 2.10 I get the following two errors:

./a.out: /lib/libc.so.6: version 'GLIBC_2.15' not found (required by ./a.out)
./a.out: /lib/libc.so.6: version 'GLIBC_2.11' not found (required by ./a.out)

What is confusing me here is this: Why do I get the "glibc 2.11 not found" error here as well? I would expect the program to require glibc 2.15 now because it has been compiled with glibc 2.15. Why is the program looking for glibc 2.11 as well? Does this mean that my program will run on both glibc versions, i.e. 2.15 AND 2.11? So it requires at least 2.11? Or will it require 2.15 in any case?

Another question: Is the assumption correct that glibc is upwards compatible but not downwards? E.g. is a program compiled with glibc 2.10 guaranteed to work flawlessly with any future version of glibc? If that is the case, what happens if a constant like PATH_MAX is changed in the future? Currently it is set to 4096 and I'm allocating my buffers for the realpath() POSIX function using the PATH_MAX constant. Now if this constant is raised to 8192 in the future, there could be problems because my program allocates only 4096 bytes. Or did I misunderstand something here?

Thanks for explanations!

Upvotes: 3

Views: 2782

Answers (1)

Jan Hudec
Jan Hudec

Reputation: 76376

Libc uses a symbol versioning. It's rather advanced wizardry, but basically each symbol is attached tag according to version where it appeared. If it's semantics changes, there are two versions, one for the old semantics with the version where it first appeared and another with the new semantics and the version where it appeared. The loader will only complain about symbols your program actually requests. Some of them happened to be introduced in 2.15 and some of them happened to be introduced in 2.11.

The whole point of this is to keep glibc backward compatible. It's really important, because there is a lot of packaged software, all of it is linked dynamically and recompiling all of it would take really long. There is also lot of software that does not have sources available and the old build of libc might not work with new kernel or new something else.

So yes, glibc is backward compatible. Just make sure you compile against the oldest version you need it to run with, because it is not (and can't be) forward compatible.

Ad PATH_MAX: If a change like that is done, glibc would simply export new versions of symbols that use the new value and old versions of symbols with suitable safegurads to work with code compiled against the old value. That's the main point of all that wizardry.

Upvotes: 7

Related Questions