Andrew Mercer
on this page

Basic usage

strace ls /tmp                          # trace a new command
sudo strace -p <pid>                    # attach to a running process (Ctrl+C to detach)
strace -o trace.txt -p <pid>            # write to a file
strace -t -p <pid>                      # add wall-clock timestamps
strace -tt -T -p <pid>                  # microsecond timestamps and time spent in each call
strace -c -p <pid>                      # summary table of calls, counts, time and errors
strace -f -o trace.txt command          # follow child processes and threads
strace -e trace=network command         # only network calls (also: file, process, memory, signal)
strace -e trace=openat,read command     # specific calls

A thorough capture

strace -f -tt -T -y -s 4096 -o out.strace command args
Flag Meaning
-f follow forks and threads
-tt microsecond timestamps
-T time spent in each syscall
-y show the path behind each file descriptor (newer strace)
-s 4096 print strings up to 4096 bytes instead of the default 32
-o file write output to a file

Attaching to a long-running multi-process service: strace -ff -tt -s 99999 -p <pid> |& tee /var/tmp/service-strace.out (-ff writes one file per process when combined with -o).

Reading the output

Look for calls returning -1 (with an errno name such as ENOENT or EACCES) right before the failure you are chasing. Long futex(), poll(), select(), or epoll_wait() calls usually mean the process is idle or waiting on something else, not busy.

strace slows the traced process noticeably. On a production system prefer perf trace or attach for a short time only.

References: futex, the syscalls(2) man page.

in this section
* strace comprehensive guide