How shared library locations are found at runtime

You have successfully compiled an executable that is linked with one or more external shared libraries. You can view the shared libraries that the executable is dependent on by using the ldd tool. When you actually run the executable, the dynamic linker-loader ld-linux looks for each dependent shared library in the following locations, in order:

  • Using RPATH, if it exists, that is hard-coded in the executable. This is a colon-separated list of directories from where the shared libraries were linked into the executable by the linker during the linking stage of compilation. If this exists, you can view it using this command: readelf -d ./your_binary | grep RPATH
  • Using LD_LIBRARY_PATH, if it is set. This is a colon-separated list of directories set as an environment variable by the user.
  • Using RUNPATH, it is exists, that is hard-coded in the executable. This is a colon-separated list of directories, just like RPATH. If this exists, you can view it using this command: readelf -d ./your_binary | grep RUNPATH
  • Checks the /etc/ld.so.cache. This cache is populated by running the ldconfig program. This program is usually run when libraries are installed. You can view the shared libraries in the cache using this command: ldconfig -p
  • Check in /lib
  • Check in /usr/lib

See it in action

You can actually witness the loader searching directories to find the location of each shared library. To see this in action, try this command:

$ LD_DEBUG=libs ldd ./some_executable

In the output of this command, you will see that:

  • Each shared library listed in the executable is picked up in order.
  • For each shared library, the locations listed above (RPATH, LD_LIBRARY_PATH, RUNPATH, cache, lib and user lib) are tried in order.
  • For each directory listed in the above colon-separated list, the shared library filename is appended and tried to see if the file path exists.
  • The first instance where such a file path exists, that is noted as the location of the shared library.

References:

Advertisements

How to view hierarchy of shared library dependencies using lddtree

Tree of library dependencies shown by lddtree
Tree of library dependencies shown by lddtree

ldd is one of the key tools that should be familiar to all programmers. It shows the list of all shared libraries that an executable binary depends on.

A binary, say ELF file, lists only the immediate shared libraries it depends on in its header. Each of these shared libraries could further depend on other libraries and so on. It would be very useful if you could see the hierarchical tree of these dependencies between the shared libraries. Thankfully, there is a tool that does exactly that named lddtree.

  • It can be installed easily:
$ sudo apt install pax-utils
  • Usage is straightforward:
$ lddtree foo
  • By default, the tool does not show duplicated dependencies. That is, the dependency between a library A and B is shown only once and skipped after that, though it may occur many times. To view all the dependencies, including duplicates:
$ lddtree -a foo

Beware that this can result in a very big tree! This is because dependencies like libc, the ld-linux loader and such will appear for almost all shared libraries.

Note: The Dependency Walker tool does something similar on Windows and can be used as described here.

Tried with: PaX-Utils 0.2.3 and Ubuntu 14.04