How to work with shared object dependencies (library) en Linux

Contents

library text on white background

Error loading shared libraries: the dreaded error that sooner or later every Linux user will encounter. Something went wrong with shared object dependencies (The libraries) used by the executable. Learn how to fix these problems and more!!

What is a Shared object dependency?

A shared object (also called library) is a binary (generally not directly executable) used by multiple programs / applications on a Linux instance. These libraries are often installed at the operating system level and shared (hence the name shared object O libraries) for use by one or more (and even many) directly executable applications.

As an example, a program that includes compressed files may require the bz2 library (bzip2) libbz2.so.1.0 to do it. The term Library It is used more frequently in Linux circles and is the jargon of choice among professionals, although shared object (and shared library) are both technically correct. It is also interesting to note that the .so The filename extension used in many libraries means shared object!

An executable can have zero, one or many libraries on which it is based. The fewer libraries, more advanced (when updating your operating system, as an example) will be compatibility. The more libraries, the greater the chance that, sooner or later, any dependency on the library is broken. This is also the reason why application providers sometimes decide to launch statically compiled binaries instead of dynamically compiled binaries.

The difference between statically and dynamically compiled binaries is simple but has far-reaching consequences. A statically compiled binary has the libraries (available in the development system at build time) compiled in binary / resulting executable. A dynamically compiled binary will use the installed libraries, available and shared on the user's system.

As you can see immediately, this would require the user to install the required dependencies, unless these are cared for in the operating system or in the details and package management system of the application vendor. This is why running a simple command like sudo apt install ...some_app... will often produce a set of other associated things (In other words, required libraries) to be co-installed at the same time.

Both static and dynamic compilation have pros and cons. As an example, if you use static compilation and a library that you have included in your software package (from a software vendor's perspective) now you have a security bug or a critical update, you will likely need to republish your software package, even if nothing has changed in your code.

But, again, trust user to install libraries, especially for complex programs, or when software auto-compilation is needed, knowing that end users often struggle with such things, it is not ideal either. It is a complex area and the subject has been discussed often.

For the purposes of this post, we will analyze the shared libraries in binding with a program that was compiled dynamically, as is usually the case with programs / executables / operating system tools. With statically compiled programs (which are less common), it is highly unlikely that an error such as 'Failed to load shared libraries' will be displayed, since libraries are included in the executable unless the program is partially dynamic and only includes a limited set of built-in files. in static libraries.

Error loading shared libraries!

Let's change to root mode for a while (using sudo su) and explore how shared libraries work when it comes to a tool like /usr/bin/zip which is included or can be installed with the major Linux distributions.

Using ldd on Linux

Here, we change the directories to /usr/bin and checked if the zip Program / tracks / executable is present. Finding it present, then we verify the version by invoking it with --version and taking only the top two lines of the output channeling the output (using |) to avoid long output given otherwise.

To end, we use the ldd tool (a program that prints shared object dependencies) to see what libraries the executable needs. As we can see, the program needs four shared libraries. The list of required libraries is generally in the format of the required library, followed by a path where the named library was already found.

For some top-level or special OS-level libraries (What linux-vdso.so.1), no such route is shown. Despite this, as long as no error is displayed in any input, you will know that it is good and available (or is it preferable). Actually, linux-vdso.so.1 Its an object / special shared virtual library injected in each procedure by Linux kernel, you don't have a physical file on disk for the same. It's there to make system calls more efficient.

Then, let's break things up a bit and rename one of the required libraries so that the binary can no longer auto-discover it:

Error loading shared libraries and missing library

As you can see, here we change the name / we moved the file from /lib/x86_64-linux-gnu/libbz2.so.1.0 for /lib/x86_64-linux-gnu/libbz2.so.1.0.NOT_PRESENT. This broke our zip app, and when we try to run it, we get the dreaded error while loading shared libraries error. Despite this, looking a little closer, the error message is quite descriptive:

zip: error while loading shared libraries: libbz2.so.1.0: cannot open shared object file: No such file or directory

An experienced IT engineer will always carefully review any check-in and check-out / program information presented to you before making a call over an obstacle. Also it would be worth it here, since the required file is clearly displayed, libbz2.so.1.0, and the problem is also clearly shown. There are No such file or directory. In other words, libbz2.so.1.0 He is lost!

We can also verify the same with ldd, as you can see in the picture above. A cleaning libbz2.so.1.0 => not found helps us know what is happening. Once we clearly understand how dynamically compiled binaries (most binaries in the operating system are compiled this way) load and require libraries, and how to see if one is missing (or if you are informed of it through the error message), things don't work. it doesn't seem so complicated anymore.

At the same time, once we know the name of the required library, a quick search on your favorite search engine will show the add-on package to be installed (will reinstall it) to get the required library name. Very often, the package name can even be constructed directly from the library name. Despite this, for this case, the name of the runtime library is a little off.

There are two types of libraries: runtime libraries and development libraries. In this circumstance, the name of the package that contains the libbz2.so.1.0 the library is likely bzip2, and trying to uninstall would probably break several other items, as you can see from a long list of programs that will be removed if you try to uninstall or purge the bzip2 package.

The second type of library is a development library. Often, These are needed when trying to compile programs and, often, are more closely related to the names of the actual library files. As an example, in Ubuntu, just take the name of the library and add -dev. As an example, if we wanted to install the development package related to the libbz2.so.1.0 package, we could consider installation libbz2-dev:

Installing a development library

Considering that this development library is not directly related to our libbz2.so.1.0 runtime library, it is useful to know the naming syntax of most development package names in Ubuntu (prefix of lib and suffix of -dev with the name of the library among those) definitively that a certain development library is required (which is usually required when compiling software).

At the same time, suppose some library breaks down somehow. Then, one of the easiest quick fixes is to purge the library sudo apt purge your_library_name command (that would totally purge the library / past program), followed by a reinstall using the sudo apt install your_library_name command.

And when you are in a situation similar to the previous one, where to uninstall the runtime library you need to uninstall / purge the main program, and where is purging / removing is too big of a part of the operating system or it would affect many other things, you can use a reinstall option instead:

Reinstall an app or library

sudo apt reinstall bzip2

Despite this, it is not always so simple, even when knowing the above (and especially the naming convention in terms of adding -dev) helps enormously when fixing problems and, often, will solve the problem directly.

Also it helps a lot to know how libraries can be verified using lddand, to end, understand that a library is just an executable (even if not directly) .so file that lives in a subdirectory of /lib o en /usr/lib or other similar directories.

Sometimes, libraries and / or packages conflict with each other, or certain packages require certain versions of libraries, or certain libraries require other libraries, in specific versions. Yes, it gets a bit complex. It is also something easy, when it gets so complex, mess up a system a bit. Sometimes, it is even quite feasible to completely interrupt the installation of an operating system due to the transfer of a too important library, etc.

Often, it is somewhat safer to create a symbolic link (a virtual link with a specific file name, witch reffers to / links to another existing file or another symbolic link itself, which in turn points to a real file) for a library remaining in a previous version, as an example and pointing that symbolic link to the latest version installed. It doesn't always work, but in case it fails, the symbolic link can be removed, hopefully safer (assuming no such symbolic link or file with the same name existed beforehand).

The best way to fix these more complex problems is to always try a apt (or a similar package management tool on your operating system), first a solution. In this point, you will also want to read how to use dkpg to fix apt, as it shows you a more granular way of managing packages (Even when be careful, since more control implies more responsibility!).

If all else fails, try creating a symbolic link or even manually add the library file. (Please, make sure any downloaded files are virus free, as an example, verifying it with VirusTotal, and it is always better to use the repositories provided by the Linux vendor to download binaries).

in extremis, it is possible that you can also find a library on a neighboring Linux operating system. As an example, an Ubuntu executable will run in Mint and vice versa. Copying a library from another PC you also have is a viable approach at times.

Ending

Fine-grained library management is a skill that takes a lifetime to learn. It's almost an art. This post has provided the information / basic knowledge and tools to use and has listed some more advanced troubleshooting tips for when things get murky, and sooner or later, they will if you are a frequent Linux user who install packages regularly.

Next time you see the error 'Error loading shared libraries’ on your Linux machine, you will be better equipped to understand where the problem may come from when using a tool like ldd, as explained in this post. We also analyze static binaries versus dynamically compiled binaries., and how shared or built-in libraries fit and work with both.

If you liked this post, also would like to read the post about dpkg previously linked, as well as How to add the universe, the multiverse and restricted repositories in Ubuntu.

Subscribe to our Newsletter

We will not send you SPAM mail. We hate it as much as you.