Shared libraries are compiled codes that could be used by programs for a particular operating system. It eases the development and distribution of programs as these libraries does not need to be packaged together with the program.

In Linux, shared libraries are normally stored in /lib* or /usr/lib*. Different Linux distribution or different version of a distribution might package different version of libraries, making a program compiled for a particular distribution or version might not properly run on another.

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

You can check the list of libraries required for a program using ldd or a few other methods at the terminal if your program is having trouble loading all the required shared libraries.

Find shared library dependency in Linux:

  1. Launch your preferred terminal application
  2. Get absolute path of the program you want to check.
    $ which bash
    /usr/bin/bash
  3. Print shared object dependencies using ldd.
    $ 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)
  4. Print verbose dependency info using ldd.
    $ 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. Find dynamic library required by program using readelf.
    $ 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. Read library requirement of running processes from /proc/<process-id>/maps.
    $ 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. View shared library requirement 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 gets the ID of the first process named bash

  8. Use pmap to gather shared library requirement of a program.
    $ 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.

Share!