A system call tracer for macOS using the LLDB debugger API.
Situation:Beta – Core functionality works, but some features are still in development.
- Works with SIP enabled – Adverse
dtrussNo need to disable System Integrity Protection - pure python implementation – No kernel extensions or compiled components
- multiple output formats – JSON lines and strace-compliant text output
- syscall filtering – Filter by syscall name or category (
-e trace=file,-e trace=network, - symbolic decoding – Automatically decodes flags, error codes and structure fields
- color output – Syntax highlighting when output is TTY
- summary statistics – Time/call/error is calculated
-c
# Run directly
nix run github:Mic92/strace-macos -- ls
# Install to profile
nix profile install github:Mic92/strace-macos
strace-macOS requires macOS system Python (has lldb bindings):
# Install directly from GitHub
/usr/bin/python3 -m pip install --user git+https://github.com/Mic92/strace-macos
# Then run (if ~/Library/Python/3.x/bin is in PATH)
strace /usr/local/bin/git status # or any homebrew-installed binary
# Or run directly from repository without installing
git clone https://github.com/Mic92/strace-macos
cd strace-macos
/usr/bin/python3 -m strace_macos /usr/local/bin/git status
# Basic usage (use non-system binaries like homebrew or nix-installed)
strace /usr/local/bin/git status
# Output to file
strace -o trace.txt /usr/local/bin/git status
# JSON output
strace --json /usr/local/bin/git status > trace.jsonl
# Filter syscalls by name
strace -e trace=open,close /usr/local/bin/git status
# Filter by category*
strace -e trace=file /usr/local/bin/git status # All file operations
strace -e trace=network /usr/local/bin/curl https://example.com # Network syscalls only
strace -e trace=process /usr/local/bin/git status # Process lifecycle syscalls
* See syscall filtering for all supported ranges.
add to running process
strace -c /usr/local/bin/git status
# % time seconds usecs/call calls errors syscall
# ------ ----------- ----------- --------- --------- ----------------
# 45.23 0.001234 12 103 read
# 32.10 0.000876 8 110 write
# ...
Supports filtering syscalls by name or range using strace-macOS -e trace= Option.
Specify one or more syscall names separated by commas:
strace -e trace=open,close,read,write /usr/local/bin/git status
Use predefined categories to locate groups of related syscalls:
| Social class | Description | Example Syscalls |
|---|---|---|
file |
file operations | open, close, read, write, state, unlink |
network |
network operations | socket, connect, send, receive, bind |
process |
process life cycle | fork, execute, stop, exit, kill |
memory |
memory management | mmap, munmap, brk, mprotect |
signal |
signal handling | signal, sigaction, sigprocmask, kill |
ipc |
inter-process communication | pipe, shm_open, message, cmop |
thread |
thread operations | pthread_create, bsdthread_register |
time |
time and timer | gettimeofday, settimer, utimes |
sysinfo |
system information | sysctl, getpid, getuid, uname |
security |
Security/Mac Operations | __mac_*, csops, csrctl |
debug |
debugging and tracing | ptrace, kdbug_trace, panic_with_data |
misc |
miscellaneous syscalls | ioctl, fcntl, kqueue, connectx |
Example:
# Trace only file operations
strace -e trace=file /usr/local/bin/git status
# Trace only network syscalls
strace -e trace=network /usr/local/bin/curl https://example.com
# Trace process management syscalls
strace -e trace=process /usr/local/bin/git status
Comparison with Linux strace
| Speciality | linux stress | stress-macos |
|---|---|---|
| filter by syscall name | -e trace=open,close |
-e trace=open,close |
| Filter by Category | -e trace=file |
-e trace=file |
prohibition (!, |
-e trace=!open |
❌ Not now |
| regex filtering | -e trace=/^open/ |
❌ Not now |
| path filtering | -P /etc/passwd |
❌ Not now |
| FD filtering | -e trace-fd=3 |
❌ Not now |
%desc Social class |
✅ FD related syscalls | ❌ Not now |
| percent prefix | %file Or file |
file |
- macOS 12+ (Monterey or later)
- Apple Silicon (ARM64) – primary platform
- Intel (x86_64) – work in progress
- Xcode Command Line Tools (for LLDB)
- system python (
/usr/bin/python3,
Important: macOS systems must use Python – LLDB bindings do not work with Homebrew/pyenv/Nix Python.
Contributions welcome! See CONTRIBUTING.md for:
- development environment setup
- code style guidelines
- test instructions
- how to add new syscalls
- pull request process
current situation:Passed 3/13 tests (spawn functionality working)
strace-macos (Python CLI)
↓
LLDB Python API
↓
debugserver (macOS debugging APIs)
↓
Target Process
Tracer uses the Python bindings of LLDB:
- Set breakpoints on syscall entry/exit points
- Read CPU register to extract syscall arguments
- Decode arguments symbolically (flags, error, structures)
- Format the output in strace-compliant or JSON format
working,
- Generate and explore new processes ✅
- Connect with ongoing processes ✅
- Basic syscall capture (entry/exit) ✅
- Argument decoding (integers, strings, pointers, buffers, iovex) ✅
- Symbolic flag decoding (O_RDONLY, etc.) ✅
- Error code decoding (ENOENT, etc.) ✅
- Structure decoding (stat, sockaddr, msghdr, etc.) ✅
- Syscall filtering by name and category ✅
- summary statistics (
-c) - JSON and text output formats ✅
- ✅ Color output with syntax highlighting
planned to,
- multi-threaded process support
- Follow the forks (
-f, - Prohibit Filtering (
-e trace=!open, - regex filtering(
-e trace=/^open/, - Path-based filtering (
-P /path, - FD-based filtering (
-e trace-fd=3, - string truncation control (
-s, - relative/absolute timestamp (
-t,-tt,-ttt,
Comes with macOS dtrussA DTrace-based syscall tracer. However:
- Need to disable System Integrity Protection (SIP)
- Doesn’t work on modern macOS versions without workaround
- Limited filtering capabilities
- No symbolic decoding of arguments
stress-macOS works with SIP enabled and provides better output.
Comparison with Linux strace
Where possible, strace-macOS aims to establish compatibility with Linux strace:
| Speciality | linux stress | stress-macos |
|---|---|---|
| basic tracing | ||
| connect to pid | ||
| syscall filtering* | ||
| summary statistics | ||
| follow the fork | ||
| symbolic decoding | ||
| JSON output | ||
| color output |
*See syscall filtering for detailed feature comparison.
MIT License – see license file for details.
Joerg Thalheim joerg@thalheim.io
Need professional support or customization?
For commercial support, please contact Mic92 at joerg@thalheim.io or contact Numtide.