17

I have a binary executable named "alpha" that requires a linked library (libz.so.1.2.7) which is placed at /home/username/myproduct/lib/libz.so.1.2.7

I export the same to my terminal instance before spawning my binary executable by executing the following command.

export LD_LIBRARY_PATH=/home/username/myproduct/lib/:$LD_LIBRARY_PATH

Now, when I spawn another application "bravo" that requires the same library but of different version, i.e (libz.so.1.2.8) which is available in /lib/x86_64-linux-gnu/libz.so.1.2.8, system throws the following error.

version `ZLIB_1.2.3.3' not found (required by /usr/lib/x86_64-linux-gnu/libxml2.so.2)

If I unset the LD_LIBRARY_PATH, "bravo" starts up fine. I understand that the above behaviour is because LD_LIBRARY_PATH takes precedence over the directory paths defined in /etc/ld.so.conf while looking for linked libraries and consequently the above error occurred. I am just curious about why have not the developers of UNIX/LINUX designed the OS to search for linked libraries in other directories according to the hierarchy if the first instance of library is of different version.

Simply put, UNIX/LINUX systems traverse through a set of directories until it finds the required library. But why does it not do the same until it finds the expected version rather than accepting the first instance of library irrespective of its version?

2
  • I'm not quite sure, but I'd guess for security. I personally would rather not have to worry about a sym-link anywhere on my machines
    – Joe
    Apr 9, 2019 at 7:08
  • @Joe Many of the libraries themselves have symlinks pointing to them. libz.so.1 is a symlink to libz.so.1.2.8 Apr 9, 2019 at 7:24

1 Answer 1

28

But why does it not do the same until it finds the expected version rather than accepting the first instance of library irrespective of its version?

It does, as far as it’s aware. zlib.so.1.2.7 and zlib.so.1.2.8 both have an soname of zlib.so.1, so your alpha and bravo binaries say they need zlib.so.1. The dynamic loader loads the first matching library it finds; it doesn’t know that version 1.2.8 provides additional symbols which bravo needs. (This is why distributions take pains to specify additional dependency information, such as zlib1g (>= 1.2.8) for bravo.)

You might think this should be easy to fix, but it isn’t, not least because binaries and libraries list the symbols they need separately from the libraries they need, so the loader can’t check that a given library provides all the symbols that are needed from it. Symbols can be provided in a variety of ways, and introducing a link between symbols and the libraries providing them could break existing binaries. There’s also the added fun of symbol interposition to complicate things (and make security-sensitive developers tear their hair out).

Some libraries provide version information which ends up being stored in .gnu.version_r, with a link to the providing library, which would help here, but libz isn’t one of them.

(Given the sonames, I’d expect your alpha binary to work fine with zlib.so.1.2.8.)

7
  • And one should note as well that GNU-style library versioning is different from the semantic(-ish) versioning with which we are most accustomed. Since they have the same "current" number, 1, zlib.so.1.2.8 should not provide any features that zlib.so.1.2.7 does not, hence it ought not to matter (from an ABI perspective) which one is found. That it does matter should be considered a flaw. Apr 9, 2019 at 15:40
  • 4
    @John no, the only guarantee is that libraries with the same soname are backwards-compatible; newer libraries can add features, they can’t remove any or change any in a backwards-incompatible fashion. That is to say, a binary built against zlib 1.2.7 will work with that or any newer zlib 1; but a binary built against zlib 1.2.8 won’t necessarily work with an older zlib 1. (And semantic versioning allows that; but soname handling isn’t semantic versioning.) Apr 9, 2019 at 15:49
  • 1
    I'm talking specifically about GNU conventions, as I said, and I guess about libtool in particular. Not every project follows that convention, so perhaps it's too strong to call zlib flawed, but on the other hand, even a semantic-versioning interpretation of the library version numbers involved would come to the same conclusion. Forwards (binary) compatibility in such cases is not a promise inherent in the soname, but it is a reasonable expectation in this case. Apr 9, 2019 at 16:01
  • 1
    Yes, I well understand the relationship between CRA numbers and SOVERSION, which comes back around to my original point: the situation described by the OP seems to be inconsistent with correct usage of the CRA scheme. Avoiding problems such as the OP's is one of the key objectives of that scheme. If zlib adds a new (version of a) binary interface, then its C number ought to be increased. That such a bump may lead to a soversion bump as well is secondary. Apr 9, 2019 at 16:32
  • 2
    @John right, I suspect we’re in violent agreement and that I misunderstood the point you were making. zlib doesn’t use libtool anyway, except on Darwin where it’s ar ;-). Apr 9, 2019 at 16:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .