How to Use the Linux strace Command to Debug System Calls and Signals

The Need for Low-Level Process Debugging

In a Linux environment, diagnosing an application failure is often a process of elimination. If a web server fails to start, a script hangs indefinitely, or an application crashes with a generic “Segmentation Fault” or “Permission Denied” error, the application logs alone are rarely sufficient to identify the root cause.

When applications run, they must constantly interact with the Linux kernel to perform actual work—reading files, opening network sockets, allocating memory, and spawning threads. These interactions are called System Calls. If an application fails, the cause is almost always a failed system call.

To view these interactions in real-time, Linux administrators use strace (System Trace). strace intercepts and records the system calls made by a process and the signals received by a process, providing absolute visibility into what an application is actually doing behind the scenes.

Step 1: Tracing a Basic Command

The most straightforward way to use strace is to launch a command directly through it. For example, to see exactly how the cat command reads a file:

strace cat /etc/hostname

The output will be an overwhelming flood of text. You will see the process call execve to launch, mmap to load shared libraries into memory, openat to open the /etc/hostname file, read to fetch the data, write to push it to the standard output, and exit_group to close.

Every line represents a single system call, formatted as: syscall_name(arguments) = return_value. If a system call fails, the return value will be -1, followed by the specific error code (like ENOENT for “No such file or directory”).

Step 2: Attaching to a Running Process

Often, the application you need to debug is already running as a background daemon (like Nginx, MySQL, or a custom Python worker). You can attach strace to a live process using the -p (PID) flag.

First, find the Process ID:

pidof nginx

Then, attach strace as the root user (since tracing another user’s process requires elevated privileges):

sudo strace -p 12345

You will immediately see the live system calls scrolling by as the web server accepts connections (accept4), reads HTTP requests (recvfrom), opens local files (openat), and sends responses (sendto).

Step 3: Filtering the Noise

Because a modern application makes thousands of system calls per second, reading an unfiltered strace output is extremely difficult. The power of strace lies in its filtering capabilities using the -e (expression) flag.

Filtering File Operations

If you are troubleshooting a “Permission Denied” error, you only care about system calls related to opening or modifying files. You can trace just the open and openat calls:

strace -e trace=open,openat -p 12345

Filtering Network Operations

If a database connection is failing, you only want to see network-related system calls. strace provides logical groups of calls:

strace -e trace=network -p 12345

Filtering Signals

If an application keeps crashing unexpectedly, you can trace exactly what kill signals it is receiving (e.g., SIGTERM, SIGKILL, SIGSEGV):

strace -e trace=signal -p 12345

Step 4: Profiling System Call Times

strace is not just for tracking errors; it is an incredible performance profiling tool. If a script is running extremely slowly, you can use strace to summarize which system calls are taking the most time, rather than printing every single event.

Use the -c (count) flag to generate a summary report when the process exits or when you detach (via Ctrl+C):

strace -c ./my_slow_script.sh

The output will provide a clean table showing the total percentage of time spent on each system call, the number of calls made, and the number of errors. If you see that 95% of the execution time is spent on nanosleep or epoll_wait, you immediately know the application is waiting on external resources, not struggling with CPU computation.

Conclusion

strace is the ultimate magnifying glass for Linux troubleshooting. By intercepting the exact conversations between user-space applications and the Linux kernel, system administrators can cut through vague error logs and definitively identify missing files, denied permissions, and network bottlenecks at the lowest possible level.

RELATED POSTS

  • How to Check Your CPU Temperature in the Linux Terminal
  • How to Use the htop Command to Monitor Linux Server Performance
  • How to Use the cut Command to Extract Specific Columns of Data from a Text File in Linux
  • How to Configure Log Rotation using logrotate on Linux Servers
  • How to Use the find Command to Locate Files Modified in the Last 24 Hours in Linux
  • Get the best tech tips delivered straight to your inbox.

    Join thousands of readers mastering Apple, Google, Microsoft, and Linux.