strace — Trace System Calls and Signals of a Process

Practical guide to strace: trace system calls, diagnose failing programs and track down performance bottlenecks at the OS level.

strace shows you what a program actually does: it logs every system call to the Linux kernel, complete with arguments and return value – from opening a file to network connections to received signals. That lets you find out why a process hangs, which config file it searches for in vain, or where time is being lost, all without reading the source code. This guide takes you from plain capturing through targeted filters to syscall statistics for profiling.

Basic Tracing

strace <command> — Trace all system calls of a command.

strace ls -la

strace -p <pid> — Attach to and trace a running process (needs ptrace permission, often sudo).

strace -p 1234

strace -f <command> — Follow child processes (forks).

strace -f nginx

strace -o <file> <command> — Write trace output to a file.

strace -o trace.log ./myapp

strace -ff -o <prefix> <command> — Write each process trace to a separate file.

strace -ff -o traces/app ./myapp

Filter by System Call

strace -e trace=<syscall> <command> — Trace only specific system calls.

strace -e trace=open,read,write ls

strace -e trace=file <command> — Trace file-related system calls.

strace -e trace=file cat /etc/hosts

strace -e trace=network <command> — Trace network-related system calls.

strace -e trace=network curl -s https://example.com

strace -e trace=process <command> — Trace process management calls (fork, exec, wait).

strace -e trace=process bash -c 'ls | grep txt'

strace -e trace=memory <command> — Trace memory management calls (mmap, brk, etc.).

strace -e trace=memory ./myapp

strace -e trace=signal <command> — Trace signal-related system calls.

strace -e trace=signal ./myapp

Timing & Performance

strace -T <command> — Show time spent in each system call.

strace -T ./myapp

strace -t <command> — Prefix each line with time of day.

strace -t ./myapp

strace -tt <command> — Prefix with time of day including microseconds.

strace -tt ./myapp

strace -r <command> — Show relative timestamp (time since previous call).

strace -r ./myapp

strace -c <command> — Count and summarize system calls (statistics).

strace -c ls -la /usr

strace -C <command> — Show both regular trace and summary statistics.

strace -C ./myapp

strace -c -S time <command> — Sort summary by time spent (default: calls).

strace -c -S time ./myapp

Output Options

strace -s <size> <command> — Set max string length in output (default 32).

strace -s 1024 -e trace=read ./myapp

strace -v <command> — Verbose mode: don't abbreviate structures.

strace -v stat /etc/hosts

strace -y <command> — Show file paths for file descriptor arguments.

strace -y -e trace=read,write ./myapp

strace -yy <command> — Show socket addresses and device details for FDs.

strace -yy -e trace=network curl -s https://example.com

Common Patterns

strace -e trace=openat <command> 2>&1 | grep <file> — Find which files a program tries to open.

strace -e trace=openat python app.py 2>&1 | grep config

strace -e trace=connect <command> — See what network connections a program makes.

strace -e trace=connect curl -s https://example.com

strace -e trace=openat -p <pid> 2>&1 | grep -v ENOENT — Watch file access of a running process (exclude failures).

strace -e trace=openat -p $(pidof nginx) 2>&1 | grep -v ENOENT

strace -c -p <pid> -e trace=all — Profile system call usage of a running process.

strace -c -p $(pidof php-fpm) -e trace=all

strace -e trace=write -s 1024 -p <pid> — Watch what a process writes (debug output issues).

strace -e trace=write -s 1024 -p 1234

Conclusion

strace is the first tool you reach for when a program misbehaves in puzzling ways and the logs reveal nothing: strace -f -e trace=file uncovers missing files, -e trace=network reveals blocked connections, and -c gives you a quick syscall profile. Keep two things in mind, though. First, tracing slows the target down considerably – use it carefully on production systems, ideally time-boxed. Second, and more importantly: strace prints syscall arguments in clear text and can expose passwords, tokens or keys in the process. So only attach to your own or explicitly authorised processes; strace -p requires the ptrace permission anyway (yama ptrace_scope, usually sudo). macOS has no strace – there you use dtruss or dtrace instead.

Further Reading

  • strace.io – the official project site with documentation and downloads
  • Wikipedia: strace – background and how the system-call tracer works
  • lsof – lists the open files and sockets of a process
  • ps – lists running processes with the PIDs you feed to strace -p
  • dmesg – reads the kernel ring buffer for low-level error messages