Shared libraries and the dynamic linker
Shared libraries: how a dynamically linked program finds the code it needs at run time, why a freshly installed library can still be invisible, and the two ways to fix that.
Lesson 3 of 6 in objective 102. Linux installation and package management, part of LPIC-1 Exam 101-500.
Dynamic linking, and the cache that makes it fast
A statically linked program contains every library function it uses and depends on nothing at run time. A dynamically linked one — which is almost everything — contains only references, and the dynamic linker resolves them when the program starts. ldd prints that list for a binary, showing each required soname and the file it currently resolves to; a line reading "not found" is precisely the failure this objective is about.
Searching the whole filesystem on every program start would be slow, so the linker consults a cache: /etc/ld.so.cache, a binary file built by ldconfig from the directories listed in /etc/ld.so.conf and the files included from /etc/ld.so.conf.d/. This is why installing a library into a new directory is not enough — until you add the directory and run ldconfig, the linker does not know to look there.
LD_LIBRARY_PATH is the override: directories in it are searched before the cache. It is useful for testing and for running a program against a library you have not installed system-wide, and it is a poor permanent answer, because it applies to whatever inherits the environment rather than to the one program that needed it.
Sonames, and why versions do not break everything
A library file is usually named something like libfoo.so.1.2.3, with a symlink libfoo.so.1 pointing at it — that shorter name is the soname, and it is what a program records. The scheme means a compatible bug-fix release can replace the file and every program keeps working, while an incompatible release gets a new soname and the two can sit side by side. ldconfig is also what creates those symlinks, which is the second reason running it matters.
That makes three names for one library, and a question will lay all three out and ask which one the program holds. The readline history library ships as the file /usr/lib/x86_64-linux-gnu/libhistory.so.8.1; libhistory.so.8 is the soname symlink beside it, carrying the interface version and nothing finer; and libhistory.so, the unversioned linker name, is shipped only in the development package and is what the compiler follows at build time. The full file name is too specific to record and the unversioned one too vague, so the soname is the one written into the binary — which is why an update to .8.2 needs no rebuild and a move to .so.9 installs alongside rather than over the top.
The two commands sit on opposite sides of the bin/sbin split, and a question will use the full path rather than the name to test whether you know which. ldd only reports, so anyone may run it and it is /usr/bin/ldd. ldconfig writes the system-wide cache, so it is an administrative tool at /usr/sbin/ldconfig, reached as /sbin/ldconfig on distributions that have not merged the two. Being unable to run ldconfig as an ordinary user is the rule working, not a broken install.
/usr/bin/ldd /usr/local/bin/reportlibvendor.so.1 => not foundlibc.so.6 => /lib/x86_64-linux-gnu/libc.so.6the file exists in /opt/vendor/lib — the linker has not been toldecho /opt/vendor/lib > /etc/ld.so.conf.d/vendor.conf/usr/sbin/ldconfigldconfig -p | grep libvendorlibvendor.so.1 (libc6,x86-64) => /opt/vendor/lib/libvendor.so.1
Worth carrying in
- /usr/bin/ldd
- The shared libraries a program needs, and what each resolves to now. A reporting tool, so not in
sbin. - /usr/sbin/ldconfig
- Rebuild
/etc/ld.so.cacheand the soname symlinks.-pprints the current cache. - /etc/ld.so.conf
- Directories the cache is built from, plus whatever
ld.so.conf.dincludes. - /etc/ld.so.cache
- The binary cache the dynamic linker actually reads.
- LD_LIBRARY_PATH
- Colon-separated directories searched before the cache. For testing, not for production.
- soname
- The versioned name a program records — libfoo.so.1, not the full file name.
What the exam does with this
- The classic scenario: a library is installed,
lddsays "not found", and the answer is add the directory told.so.confand run ldconfig. ldconfig -pprints the cache; plainldconfigrebuilds it. Both appear as options in the same question.- Static binaries need no shared libraries at run time; that is the trade for their size.
- Three names, one library: the file
libhistory.so.8.1, the sonamelibhistory.so.8that a program records, and the unversionedlibhistory.sothe compiler links against. A question will list all three and ask which is stored.
- Objective
- 102. Linux installation and package management
- Share of the exam
- 18.33% (the whole objective)
- Questions in this lesson
- 6
- Signed for by a person
- 0
Partly checked. None of the 6 questions here has been read against the cited source by a person. 6 questions have been checked against their cited clause by an automated pass — which is not the same thing, and is not a signature.
Only questions a person has signed for are used in mock exams here. That is the whole difference between the two kinds of checking above.
How these questions are written — where each question comes from, what the verification ledger records, and what happens when one is found wrong.
Drill this lesson
A lesson is one sitting: the trainer draws a short run from these questions alone and spaces the ones you get wrong.
Practise Shared libraries and the dynamic linker
Questions in this lesson
- A program fails to start with an error about a missing shared object. Type the command that prints the shared libraries the binary /usr/bin/ssh depends on, and shows which file each one currently resolves to. machine-checked
- You installed a vendor application whose shared libraries live in /opt/vendor/lib. You added a line containing that directory to /etc/ld.so.conf.d/vendor.conf, but programs still cannot find the libraries. What is the missing step? machine-checked
- You have just edited /etc/ld.so.conf.d/local.conf to add a library directory. Type the command (no options or arguments) that rebuilds the dynamic linker cache so the change takes effect system-wide. machine-checked
- A developer wants to test a single program against a private build of a library in ~/testlib, without changing anything system-wide or affecting other users. What is the appropriate mechanism? machine-checked
- A library is installed as /usr/lib/x86_64-linux-gnu/libhistory.so.8.1 and its soname is libhistory.so.8. Which name does a dynamically linked program record, so that the dynamic linker can find the library at run time? machine-checked
- You want to confirm that the dynamic linker's cache already knows about libssl.so.3, without running or even having a program that uses it. Which command lists the cache contents? machine-checked
Practise Shared libraries and the dynamic linker
The rest of objective 102
- Planning a disk layout
- Installing and configuring a boot manager
- Shared libraries and the dynamic linker — you are here
- Debian package management
- RPM and DNF package management, and virtual guests
- Running Linux as a virtualization guest