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.
openat() • read() • connect()
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,
ltracemay 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
-efilters and-csummaries 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