ltrace

Trace dynamic library calls made by a process (user‑space boundary). Think: strace for syscalls, ltrace for shared-library calls.

Category: Debugging Library call tracing Dynamic linking Troubleshooting strace companion

What it does

ltrace intercepts and prints calls that a program makes to shared libraries (for example: printf(), malloc(), getaddrinfo(), SSL_read()). It helps you see what the program is doing in user space before/around kernel syscalls.

strace: shows syscalls (kernel boundary)
openat()read()connect()
ltrace: shows library calls (user-space boundary)
fopen()malloc()getenv()

How it works (mechanical)

On dynamically linked programs, many functions are resolved through the runtime linker (PLT/GOT). ltrace uses process tracing to hook those call boundaries and record arguments and return values for library functions. This means it works best when the program is dynamically linked and symbols are available.

  • Best on dynamically linked binaries
  • Limited/ineffective on fully static binaries
  • Some functions may be inlined or optimized away (not traceable)

10 Practical Examples

# 1) Trace a command (basic)
ltrace ls
# 2) Trace a program with arguments
ltrace curl -I https://example.com
# 3) Trace an existing process by PID
sudo ltrace -p 12345
# 4) Write output to a file (clean logs)
ltrace -o ltrace.log curl https://example.com
# 5) Show timestamps (helpful for “hang” diagnosis)
ltrace -tt ./myapp
# 6) Filter to specific functions (example: DNS + sockets via libc)
ltrace -e getaddrinfo,freeaddrinfo,connect,send,recv curl https://example.com
# 7) Filter to memory behavior (quick suspicion check)
ltrace -e malloc,calloc,realloc,free ./myapp
# 8) Count calls and summarize (profile-ish view)
ltrace -c ./myapp
# 9) Follow forks (multi-process apps)
sudo ltrace -f ./myapp
# 10) Combine with strace (two complementary lenses)
ltrace -o ltrace.log ./myapp
strace -o strace.log -ff ./myapp

Notes & Gotchas

  • Interactive / curses apps: tracing can slow the program and scramble terminal output; log to a file with -o.
  • Static binaries: if the binary is statically linked, ltrace may show little or nothing.
  • Optimizations: inlined functions and LTO builds reduce what’s visible.
  • Permissions: attaching to processes often needs root (ptrace restrictions).
  • Noise: start with -e filters and -c summaries to keep signal high.
# Quick check: is it dynamically linked?
ldd ./myapp

Historical Context

ltrace became popular as Linux systems grew more complex and dynamically linked software became the norm. It complements strace: where strace reveals kernel interactions, ltrace reveals the “conversation” between your program and its libraries.

Modern Equivalent / Related Tools

  • strace — trace syscalls (kernel boundary)
  • ldd — show shared library dependencies
  • readelf / objdump — inspect ELF symbols, PLT/GOT, relocations
  • perf — sampling profiler (performance hotspots)
  • bpftrace / eBPF tools — modern, low-overhead observability (advanced)
  • gdb — interactive debugging