Programs often rely on external libraries to function correctly. These libraries can either be compiled directly into the program or loaded from a shared library pool. Using shared libraries helps minimize program size and simplifies development and distribution. In Linux, shared libraries are usually stored in /lib* or /usr/lib* directories.
Different Linux distributions or even versions of the same distribution might utilize different libraries, causing a program compiled for one distribution or version to malfunction on another. When the required library is missing from the system, you may encounter an error.
$ sudo dpkg sudo: error while loading shared libraries: libpthread.so.0: cannot open shared object file: No such file or directory
To resolve shared library loading issues, you can use ldd or other command-line tools to determine the shared libraries a program depends on.
$ which bash /usr/bin/bash
$ ldd /usr/bin/bash linux-vdso.so.1 (0x00007ffdd2749000) libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007fcecb9b6100) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fcecb9b0000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcecb7c5000) /lib64/ld-linux-x86-64.so.2 (0x00007fcecbb21000)
$ ldd --verbose /usr/bin/bash linux-vdso.so.1 (0x00007ffce299c000) libtinfo.so.6 => /lib/x86_64-linux-gnu/libtinfo.so.6 (0x00007f6fb24dd000) libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6fb24d6100) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6fb22ec000) /lib64/ld-linux-x86-64.so.2 (0x00007f6fb2648000) Version information: /usr/bin/bash: libdl.so.2 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libdl.so.2 libtinfo.so.6 (NCURSES6_TINFO_5.0.19991023) => /lib/x86_64-linux-gnu/libtinfo.so.6 libc.so.6 (GLIBC_2.11) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.8) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.15) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libtinfo.so.6: libc.so.6 (GLIBC_2.3) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.14) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.16) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libdl.so.2: ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2 libc.so.6 (GLIBC_PRIVATE) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.4) => /lib/x86_64-linux-gnu/libc.so.6 libc.so.6 (GLIBC_2.2.5) => /lib/x86_64-linux-gnu/libc.so.6 /lib/x86_64-linux-gnu/libc.so.6: ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2 ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
More options for ldd:
$ ldd --help Usage: ldd [OPTION]... FILE... --help print this help and exit --version print version information and exit -d, --data-relocs process data relocations -r, --function-relocs process data and function relocations -u, --unused print unused direct dependencies -v, --verbose print all information For bug reporting instructions, please see: <https://bugs.launchpad.net/ubuntu/+source/glibc/+bugs>.
$ readelf --dynamic /usr/bin/bash | grep NEEDED 0x0000000000000001 (NEEDED) Shared library: [libtinfo.so.6] 0x0000000000000001 (NEEDED) Shared library: [libdl.so.2] 0x0000000000000001 (NEEDED) Shared library: [libc.so.6]
$ awk '/\.so/{print $6}' /proc/$(pgrep bash | head -n1)/maps | sort -u /usr/lib/x86_64-linux-gnu/ld-2.29.so /usr/lib/x86_64-linux-gnu/libc-2.29.so /usr/lib/x86_64-linux-gnu/libdl-2.29.so /usr/lib/x86_64-linux-gnu/libnss_files-2.29.so /usr/lib/x86_64-linux-gnu/libtinfo.so.6.1
$ lsof -p $(pgrep bash | head -n1) | grep mem\ bash 4470 user mem REG 8,1 51672 404577 /usr/lib/x86_64-linux-gnu/libnss_files-2.29.so bash 4470 user mem REG 8,1 14529344 401393 /usr/lib/locale/locale-archive bash 4470 user mem REG 8,1 2000480 403822 /usr/lib/x86_64-linux-gnu/libc-2.29.so bash 4470 user mem REG 8,1 18656 403961 /usr/lib/x86_64-linux-gnu/libdl-2.29.so bash 4470 user mem REG 8,1 183528 404929 /usr/lib/x86_64-linux-gnu/libtinfo.so.6.1 bash 4470 user mem REG 8,1 26402 789841 /usr/lib/x86_64-linux-gnu/gconv/gconv-modules.cache bash 4470 user mem REG 8,1 179032 403610 /usr/lib/x86_64-linux-gnu/ld-2.29.so
pgrep bash | head -n1 gets the ID of the first process named bash
$ pmap $(pgrep bash | head -n1) | grep \.so | awk '{ print $4 }' | sort -u ld-2.29.so libc-2.29.so libdl-2.29.so libnss_files-2.29.so libtinfo.so.6.1
Comment anonymously. Login not required.