- I tested Samsung's 98-inch 4K QLED TV, and watching Hollywood movies on it left me in awe
- Apple is working on a doorbell that unlocks your door Face ID-style
- 5 biggest Linux and open-source stories of 2024: From AI arguments to security close calls
- Securing the OT Stage: NIS2, CRA, and IEC62443 Take Center Spotlight
- Trump taps Sriram Krishnan for AI advisor role amid strategic shift in tech policy
Using the ldd command on Linux
Shared object files streamline programs by providing information applications need to do their jobs, but that don’t have to be part of the application itself. To find out which of these files a Linux command calls on, use the ldd command.
What is a shared object file?
Shared object files (designated as .so) are libraries that are automatically linked into a program when the program starts, yet exist as a standalone files. They contain information that can be used by one or more programs to offload resources so that any program calling a .so file doesn’t itself have to actually provide all the needed tools. These files can be linked to any program and be loaded anywhere in memory.
A single .so file might contain information and functions on how to quickly search through the whole computer or perform very complex calculations. Several programs can then call upon that .so file. In fact, .so files can be updated/replaced without those programs having to make any changes to their own code.
Shared libraries can be linked to any program at run-time. Think of them as chunks of code that can be used by many different programs, thus allowing those programs to be smaller and much more efficient than ensuring all the programs that use them contain them and get updated as needed if the code changes.
Using ldd
This simple example uses ldd to find out what files the date command uses:
$ ldd /usr/bin/date linux-vdso.so.1 (0x00007ffd230e5000) libc.so.6 => /lib64/libc.so.6 (0x00007f8e9fc54000) /lib64/ld-linux-x86-64.so.2 (0x00007f8e9fe52000)
The result above shows that the date command uses three shared object files.
Note that you have to include a full pathname to the file when using ldd. Otherwise, ldd looks into the current directory for the program name and isn’t likely to find it.
$ ldd date ldd: ./date: No such file or directory
If you’re not sure where a particular program is located, you can use the which command in either of the forms shown below.
$ which pwd /usr/bin/pwd $ ldd /usr/bin/pwd linux-vdso.so.1 (0x00007ffe9df9b000) libc.so.6 => /lib64/libc.so.6 (0x00007f686d670000) /lib64/ld-linux-x86-64.so.2 (0x00007f686d85d000)
or
$ ldd `which pwd` linux-vdso.so.1 (0x00007ffc3b9e4000) libc.so.6 => /lib64/libc.so.6 (0x00007f2d491a9000) /lib64/ld-linux-x86-64.so.2 (0x00007f2d49396000)
You can get a lot more information by using the -v (or –verbose) option:
$ ldd -v `which pwd` linux-vdso.so.1 (0x00007ffeea1f6000) libc.so.6 => /lib64/libc.so.6 (0x00007ff3b0c64000) /lib64/ld-linux-x86-64.so.2 (0x00007ff3b0e51000) Version information: /usr/bin/pwd: libc.so.6 (GLIBC_2.3) => /lib64/libc.so.6 libc.so.6 (GLIBC_2.14) => /lib64/libc.so.6 libc.so.6 (GLIBC_2.3.4) => /lib64/libc.so.6 libc.so.6 (GLIBC_2.33) => /lib64/libc.so.6 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_2.2.5) => /lib64/ld-linux-x86-64.so.2 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
The ldd command is sometimes used when it appears that a needed shared library is missing, and instead a “not found” message is generated. For example:
libcsfml-graphics.so.2.2 => not found
If many or all of the needed libraries are missing, you might actually be missing a configuration file or symbolic link meant to make the connection. Missing shared object files are very uncommon, and you are unlikely to ever run into this problem.
Some programs use only a few shared libraries while others use a pile of them. Take a look at the reboot command and you will see a very long list of files like this:
$ ldd /usr/sbin/reboot linux-vdso.so.1 (0x00007ffd0b374000) libsystemd-shared-249.so => /usr/lib/systemd/libsystemd-shared-249.so (0x00007f30fbec3000) libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f30fbe9a000) libc.so.6 => /lib64/libc.so.6 (0x00007f30fbc90000) libacl.so.1 => /lib64/libacl.so.1 (0x00007f30fbc85000) libblkid.so.1 => /lib64/libblkid.so.1 (0x00007f30fbc4d000) libcap.so.2 => /lib64/libcap.so.2 (0x00007f30fbc43000) libcrypt.so.2 => /lib64/libcrypt.so.2 (0x00007f30fbc07000) libgcrypt.so.20 => /lib64/libgcrypt.so.20 (0x00007f30fbacb000) libip4tc.so.2 => /lib64/libip4tc.so.2 (0x00007f30fbac1000) libkmod.so.2 => /lib64/libkmod.so.2 (0x00007f30fbaa6000) liblz4.so.1 => /lib64/liblz4.so.1 (0x00007f30fba82000) libmount.so.1 => /lib64/libmount.so.1 (0x00007f30fba3d000) libcrypto.so.1.1 => /lib64/libcrypto.so.1.1 (0x00007f30fb74d000) libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007f30fb61b000) libpam.so.0 => /lib64/libpam.so.0 (0x00007f30fb609000) libseccomp.so.2 => /lib64/libseccomp.so.2 (0x00007f30fb5e8000) libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f30fb5bc000) libzstd.so.1 => /lib64/libzstd.so.1 (0x00007f30fb4c6000) liblzma.so.5 => /lib64/liblzma.so.5 (0x00007f30fb498000) /lib64/ld-linux-x86-64.so.2 (0x00007f30fc216000) libattr.so.1 => /lib64/libattr.so.1 (0x00007f30fb490000) libgpg-error.so.0 => /lib64/libgpg-error.so.0 (0x00007f30fb46a000) libpcap.so.1 => /lib64/libpcap.so.1 (0x00007f30fb41d000) libz.so.1 => /lib64/libz.so.1 (0x00007f30fb403000) libffi.so.6 => /lib64/libffi.so.6 (0x00007f30fb3f6000) libaudit.so.1 => /lib64/libaudit.so.1 (0x00007f30fb3c8000) libeconf.so.0 => /lib64/libeconf.so.0 (0x00007f30fb3bd000) libm.so.6 => /lib64/libm.so.6 (0x00007f30fb2e1000) libpcre2-8.so.0 => /lib64/libpcre2-8.so.0 (0x00007f30fb24a000) libibverbs.so.1 => /lib64/libibverbs.so.1 (0x00007f30fb228000) libcap-ng.so.0 => /lib64/libcap-ng.so.0 (0x00007f30fb21d000) libnl-route-3.so.200 => /lib64/libnl-route-3.so.200 (0x00007f30fb197000) libnl-3.so.200 => /lib64/libnl-3.so.200 (0x00007f30fb173000)
Of course, what this output doesn’t tell you is how many programs use these shared libraries and how much trouble you would have if one of the more important ones was removed from your system. Even common commands could stop working.
Don’t be fooled. Likely every command that you enter on a Linux system is using shared libraries. Even as modest a command as echo uses several:
$ ldd /usr/bin/echo linux-vdso.so.1 (0x00007ffdbf99d000) libc.so.6 => /lib64/libc.so.6 (0x00007f0696277000) /lib64/ld-linux-x86-64.so.2 (0x00007f069649c000)
The criticality of these files is quite obvious. Fortunately, it’s easy to appreciate them, but otherwise let them do their thing. There’s no way to peer into them or inquire about how they work. You can display some details like those shown below, but this doesn’t provide much insight the functions the files provide.
$ ls -l /lib64/libc.so.6 -rwxr-xr-x. 1 root root 2387984 Oct 1 14:19 /lib64/libc.so.6 $ file /lib64/libc.so.6 /lib64/libc.so.6: ELF 64-bit LSB shared object, x86-64, version 1 (GNU/Linux),
dynamically linked, interpreter lib64/ld-linux-x86-64.so.2, BuildID[sha1]=
f891252f9069edee265f92cfb9a163880999588b, for GNU/Linux 3.2.0, not stripped
Wrap-Up
Shared object files are an extremely important part of any Linux system as they allow programs to share resources that can be updated and loaded into memory separately. It’s easy to determine what shared object files any particular command uses, but virtually impossible to determine the roles that they are playing.
Copyright © 2022 IDG Communications, Inc.