Programs on Linux often require external libraries to run correctly. These libraries are either loaded dynamically during runtime or built directly into the program. By using shared libraries, programs can reduce size and reuse common code. Typically, shared libraries are stored in the /lib or /usr/lib directories.

A program compiled on one version of Linux may not work on another if the required libraries are missing or incompatible. This can lead to errors, especially when the program tries to load a shared library that is absent. Missing libraries or incorrect versions can prevent the program from starting, often resulting in an error like cannot open shared object file.

$ sudo dpkg
sudo: error while loading shared libraries: libpthread.so.0: 
cannot open shared object file: No such file or directory

To fix these issues, you can inspect the program's shared library dependencies. Linux provides tools like ldd to list dynamic libraries required by a program. These tools help identify the exact dependencies so that missing libraries can be installed or updated as needed.

Steps to check library dependencies in Linux:

  1. Open the terminal application.
  2. Determine the absolute path of the program you want to inspect.
    $ which bash
    /usr/bin/bash
  3. Display the shared object dependencies of the program.
    $ 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)

    The ldd command shows all shared libraries required by a program. The path returned points to where each library is located on the system.

  4. Run ldd in verbose mode to view additional information.
    $ 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>.
  5. Use readelf to check dynamic library dependencies of a program.
    $ 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]
  6. Inspect libraries required by a running process using the proc filesystem.
    $ 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
  7. List memory-mapped shared libraries of a running process using lsof.
    $ 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 fetches the process ID of the first bash process running.

  8. Use pmap to check the memory maps of a running process and list shared libraries.
    $ 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
Discuss the article:

Comment anonymously. Login not required.