8 ldd Command Examples in Linux

Last updated: November 8, 2023 | Linuxopsys

Ldd is a Linux command line utility that is used in case a user wants to know the shared library dependencies of an executable or even that of a shared library. You might have noticed many files starting with lib* in /lib and /usr/lib directories of your Linux machine. These files are called libraries. Library is a collection of resources such as subroutines/functions, classes, values or type specifications.

A library allows a program to utilize shared routines without the need to manage their source code or recompile them every time the program is built. This promotes code reuse and reduces the administrative and processing burdens associated with maintaining and compiling these routines.

There are two types of libraries:

Static libraries: Static libraries are for complete programs that do not depend on external libraries to run. The feature of statically linked programs is that they work without installing any prerequisites. The static library is end with *.a extension and these libraries are included (a separate copy) into the programs that require its functions.

Dynamic libraries: Dynamic libraries are tiny programs in size. These libraries end with .so extension. A key advantage of dynamic linking is its ability to share a single copy of a library among multiple running programs. This efficient resource sharing prevents redundant memory usage.

In this article, we will go through the ldd command in Linux with examples.

Shared libraries

Shared libraries contain pre-written code components used to perform various functions in programs. These libraries are linked with our code either during program building or runtime, enabling us to utilize existing code for routine or specialized tasks, thereby promoting code reuse and efficient development. Dynamic linking is the process of linking programs with these shared libraries at runtime.

Syntax

The syntax for the ldd command in Linux is as follows:

ldd [OPTIONS]... FILE...

OPTIONS

  • -v : Print all information, including symbol versioning information.
  • -d : Process data relocations and report any missing objects (ELF files only).
  • -r : Process relocations for both data objects and functions (ELF files only).
  • -u : Print unused direct dependencies.

Important points to understand before working with the ldd command and dynamic linking in Linux:

  • ld-linux.so (Dynamic Linker/Loader):
    • ld-linux.so is the Linux dynamic linker/loader.
    • It locates and loads shared libraries when you run a program.
  • ld.so.cache (Library Cache):
    • /etc/ld.so.cache is a cache file containing a list of shared libraries found in specified directories.
    • It speeds up dynamic linking by prelisting available libraries.
  • ld.so.conf (Library Configuration):
    • /etc/ld.so.conf is a config file specifying library search directories.
    • Libraries are searched in listed directories in order of appearance.

Install ldd

ldd is installed by default in most Linux distributions. If you getting ldd command not found error, install it using:

Ubuntu / Debian

apt install libc-bin

Redhat / CentOS Stream

yum install glibc-common

Fedora

dnf install glibc-common

Arch

pacman -S glibc

How to use ldd command

Let's look into some useful usages of ldd command.

1. Display dependencies of the command

We will display the dependencies of cp command.

ldd /bin/cp
    Output:
    linux-vdso.so.1 =>  (0x00007fffaf3ff000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
    librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
    libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
    libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
    libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)

2. Display dependencies of the command with details

We will display the dependencies of cp command with more details using -v option.

ldd -v /bin/cp
    Output:
     linux-vdso.so.1 =>  (0x00007fff473ff000)
        libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
        librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
        libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
        libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)
        libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
        libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
        /lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)

        Version information:
        /bin/cp:
                librt.so.1 (GLIBC_2.2.5) => /lib64/librt.so.1
                libattr.so.1 (ATTR_1.1) => /lib64/libattr.so.1
                libacl.so.1 (ACL_1.2) => /lib64/libacl.so.1
                libacl.so.1 (ACL_1.0) => /lib64/libacl.so.1
                libc.so.6 (GLIBC_2.6) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libselinux.so.1:
                libdl.so.2 (GLIBC_2.2.5) => /lib64/libdl.so.2
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
                libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.8) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/librt.so.1:
                libpthread.so.0 (GLIBC_2.2.5) => /lib64/libpthread.so.0
                libpthread.so.0 (GLIBC_PRIVATE) => /lib64/libpthread.so.0
                libc.so.6 (GLIBC_2.3.2) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
                libc.so.6 (GLIBC_PRIVATE) => /lib64/libc.so.6
        /lib64/libacl.so.1:
                libattr.so.1 (ATTR_1.0) => /lib64/libattr.so.1
                libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libattr.so.1:
                libc.so.6 (GLIBC_2.4) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libc.so.6:
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
        /lib64/libdl.so.2:
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
                libc.so.6 (GLIBC_PRIVATE) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6
        /lib64/libpthread.so.0:
                ld-linux-x86-64.so.2 (GLIBC_2.3) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_2.2.5) => /lib64/ld-linux-x86-64.so.2
                ld-linux-x86-64.so.2 (GLIBC_PRIVATE) => /lib64/ld-linux-x86-64.so.2
                libc.so.6 (GLIBC_2.3.2) => /lib64/libc.so.6
                libc.so.6 (GLIBC_PRIVATE) => /lib64/libc.so.6
                libc.so.6 (GLIBC_2.2.5) => /lib64/libc.so.6

3. Display unused direct dependencies of the command

We can display unused direct dependencies of cp command using -u option.

ldd -u /bin/cp
    Output:
     Unused direct dependencies:

        /lib64/libselinux.so.1
        /lib64/librt.so.1
        /lib64/libacl.so.1
        /lib64/libattr.so.1

4. Display ldd works only on dynamic executables

We will display ldd works only on dynamic executables using -r option.

ldd -r /smart/pycharm-community-2017.3.3/bin/pycharm.sh
    Output:
     not a dynamic executable

The output displayed a clear message state that the supplied file is not a dynamic executable.

5. ldd with standard command line executable

When we try ldd on a standard command line executable like ls, We need full path to the dynamic executable.

ldd ls
    Output:
    ldd: ./ls: No such file or directory

We see that ldd states that it cannot find ls.

ldd /bin/ls
    Output:
    linux-vdso.so.1 =>  (0x00007fff5cbea000)
    libselinux.so.1 => /lib64/libselinux.so.1 (0x0000003a06a00000)
    librt.so.1 => /lib64/librt.so.1 (0x0000003a06200000)
    libcap.so.2 => /lib64/libcap.so.2 (0x0000003a07600000)
    libacl.so.1 => /lib64/libacl.so.1 (0x0000003a13000000)
    libc.so.6 => /lib64/libc.so.6 (0x0000003a05200000)
    libdl.so.2 => /lib64/libdl.so.2 (0x0000003a05a00000)
    /lib64/ld-linux-x86-64.so.2 (0x0000003a04a00000)
    libpthread.so.0 => /lib64/libpthread.so.0 (0x0000003a05600000)
    libattr.so.1 => /lib64/libattr.so.1 (0x0000003a0ea00000)

But with the absolute path, ldd worked fine.

6. Know a given executable daemon supports TCP Wrapper

To determine whether a given executable daemon supports TCP Wrapper or not, run the following command.

sudo ldd /usr/sbin/sshd | grep libwrap
    Output:
    libwrap.so.0 => /lib64/libwrap.so.0 (0x00007f1cc2ac6000)

The output indicates that the OpenSSH (sshd) daemon supports TCP Wrapper.

7. ldd with missing dependency

We can use the ldd command when an executable is failing because of a missing dependency. Once we found a missing dependency, we can install it or update the cache with the ldconfig command.

sudo ldd /bin/mv
libacl.so.1 => /lib/libacl.so.1 (0×40016000)
libc.so.6 => /lib/libc.so.6 (0x4001c000)
libattr.so.1 => /lib/libattr.so.1 (0×40141000)
/lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0×40000000)

We will perform relocations and report any missing objects (ELF only) by typing the command.

sudo ldd -d path/to/executable_file

We will perform relocations for both data objects and functions, and report any missing objects or functions (ELF only) by typing the following command.

sudo ldd -r path/to/executable_file
SHARE

Comments

Please add comments below to provide the author your ideas, appreciation and feedback.

Leave a Reply

Leave a Comment