What is LD_LIBRARY_PATH used for?

Table of contents

No heading

No headings in the article.

In today's blogs, I will be talking about LD_library_path.

LD_LIBRARY_PATH is an environment variable that lists a directory where the executable can search for a Linux shared library. It's also called the shared library search path.

The value of the environment variable LD_LIBRARY_PATH is a colon-separated (:) set of directories where libraries are searched for first before the standard set of directories.

Why was it invented? There were a couple of good reasons why it was invented:

This is useful when debugging a new library or using a non-standard library for special purposes, but be sure you trust those who can control those directories. To test out new library routines against an already compiled binary (for either backward compatibility or new feature testing). To have a short-term way out in case you wanted to move a set of shared libraries to another location.

If you are running on a Solaris system, the LD_LIBRARY_PATH environment variable is used to define the native library path.

This little note is about one of the most “misused” environment variables on Unix systems: LD_LIBRARY_PATH. If used right, it can be very useful, but very often – not to say, most of the time – people apply it in the wrong way, and that is where they are calling for trouble.

So, what does it do? LD_LIBRARY_PATH tells the dynamic link loader (ld. so – this little program that starts all your applications) where to search for the dynamic shared libraries an application was linked against. Multiple directories can be listed, separated by a colon (:), and this list is then searched before the compiled-in search path(s), and the standard locations (typically /lib, /usr/lib, …).

This can be used for

testing new versions of a shared library against an already compiled application by re-locating shared libraries, e.g. to preserve old versions creating a self-contained, relocatable(!) environment for larger applications, such that they do not depend on (changing) system libraries – many software vendors use that approach. Sounds very useful, where is the problem? Yes, it is useful – if you apply it in the way it was invented, like in the three cases above. However, very often it is used as a crutch to fix a problem that could have been avoided by other means (see below). It is even getting worse if this crutch is applied globally into a user’s (or the system’s!) environment: applications compiled with those settings get dependent on this crutch – and if it is eventually taken away, they start to stumble (i.e. fail to run).

There are other implications as well:

Security: Remember that the directories specified in LD_LIBRARY_PATH get searched before(!) the standard locations? In that way, a nasty person could get your application to load a version of a shared library that contains malicious code! That’s one reason why setuid/setgid executables do neglect that variable! Performance: The linking loader has to search all the directories specified until it finds the directory where the shared library resides – for ALL shared libraries the application is linked against! This means a lot of system calls to open(), that will fail with “ENOENT (No such file or directory)”! If the path contains many directories, the number of failed calls will increase linearly, and you can tell that from the start-up time of the application. If some (or all) of the directories are in an NFS environment, the start-up time of your applications can get long – and it can slow down the whole system! Inconsistency: This is the most common problem. LD_LIBRARY_PATH forces an application to load a shared library it wasn’t linked against, and that is quite likely, not compatible with the original version. This can either be very obvious, i.e. the application crashes, or it can lead to wrong results if the picked-up library not quite does what the original version would have done. Especially the latter is sometimes hard to debug.