Skip to main content
โšก Calmops

strace and Performance Profiling: Linux System Analysis

Introduction

When applications misbehave - whether running slowly, crashing, or consuming excessive resources - you need powerful diagnostic tools to understand what’s happening under the hood. Linux provides an excellent toolkit for system analysis, with strace and perf standing out as essential utilities for debugging and performance optimization.

This comprehensive guide covers system call tracing with strace, hardware performance profiling with perf, and complementary tools for comprehensive system analysis. These skills are indispensable for developers, DevOps engineers, and system administrators troubleshooting production issues in 2026.

Understanding System Calls

What Are System Calls?

System calls (syscalls) are the fundamental interface between user-space applications and the Linux kernel. When a program needs to read a file, allocate memory, create a network connection, or perform any privileged operation, it makes a system call to request kernel assistance.

Common system calls include:

  • File operations: open, read, write, close, stat
  • Process management: fork, execve, wait, exit
  • Memory management: mmap, brk, mprotect
  • Networking: socket, connect, send, recv
  • Inter-process communication: pipe, shmget, msgget

Understanding which system calls an application makes provides invaluable insight into its behavior.

System Call Lifecycle

When a program makes a system call:

  1. Application prepares arguments in registers
  2. Software interrupt (0x80 on x86) triggers kernel mode switch
  3. Kernel validates arguments and permissions
  4. Kernel performs the requested operation
  5. Result returned to userspace
  6. Control returns to application

This process involves context switching overhead, making system call frequency critical to performance.

strace: System Call Tracer

Getting Started with strace

The strace command intercepts and records system calls made by a process:

# Install strace
sudo apt install strace

# Basic usage - trace command execution
strace ls -l

# Trace running process
strace -p 1234

# Trace new process and exit
strace -f -o output.log your_application

Essential strace Options

# Timestamp each call
strace -t ls                          # Time only
strace -tt ls                        # Microseconds
strace -ttt ls                       # Epoch timestamp

# Relative timing
strace -r ls                         # Relative time between calls

# Filter specific calls
strace -e trace=open,read,write ls
strace -e trace=network ls
strace -e trace=file ls
strace -e trace=process ls

# Follow child processes
strace -f -o full.log nginx

# Summary statistics
strace -c ls
strace -c -f python script.py

Practical strace Examples

Diagnosing file access issues:

# Find which files an application opens
strace -e trace=open,openat,close python app.py 2>&1 | grep -E "open|ENOENT"

# Detailed file operations
strace -e trace=openat -v python app.py

# Monitor specific file
strace -f -e trace=openat -e inotify /var/log/app.log

Network debugging:

# Trace network syscalls
strace -e trace=socket,connect,sendto,recvfrom curl example.com

# Full network details
strace -e trace=network -v curl example.com

Performance analysis:

# Count syscalls and timing
strace -c -f ./myapp

# Output:
# % time     seconds  usecs/call     calls    errors syscall
# ------ ----------- ----------- --------- --------- ----------------
#  45.00    0.001234          12       102           read
#  30.00    0.000821           8        98           write
#  10.00    0.000274           2       150           fstat
#   5.00    0.000137           1        95           mmap
#   ...

# Find slow system calls
strace -r python slow_script.py | head -20

Process debugging:

# Follow fork/exec
strace -f -e trace=fork,execve,binary

# Trace child immediately after fork
strace -f -o child.log -s 200 binary

# Attach to running process
strace -p $(pgrep -f myapp) -f

Interpreting strace Output

# Sample output
read(3, "Hello, World!\n", 1024) = 13
write(1, "Hello, World!\n", 13)   = 13
openat(AT_FDCWD, "/etc/passwd", O_RDONLY) = 3

Format: syscall(arg1, arg2, ...) = return_value

Common patterns:

  • -1 (or negative) indicates error (check errno)
  • = -1 ENOENT (No such file or directory) shows the error
  • Large numbers for file descriptors indicate resource usage

Advanced strace Techniques

Filtering by outcome:

# Show failed calls only
strace -e trace=open -z python app.py

# Show successful calls only
strace -e trace=open -Z python app.py

Decoding arguments:

# Resolve addresses
strace -v python app.py

# Decode errors
strace -r python app.py

# Show string contents
strace -s 256 python app.py  # 256 char max

Conditional tracing:

# Trace when condition met
strace -e trace=write -e when=write==1 python app.py

# First N calls
strace -c -n 100 python app.py

perf: Performance Analysis Tools

Introduction to perf

The perf tool provides access to hardware performance counters, kernel tracepoints, and dynamic probes - essential for CPU-bound performance analysis:

# Install perf
sudo apt install linux-tools-common linux-tools-generic

# Basic version check
perf --version

###perf record and report

Profile application execution:

# Record profile
perf record -g ./myapp
perf record -g -p 1234

# View report
perf report

# Record with specific event
perf record -e cycles ./myapp
perf record -e cache-misses ./myapp

Essential perf Commands

Hardware events:

# CPU cycles
perf stat -e cycles ./myapp

# Cache misses
perf stat -e cache-misses ./myapp

# Branch mispredictions
perf stat -e branch-misses ./myapp

# Multiple events
perf stat -e cycles,instructions,cache-references,cache-misses ./myapp

# Sample output:
#  Performance counter stats for './myapp':
#         1,234,567    cycles                           #    0.000 GHz
#           567,890    instructions                     #    0.46  insn per cycle
#            12,345    cache-references                 #    0.015 M
#             1,234    cache-misses                     #   10.00% of all cache refs
#        0.001234 seconds time elapsed

Software events:

# Page faults
perf stat -e page-faults ./myapp

# Context switches
perf stat -e context-switches ./myapp

# CPU migrations
perf stat -e cpu-migrations ./myapp

Kernel tracepoints:

# List available tracepoints
perf list | head -50

# Block I/O events
perf stat -e block:* ./myapp

# Scheduler events
perf stat -e sched:sched_switch ./myapp

# System call events
perf stat -e 'syscalls:sys_enter_*' ./myapp

perf annotate

View source-level analysis:

# Record with debug info
perf record -g --call-graph dwarf ./myapp

# Annotate
perf annotate

# Or specify symbol
perf annotate --symbol=function_name

perf top

Real-time performance monitoring:

# System-wide view
sudo perf top

# Per-process
perf top -p 1234

# With call graph
sudo perf top -g

perf probe

Dynamic tracing:

# Add probe to function
perf probe --add vfs_read

# List probes
perf probe -l

# Trace probe
perf record -e probe:vfs_read -a ./myapp
perf report

Flame Graphs

Visualize perf data:

# Install flamegraph
git clone https://github.com/brendangregg/FlameGraph.git

# Generate flame graph
perf record -F 99 -g -- ./myapp
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > flamegraph.svg

Comprehensive Performance Analysis

CPU Profiling

# Simple CPU measurement
time ./myapp

# Detailed CPU analysis
perf stat -e cycles -e instructions -e task-clock ./myapp

# CPU Flame graph
perf record -F 99 -p $(pgrep -f myapp)

Memory Analysis

# Memory allocation tracking
valgrind --tool=massif ./myapp
valgrind --tool=memcheck ./myapp

# With perf
perf record -e kmem:* ./myapp
perf report

I/O Analysis

# I/O statistics
iostat -x 1

# Block I/O details
perf record -e block:* -a
perf report

# strace I/O
strace -e trace=read,write -c ./myapp

Network Analysis

# Network stats
sar -n DEV 1

# TCP analysis
perf record -e 'tcp:*' -a
perf report

Advanced Techniques

Debugging Hangs

# Find where process is blocked
strace -p 1234

# With time
strace -r -p 1234

# Sample stack traces
perf record -p 1234 -g -- sleep 10
perf report

Debugging Crashes

# Core dump analysis
ulimit -c unlimited
./crashing_app
gdb ./crashing_app core

# With strace
strace -f -o crash.log ./crashing_app

# Post-mortem with perf
perf record -g -o perf.data ./crashing_app
perf report

Latency Analysis

# Syscall latency
strace -T ls 2>&1 | head -20
# Shows time spent in each call

# Function latency with perf
perf record -e probeๅ‡ฝๆ•ฐ -a ./myapp
perf report

Tool Comparison

Tool Best For Limitations
strace System call debugging, file/network tracing High overhead, verbose output
perf CPU profiling, hardware events Requires debug symbols
ltrace Library call tracing Only shared libraries
gdb Interactive debugging Not for production
valgrind Memory debugging Very slow

Practical Debugging Workflows

Application Not Responding

# Check if process is running
ps aux | grep app

# Find blocking syscall
strace -p $(pgrep app)

# CPU usage
top -p $(pgrep app)

# Stack traces
pstack $(pgrep app)

Slow Application

# CPU bottleneck?
perf stat ./app

# System calls?
strace -c ./app

# I/O?
iostat -x 1
strace -e trace=read,write -c ./app

# Flame graph
perf record -F 99 -g -- ./app

Memory Leak

# With valgrind
valgrind --leak-check=full ./app

# With perf
perf record -e kmem:kmalloc -g ./app
perf report

Best Practices

When to Use Each Tool

  • strace: File issues, network problems, understanding behavior
  • perf: CPU hotspots, cache misses, branch prediction
  • gdb: Interactive debugging, crash analysis
  • valgrind: Memory bugs, undefined behavior

Minimizing Overhead

# strace overhead reduction
strace -c -O 1000 app  # Sample every 1000th call
strace -e trace=openat app  # Filter to relevant calls

# perf overhead reduction  
perf record -F 99 app  # 99 Hz sampling
perf record -c 1000 app  # Count every 1000th event

Production Considerations

# Attach to production process
sudo strace -p $(pgrep -f production) -f

# System-wide perf
sudo perf record -a -g -- sleep 30

# Always have debug symbols
sudo apt install debug symbols for your packages

Conclusion

System analysis tools like strace and perf are essential for understanding application behavior and diagnosing performance issues. strace provides visibility into system call interactions, while perf offers hardware-level performance insights. Together with supporting tools, they form a comprehensive debugging and optimization toolkit.

Master these tools through practice - start with simple applications and progressively tackle more complex debugging scenarios. The ability to quickly diagnose production issues will prove invaluable throughout your career.

Resources

Comments