# strace — Trace System Calls and Signals of a Process

> Practical guide to strace: trace system calls, diagnose failing programs and track down performance bottlenecks at the OS level.

Source: https://www.jpkc.com/db/en/cheatsheets/shell-system/strace/

<!-- PROSE:intro -->
strace shows you what a program actually does: it logs every system call to the Linux kernel, complete with arguments and return value – from opening a file to network connections to received signals. That lets you find out why a process hangs, which config file it searches for in vain, or where time is being lost, all without reading the source code. This guide takes you from plain capturing through targeted filters to syscall statistics for profiling.
<!-- PROSE:intro:end -->

## Basic Tracing

`strace <command>` — Trace all system calls of a command.

```bash
strace ls -la
```

`strace -p <pid>` — Attach to and trace a running process (needs ptrace permission, often `sudo`).

```bash
strace -p 1234
```

`strace -f <command>` — Follow child processes (forks).

```bash
strace -f nginx
```

`strace -o <file> <command>` — Write trace output to a file.

```bash
strace -o trace.log ./myapp
```

`strace -ff -o <prefix> <command>` — Write each process trace to a separate file.

```bash
strace -ff -o traces/app ./myapp
```

## Filter by System Call

`strace -e trace=<syscall> <command>` — Trace only specific system calls.

```bash
strace -e trace=open,read,write ls
```

`strace -e trace=file <command>` — Trace file-related system calls.

```bash
strace -e trace=file cat /etc/hosts
```

`strace -e trace=network <command>` — Trace network-related system calls.

```bash
strace -e trace=network curl -s https://example.com
```

`strace -e trace=process <command>` — Trace process management calls (fork, exec, wait).

```bash
strace -e trace=process bash -c 'ls | grep txt'
```

`strace -e trace=memory <command>` — Trace memory management calls (mmap, brk, etc.).

```bash
strace -e trace=memory ./myapp
```

`strace -e trace=signal <command>` — Trace signal-related system calls.

```bash
strace -e trace=signal ./myapp
```

## Timing & Performance

`strace -T <command>` — Show time spent in each system call.

```bash
strace -T ./myapp
```

`strace -t <command>` — Prefix each line with time of day.

```bash
strace -t ./myapp
```

`strace -tt <command>` — Prefix with time of day including microseconds.

```bash
strace -tt ./myapp
```

`strace -r <command>` — Show relative timestamp (time since previous call).

```bash
strace -r ./myapp
```

`strace -c <command>` — Count and summarize system calls (statistics).

```bash
strace -c ls -la /usr
```

`strace -C <command>` — Show both regular trace and summary statistics.

```bash
strace -C ./myapp
```

`strace -c -S time <command>` — Sort summary by time spent (default: calls).

```bash
strace -c -S time ./myapp
```

## Output Options

`strace -s <size> <command>` — Set max string length in output (default 32).

```bash
strace -s 1024 -e trace=read ./myapp
```

`strace -v <command>` — Verbose mode: don't abbreviate structures.

```bash
strace -v stat /etc/hosts
```

`strace -y <command>` — Show file paths for file descriptor arguments.

```bash
strace -y -e trace=read,write ./myapp
```

`strace -yy <command>` — Show socket addresses and device details for FDs.

```bash
strace -yy -e trace=network curl -s https://example.com
```

## Common Patterns

`strace -e trace=openat <command> 2>&1 | grep <file>` — Find which files a program tries to open.

```bash
strace -e trace=openat python app.py 2>&1 | grep config
```

`strace -e trace=connect <command>` — See what network connections a program makes.

```bash
strace -e trace=connect curl -s https://example.com
```

`strace -e trace=openat -p <pid> 2>&1 | grep -v ENOENT` — Watch file access of a running process (exclude failures).

```bash
strace -e trace=openat -p $(pidof nginx) 2>&1 | grep -v ENOENT
```

`strace -c -p <pid> -e trace=all` — Profile system call usage of a running process.

```bash
strace -c -p $(pidof php-fpm) -e trace=all
```

`strace -e trace=write -s 1024 -p <pid>` — Watch what a process writes (debug output issues).

```bash
strace -e trace=write -s 1024 -p 1234
```

<!-- PROSE:outro -->
## Conclusion

strace is the first tool you reach for when a program misbehaves in puzzling ways and the logs reveal nothing: `strace -f -e trace=file` uncovers missing files, `-e trace=network` reveals blocked connections, and `-c` gives you a quick syscall profile. Keep two things in mind, though. First, tracing slows the target down considerably – use it carefully on production systems, ideally time-boxed. Second, and more importantly: strace prints syscall arguments in clear text and can expose passwords, tokens or keys in the process. So only attach to your own or explicitly authorised processes; `strace -p` requires the ptrace permission anyway (yama `ptrace_scope`, usually `sudo`). macOS has no strace – there you use `dtruss` or `dtrace` instead.

## Further Reading

- [strace.io](https://strace.io/) – the official project site with documentation and downloads
- [Wikipedia: strace](https://en.wikipedia.org/wiki/Strace) – background and how the system-call tracer works
<!-- PROSE:outro:end -->

## Related Commands

- [lsof](https://www.jpkc.com/db/en/cheatsheets/shell-system/lsof/) – lists the open files and sockets of a process
- [ps](https://www.jpkc.com/db/en/cheatsheets/shell-system/ps/) – lists running processes with the PIDs you feed to `strace -p`
- [dmesg](https://www.jpkc.com/db/en/cheatsheets/shell-system/dmesg/) – reads the kernel ring buffer for low-level error messages

