How to Determine and Configure LDD’s Library Search Path in Linux Systems


2 views

When troubleshooting shared library dependencies with ldd, understanding its search path mechanism is crucial. The tool follows the same search rules as the dynamic linker (ld.so), which is configured through several mechanisms:

1. DT_RPATH in the ELF binary (deprecated but still used)
2. DT_RUNPATH in the ELF binary
3. LD_LIBRARY_PATH environment variable
4. /etc/ld.so.cache (built from /etc/ld.so.conf)
5. Default paths: /lib and /usr/lib (plus architecture-specific variants)

To view the effective search paths, use these commands:

# Display the linker's default configuration
ldconfig -v 2>/dev/null | grep -v ^$'\t'

# Alternative method showing registered directories
cat /etc/ld.so.conf.d/*.conf

# For runtime inspection of a specific binary:
readelf -d /path/to/binary | grep -E 'RPATH|RUNPATH'

When you encounter output like:

libstdc++.so.5 => not found

Here's how to resolve it:

# Locate the library manually
find / -name libstdc++.so.5 2>/dev/null

# Once found, add its directory to the search path temporarily
export LD_LIBRARY_PATH=/path/to/library:$LD_LIBRARY_PATH

# Or permanently by creating a new config file
echo "/path/to/library" | sudo tee /etc/ld.so.conf.d/custom.conf
sudo ldconfig

For developers building packages, you can embed search paths directly in the binary:

# During compilation with GCC:
gcc -Wl,-rpath=/custom/library/path -o output input.c

# To verify the embedded path:
readelf -d output | grep RPATH

When dealing with multi-arch systems (x86_64 vs. i386):

# For 32-bit libraries on 64-bit systems:
dpkg -L libc6-i386 | grep .so
# Or on RPM systems:
rpm -ql glibc.i686 | grep .so

# Cross-arch linking example:
gcc -m32 -Wl,-rpath=/usr/lib32 -o output32 input.c

Remember that system-wide changes should be made through /etc/ld.so.conf or its included files rather than modifying LD_LIBRARY_PATH globally.


When examining shared library dependencies with ldd, it's crucial to understand how the dynamic linker locates libraries. The search paths shown in your example (/lib64, etc.) are determined by several configuration mechanisms:

$ ldd /path/to/your/binary
    linux-vdso.so.1 => (0x00007ffd45bf9000)
    libexample.so.1 => /usr/local/lib/libexample.so.1
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6

The search path is primarily controlled by:

  • /etc/ld.so.conf - Main configuration file
  • Files in /etc/ld.so.conf.d/ - Additional configuration snippets
  • Environment variables (LD_LIBRARY_PATH, etc.)

To inspect the current library search paths:

$ ldconfig -v 2>/dev/null | grep -v ^$'\t'
/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu
/usr/local/lib

Alternatively, check the config files directly:

$ cat /etc/ld.so.conf
include /etc/ld.so.conf.d/*.conf

$ ls /etc/ld.so.conf.d/
fakeroot-x86_64-linux-gnu.conf  libc.conf  x86_64-linux-gnu.conf

To add a new library path (e.g., /opt/myapp/lib):

# Create new config file
echo '/opt/myapp/lib' | sudo tee /etc/ld.so.conf.d/myapp.conf

# Update cache
sudo ldconfig

For temporary changes (current session only):

export LD_LIBRARY_PATH=/custom/path:$LD_LIBRARY_PATH
ldd /path/to/binary

For detailed debugging of library resolution:

$ LD_DEBUG=libs ldd /path/to/binary
     31533:     find library=libexample.so.1 [0]; searching
     31533:      search path=/opt/myapp/lib/tls/x86_64:/opt/myapp/lib/tls:/opt/myapp/lib/x86_64
     31533:      trying file=/opt/myapp/lib/tls/x86_64/libexample.so.1
     31533:      trying file=/opt/myapp/lib/tls/libexample.so.1
     31533:      trying file=/opt/myapp/lib/x86_64/libexample.so.1

Remember that ldd itself uses the dynamic linker (ld.so) to resolve dependencies, following the same path resolution rules as executed programs.