3

I have a simple program called main:

#include <iostream>
#include "random.h"

int main()
{
        std::cout << "The program has started\n";
        return get_another_random_number();
}

The get_another_random_number() function is in a new version of a shared library, but only the old version is installed. The program begins running, but crashes at a later time when the lookup fails; e.g.

$ ./main
The program has started
./main: symbol lookup error: ./main: undefined symbol: _Z25get_another_random_numberv

This will happen if, for example, librandom.so.1.3.1 contains a function called get_another_random_number(), but main is executed on a server that has only librandom.so.1.2.5 installed. These libraries differ only in their minor version because the 1.3 version is backwards compatible with the 1.2 version of the library, but 1.2 lacks the extra function.

In my own example if I run readelf -d main | grep NEEDED I get:

 0x0000000000000001 (NEEDED)             Shared library: [librandom.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libstdc++.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libm.so.6]
 0x0000000000000001 (NEEDED)             Shared library: [libgcc_s.so.1]
 0x0000000000000001 (NEEDED)             Shared library: [libc.so.6]

So everything is linked against the major version numbers only.

For my shared library I placed it in /usr/lib/ and added the symlinks:

lrwxrwxrwx 1 root root     23 Feb  7 14:25 /usr/lib/librandom.so -> /usr/lib/librandom.so.1
lrwxrwxrwx 1 root root     27 Feb  7 14:13 /usr/lib/librandom.so.1 -> /usr/lib/librandom.so.1.2.5
-rw-r--r-- 1 root root   7696 Feb  7 14:00 /usr/lib/librandom.so.1.2.5

Between the library maintainer, application developer and system administrator; who takes responsibility for avoiding this program crash?

  • Is it during installation of main that an error should be produced stating that the currently installed library's minor version is too low?
  • Should the program call a special function in the library to identify the version and check if the minor version is enough?
  • Is the library loader supposed to check all the symbols before the program starts running?
  • Have I misunderstood the version numbering or missed a setting to check the minor version?
2

You haven’t misunderstood version numbering, and this is indeed an area where symbol lookup typically comes up wanting.

As to whose responsibility this is, I’d say that on modern systems it belongs to whomever builds the application, not the library: if you link the application with ld -z now (at least on GNU binutils), the dynamic linker will resolve all symbols at startup and fail early if any symbol is missing (so you don’t need to add manual checks of your own). You can enable this behaviour after a program is linked by exporting LD_BIND_NOW=1 to the environment (any non-empty value works, and this isn’t Linux-specific).

This kind of problem is typically dealt with by package management systems: they keep extensive metadata describing version requirements for symbols, and generate the appropriate versioned dependencies. It’s also possible for library authors to help improve the situation, but it can take a lot of effort; see the GNU libc’s special version symbols (the GLIBC_... symbols that often turn up in error messages) and generally thorough handling of versioned symbols.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.