Subject: Re: stdio FILE extension
To: James Graham <greywolf@starwolf.com>
From: Nathan J. Williams <nathanw@MIT.EDU>
List: tech-userlevel
Date: 10/14/2001 15:14:12
<daemon@ATHENA.MIT.EDU> (James Graham) writes:
> # I understand why we need to keep libc.12 essentially forever now, I don't
> # understand why that means we can't have a libc.13 (and 14, and ...) as well.
>
> The thing I am not getting here is why we have to bump ALL the major
> numbers.
Okay, I'm going to make up an example to demonstrate.
Imagine we have some shared library, call it libbar, that depends on
libc. Most libraries do; the ones with better build systems depend on
it explicitly (using the ELF dependancy mechanism).
Now imagine we build some program, foo, against the current version of
libc and libbar. We end up with dependancies that look like:
foo : libc.so.12
libbar.so.3 : libc.so.12
foo depends on libc.so.12 and libbar.so.3; libbar.so.3 also depends on
libc.so.12. The runtime linker knows how to deal with this and pulls
in one copy each of libc and libbar and does the relocation magic. All
is good.
Now imagine that libc's major is bumped to 13. We don't have any
problem running the old foo binary yet, because it explicitly depends
on an older version. Fine.
We rebuild foo from source. If we do this without rebuilding libbar,
the following situation arises:
foo' : libc.so.13
libbar.so.3 : libc.so.12
Boom! Two different libc's in the program. This doesn't work,
essentially because libc has state (like stdio information, errno,
getopt state, and so on) which needs to be shared process-wide, but
there are now two copies of it (There may also be problems with name
collisions, but I'm less sure about that).
Okay, so we rebuild libbar from source without bumping its major, and
get foo'':
foo'' : libc.so.13
libbar.so.3 : libc.so.13
This works, but we've broken our original foo, in the same way that
foo' was broken, with two different libc's:
foo : libc.so.12
libbar.so.3 : libc.so.13
Thus, we are forced to bump libbar's major number if we want to be
able to both (1) build new programs against it and (2) not break old
programs built against it. This is awkward at best, and a real
nightmare for third-party or non-open-source libraries that the user
can't rebuild.
(It's true that libraries that don't use any stateful part of libc, or
don't depend on libc at all, aren't affected this way, but enough
libraries use stdio that this is a real problem.)
- Nathan