Linux Tips & Tricks · November 8, 2021

Shared Libraries

[Linux] Shared Libraries – A Brief Summary

To understand shared libraries, we must understand what’s a library first. A library is simply a collection of items, like functions. As you know, functions are used to perform specific tasks. Such as opening a file, writing something to standard output etc.

Functions are separated into library files. Therefore, two (or more) applications required the same function can use the same library. But we should mention a problem here. How do we keep track of which library file installed by which package? which applications(s) require(s) a library? This is one of the importance of package managers.

Want to learn more about Debian Package Manager (DPKG) or Red Hat Package Manager (RPM)?

Static vs. Shared Libraries

There are two types of libraries supported by Linux. Static libraries (aka statically linked libraries) are copied into the application while compiling. On the other hand, shared libraries (aka dynamic libraries) don’t work like that. Shared library functions are copied into memory on runtime. This process is called loading library. Dynamic linker is responsible for this process.

Dynamic Linker In Linux

System searches a few places while it needs to load a shared function. Like LD_LUBRARY_PATH contents or /lib*/ and /usr/lib*/ directories.

Let’s see where’s our dynamic linker:

root@debian:~# locate ld-linux
/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/usr/lib64/ld-linux-x86-64.so.2
/usr/share/man/man8/ld-linux.8.gz
/usr/share/man/man8/ld-linux.so.8.gz
root@debian:~# file /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
/usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2: symbolic link to ld-2.31.so
root@debian:~# file /usr/lib/x86_64-linux-gnu/ld-2.31.so 
/usr/lib/x86_64-linux-gnu/ld-2.31.so: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, BuildID[sha1]=32438eb3b034da54caf58c7a65446639f7cfe274, stripped

Library Management In Linux

Knowing library paths is one thing, but it’s not enough for managing or troubleshooting by itself.

What is library cache?

When your system finds and loads a library, it’ll keep the path in cache so when it’s needed again, system can easily find the library without searching it. But what if we’ve installed a new library or updated existing ones? Then, we should update the library cache. We can simply use “ldconfig” command to do so. But hey, package managers got you covered in here also. Package managers runs “ldconfig” while needed.

To list all cached libraries, you can run “ldconfig -p” command:

root@debian:~# ldconfig -p
212 libs found in cache `/etc/ld.so.cache'
	libzstd.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libzstd.so.1
	libz.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libz.so.1
	libxxhash.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libxxhash.so.0
	libxtables.so.12 (libc6,x86-64) => /lib/x86_64-linux-gnu/libxtables.so.12
	libxml2.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libxml2.so.2
	libxcb.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libxcb.so.1
	libwrap.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libwrap.so.0
	libuv.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libuv.so.1
	libuuid.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libuuid.so.1
	libutil.so.1 (libc6,x86-64, OS ABI: Linux 3.2.0) => /lib/x86_64-linux-gnu/libutil.so.1
	libusb-1.0.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libusb-1.0.so.0
	libusb-0.1.so.4 (libc6,x86-64) => /lib/x86_64-linux-gnu/libusb-0.1.so.4
	libunwind.so.8 (libc6,x86-64) => /lib/x86_64-linux-gnu/libunwind.so.8
	libunwind-x86_64.so.8 (libc6,x86-64) => /lib/x86_64-linux-gnu/libunwind-x86_64.so.8
	libunwind-ptrace.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libunwind-ptrace.so.0
	libunwind-coredump.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libunwind-coredump.so.0
	libunistring.so.2 (libc6,x86-64) => /lib/x86_64-linux-gnu/libunistring.so.2
	libulockmgr.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libulockmgr.so.1
	libudev.so.1 (libc6,x86-64) => /lib/x86_64-linux-gnu/libudev.so.1
	libuchardet.so.0 (libc6,x86-64) => /lib/x86_64-linux-gnu/libuchardet.so.0
	libtirpc.so.3 (libc6,x86-64) => /lib/x86_64-linux-gnu/libtirpc.so.3
.............................

Help! I’ve lost my library!

Let’s say you’ll need a list of shared libraries that are required by an application. You can use “ldd” command here to find out library dependencies and that’ll help your troubleshooting about missing / required libraries.

Below, you’ll find library dependencies for “ls” program:

root@debian:~# ldd $(which ls)
	linux-vdso.so.1 (0x00007ffe14ffd000)
	libselinux.so.1 => /lib/x86_64-linux-gnu/libselinux.so.1 (0x00007f67feb16000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f67fe951000)
	libpcre2-8.so.0 => /lib/x86_64-linux-gnu/libpcre2-8.so.0 (0x00007f67fe8b9000)
	libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f67fe8b3000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f67feb6f000)
	libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f67fe891000)
Library dependencies for "ls" program
Library dependencies for “ls” program

Here’s another question: What if all libraries required are already installed but we still run into library problems? Well, sometimes libraries depend on another libraries. In the example above, you may check requirements and say all library dependencies for “ls” are installed. But you should check dependencies of these libraries too to find out the root cause.