Loading...

Lab 126: Dynamic Linker & Shared Library

Inspect shared library dependencies with ldd and verify how the dynamic linker resolves libraries at runtime. Make /opt/mylib discoverable via /etc/ld.so.conf.d and ldconfig, then validate the cache and test a temporary override with LD_LIBRARY_PATH.

linker libs ldconfig troubleshooting

Scenario

A vendor shipped a binary that depends on a custom shared library. The library was dropped under /opt/mylib and the binary now fails to start because the dynamic linker cannot find it. You need to prove what the binary needs, make the new path discoverable, refresh the loader cache, and validate resolution with a controlled, repeatable workflow.

Operator context

Treat this as a dependency triage task. Confirm the missing object, verify the search path and cache state, then apply a minimal persistent fix via /etc/ld.so.conf.d. Use LD_LIBRARY_PATH only for testing or containment.

Objective

  • Inspect shared library dependencies for a known binary using ldd.
  • Inspect the dynamic linker cache with ldconfig -p.
  • Confirm how /etc/ld.so.conf includes snippet files under /etc/ld.so.conf.d.
  • Add /opt/mylib to the loader search path using a dedicated snippet file.
  • Rebuild the loader cache with ldconfig and validate the new directory is scanned.
  • Use LD_LIBRARY_PATH as a temporary, per-shell override.

Concepts

  • ELF runtime linking: the dynamic loader resolves shared libraries at process start.
  • Dependency inspection with ldd to surface missing objects (not found).
  • Persistent linker configuration via /etc/ld.so.conf and /etc/ld.so.conf.d/*.conf.
  • Cache rebuild and visibility checks using ldconfig and ldconfig -p.
  • Temporary search-path override with LD_LIBRARY_PATH for scoped testing.

Walkthrough

Step 1 : Inspect shared library dependencies for a known binary.
Command
ldd /bin/ls

This prints loader resolution results: which libraries are required and what paths they map to. When a dependency cannot be resolved, you will typically see not found.

# Example pattern:
# libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f...)
# libdoesnotexist.so => not found
Step 2 : Inspect the dynamic linker cache.
Command
ldconfig -p | head

ldconfig -p prints what is currently known in ld.so.cache. If a library directory is not configured, its objects will not appear here.

Step 3 : Confirm how ld.so.conf is wired.
Command
grep -E '^[^#]' /etc/ld.so.conf

Most systems include drop-in snippet files via /etc/ld.so.conf.d/*.conf. That is the preferred place to add custom library paths without editing the top-level file directly.

Step 4 : List existing snippet files.
Command
ls -1 /etc/ld.so.conf.d

These files define additional search directories. Keep your change isolated in a single, clearly named snippet so it is easy to audit and roll back.

Step 5 : Add /opt/mylib via a new snippet file.
Command
echo /opt/mylib | sudo tee /etc/ld.so.conf.d/mylib.conf
Expectation

This only writes configuration. The loader cache will not change until you run ldconfig.

Step 6 : Rebuild the dynamic linker cache.
Command
sudo ldconfig

ldconfig scans configured directories and rebuilds ld.so.cache. This is the step that makes the new directory effective system-wide.

Step 7 : Prove ldconfig scanned the new directory.
Command
sudo ldconfig -v 2>/dev/null | grep -m1 /opt/mylib

This is a quick sanity check. If the directory does not appear, the snippet was not read or the file contents are invalid.

Step 8 : Use LD_LIBRARY_PATH as a temporary override.
Command
export LD_LIBRARY_PATH=/opt/mylib:$LD_LIBRARY_PATH

This prepends /opt/mylib for processes launched from the current shell. It does not modify system configuration and will not persist across sessions.

Operational note

Services started by systemd will not inherit this unless explicitly configured in the unit or environment file. Use this for validation, not as a long-term deployment strategy.

Common breakpoints

ldd shows “not found”

The library is missing, the path is not configured, or the SONAME does not match what the binary requests. Confirm the library exists under /opt/mylib, then rebuild the cache with ldconfig.

Snippet exists but ldconfig does not scan it

The snippet must contain a valid directory path on its own line. Also confirm /etc/ld.so.conf includes /etc/ld.so.conf.d/*.conf.

LD_LIBRARY_PATH works in a shell but not for a service

That is expected. It only affects the current shell’s process tree. If a service needs it for testing, define the environment in the systemd unit or an environment file.

Global search path change has unintended impact

Adding directories changes how multiple binaries resolve libraries. Keep paths narrow, prefer dedicated directories, and revalidate the target binary with ldd after changes.

Cleanup checklist

If you created a snippet under /etc/ld.so.conf.d, remove it and rebuild the cache to revert the system-wide search path.

Commands
sudo rm -f /etc/ld.so.conf.d/mylib.conf
sudo ldconfig
ldconfig -p | grep -m1 /opt/mylib || true
Success signal

ldconfig -v no longer lists /opt/mylib, and the cache output does not surface libraries from that directory.

Reference

  • ldd <binary> : Shows runtime shared library dependencies for an ELF binary.
  • ldconfig -p : Displays the current dynamic linker cache contents.
  • grep -E '^[^#]' /etc/ld.so.conf : Displays active (non-comment) loader configuration lines.
  • ls -1 /etc/ld.so.conf.d : Lists drop-in snippet files used by the loader configuration.
    • /etc/ld.so.conf.d/*.conf : Directory of snippet files that add search paths.
  • echo <dir> | sudo tee /etc/ld.so.conf.d/<name>.conf : Writes a new search path snippet for the dynamic linker.
    • tee : Writes to a root-owned file while still accepting stdin from a pipeline.
  • ldconfig : Rebuilds the dynamic linker cache based on configured directories.
  • ldconfig -v : Shows verbose scan output (useful for proving a directory is read).
    • -v : Enables verbose scanning output.
  • LD_LIBRARY_PATH=<dir>:<existing> : Temporarily prepends directories to the library search path for a process tree.