Article :: Debugging with strace

Introduction

By the end of this article, you’ll understand how to use strace to debug programs without access to source code, trace system calls, and troubleshoot execution issues in Linux.

Overview

Debugging without source code can feel like solving a puzzle in the dark. Strace shines a light by showing you exactly what system calls a program makes, from opening files to network connections. Whether you’re troubleshooting a crash, investigating suspicious behavior, or just curious about how a program works under the hood, strace is an essential tool in your Linux toolkit.

Strace monitors the system calls and signals of a specific program, providing the execution sequence from start to end. It’s particularly valuable when you don’t have source code access and need to understand what a program is actually doing at the system level.

Prerequisites

Before starting, you should have:

What is strace?

Strace is a diagnostic and debugging tool that intercepts and records system calls made by a process. It’s particularly useful when:

Tracing an Execution

The simplest way to use strace is to run it with a program:

1
strace Binary_File

This outputs every system call made by the program to stderr, which can be overwhelming for complex programs.

Useful options:

Filtering System Calls

Strace’s real power comes from filtering. Use the -e option to focus on specific system calls:

1
strace -e socket,send,recv nc google.com 80

This shows only network-related calls, filtering out hundreds of irrelevant system calls.

Common filter categories:

Attaching to Running Processes

You can attach strace to an already running process using its PID:

1
strace -p PID

This is invaluable for debugging live systems without restarting services.

Example: Debug a hanging web server:

1
2
3
4
5
# Find the PID
ps aux | grep nginx

# Attach strace (may require sudo)
sudo strace -p 1234

Analyzing Program Statistics

The -c flag provides a summary report instead of detailed output, showing:

1
strace -c binary_file arguments

This is perfect for performance analysis and identifying bottlenecks.

Example output:

% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 45.12    0.012345          23       537           read
 32.45    0.008876          45       197           write
 12.34    0.003376         112        30           open

Key Takeaways

Practice Exercises

  1. Run strace ls /tmp and identify the system calls used to read the directory
  2. Use strace -e open cat /etc/passwd to see which files cat opens before reading your target file
  3. Create a simple Python script and use strace -c to analyze which system calls dominate
  4. Attach strace to a long-running process (like a text editor) and observe its system calls during idle time

Further Reading