This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: dynamic library version crashes but static version works


On 20 Jan 2005, Ted Sung asked:
> I have a few more questions regarding the compatibility of dynamic
> (and static libraries).

(This is probably off-topic on the GCC list, but I'm not aware of a list
where it would be on-topic, really.)

> Does the compatibility of the libraries depend solely on the version
> of Linux?

Not exactly.

>            For example, will libraries be compatible if they are built
> on the same machine but with different versions of the GNU compiler ?

Not exactly.

> Aside from versions of Linux, what else (gcc version, glibc version,
> ld version etc.) determines whether a dynamic (and static) library are
> compatible?

The library and its caller have to agree on some things. The API (that
the library provides, and that the caller expects it to provide) has to
match, any shared data structures have to match, and the ABI has to
match.

The former, the library's direct API, is pretty much handled for you
on ELF shared library systems like Linux: a combination of SONAMEs
(roughly corresponding to shared library major version numbers) and
symbol versioning (which lets shared libraries expect several
symbols with the `same name' for old and new binaries) keeps things
pretty much in shape.

The shared data structure matching stuff was, for instance, why you had
to rebuild the world when going from libc5 to libc6. The data structures
maintained by things like malloc() drastically changed, and because
libc5 didn't use symbol versioning it was impossible to hide this from
the user; a malloc() in a library linked against libc5 followed by a
free() in its caller linked against libc6 would have led to a corrupted
heap arena and a crash.

The ABI matching stuff is why you had to rebuild all C++ programs when
going from, say, GCC 2.95.x to GCC 3; the data structures used to
represent things like C++ classes in memory changed. (This is really a
special case of the previous case, except that ABIs are shared data
structures that every single program in some language has an implicit
dependency on, because they're compiler-generated.)


In addition, there's the issue that in older GCCs, libgcc.a contained
exception-handling code that was linked directly to your binary: this
code maintained global structures which there must be only one copy of
per process --- yet shared libraries often had their own copies of this
code, and they sometimes made multiple copies of those data structures,
or disagreed on their layout... nowadays, C++ programs are linked
against a shared version of this library, ensuring that there's only one
copy of the exception-stack-walking code per process.

(But this is *another* reason why old and new C++ code won't work
together.)

> Why do the static libraries tend to work more frequently than the
> dynamic libraries?

Because they get actually linked in to the binary, and so don't change
from underneath it. (However, static libraries may sitll get broken by C
library upgrades, among other things, and are accordingly deprecated or
outright unavailable on some systems, like Solaris 10 and recent Linux
distros.)

> As a provider of such libraries to clients, I'd like to try to
> minimize the # of machines and builds that need to be done.

If you stick to the oldest (still compatible) versions of libraries that
you can find or that are used in major distributions, you should be
safe; important libraries like the X libraries or glibc are either
insanely compatible (libX11), or state that programs linked against some
library version X are guaranteed to work with higher versions until the
major version number changes (which of course signals broken
compatibility, as usual). Less visible libraries sometimes break this
guarantee, but it's pretty much an assumed thing these days: it's not
very common to find binary compatibility being broken without major
version number bounces.

(Note that this doesn't mean that you can link against, say,
libtiff.so.3.7.1 and expect people to be necessarily able to use your
program with libtiff.so.3.6.0; the guarantee only works
*upwards*. Library maintainers can introduce new stuff at any time, but
can only break old stuff when they bump the major version number.)

(In some situations, different distributors provide different major
versions of some libraries, or provide shared libraries in development
that don't guarantee a stable ABI: in that situation, your only choices
are to ship a copy yourself, or to mandate a particular version of the
library.)

-- 
`Blish is clearly in love with language. Unfortunately,
 language dislikes him intensely.' --- Russ Allbery


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]