strace is a debugging tool that intercepts and records system calls made by a process and signals received by it. When you need to capture strace output for a long-running process or a process that produces a lot of output, redirecting it to a file is essential to avoid overwhelming your terminal and to have a persistent record for analysis.

Here’s how to do it:

strace -o /path/to/output.log your_command --with --options

The -o flag tells strace to write all its output to the specified file instead of standard error. The your_command --with --options part is the actual command you want to trace.

Let’s look at a practical example. Suppose you want to trace the startup of a web server like Nginx and save the output to a file named nginx_trace.log.

strace -o nginx_trace.log nginx -c

This command will execute nginx -c and dump all system calls and signals it makes into nginx_trace.log. The -c option for nginx is just an example; you’d replace it with whatever arguments your command needs.

Understanding the Output

The nginx_trace.log file will contain lines like these:

execve("/usr/sbin/nginx", ["nginx", "-c"], 0x7ffd865d2b60 /* 59 vars */) = 0
brk(NULL)                               = 0x55d80175b000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=183396, ...}) = 0
mmap(NULL, 183396, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f7c6d223000
close(3)                                = 0
openat(AT_FDCWD, "/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\260\345\1\0\0\0\0\0"..., 832) = 832
...

Each line represents a single system call or signal.

  • The first part is the system call name (e.g., execve, brk, openat).
  • The second part shows the arguments passed to the system call.
  • The third part is the return value of the system call.
  • Error codes are indicated by -1 followed by the error name (e.g., ENOENT).

Why Redirect?

When tracing a process that performs many operations, like starting a complex application or processing a large file, the standard error stream can fill up very quickly. Without redirection, your terminal might become unresponsive, and you’ll lose the trace data. Redirecting to a file ensures that all the information is captured persistently for later examination.

Advanced Usage: Appending to a File

If you are running strace multiple times and want to keep the output from each run, you can append to the log file using >>:

strace -o /path/to/output.log -e trace=open,read,write your_command

This is particularly useful if you’re debugging a scenario that requires several test runs.

Filtering System Calls

Often, you don’t need all system calls. strace allows you to filter the output, which can significantly reduce the log file size and make it easier to find relevant information.

For example, to trace only open, read, and write system calls:

strace -o file_io.log -e trace=open,read,write your_command

The -e trace= option specifies which system calls to include. You can also exclude calls using -e trace=!syscall_name.

Tracing Child Processes

If the command you are tracing spawns child processes, you’ll want to trace them too. Use the -f flag for this:

strace -o all_processes.log -f your_command

This will follow all child processes created by your_command. When combined with file redirection, it’s powerful for understanding complex process hierarchies.

Example: Tracing a Python Script

Let’s trace a simple Python script that reads a file:

# read_file.py
with open("my_data.txt", "r") as f:
    content = f.read()
    print(f"File content length: {len(content)}")

First, create my_data.txt with some content. Then, run strace:

echo "Hello, strace!" > my_data.txt
strace -o python_trace.log -f python read_file.py

The python_trace.log will show openat calls for my_data.txt, read calls to get its content, and write calls to stdout for the print statement.

Analyzing the Trace

Once you have the strace output in a file, you can use standard text processing tools like grep, awk, and less to analyze it.

For instance, to find all lines related to file opening:

grep "openat" python_trace.log

Or to see how many times read was called:

grep "read(" python_trace.log | wc -l

The Next Step: Performance Bottlenecks

After successfully capturing and reviewing system call traces, the next logical step in performance analysis is often identifying the specific system calls that are consuming the most time or occurring with excessive frequency. This might involve looking for patterns of repeated read or write operations to slow storage, or frequent stat calls checking file metadata.

Want structured learning?

Take the full Strace course →