A system call tracer for macOS using the LLDB debugger API.
Status: Beta - Core functionality works, but some features are still in development.
dtruss, doesn't require disabling System Integrity Protection-e trace=file, -e trace=network)-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 categories.
strace -p 1234
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
# ...
strace-macos supports filtering syscalls by name or category using the -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 trace groups of related syscalls:
| Category | Description | Example Syscalls |
|---|---|---|
file | File operations | open, close, read, write, stat, unlink |
network | Network operations | socket, connect, send, recv, bind |
process | Process lifecycle | fork, exec, wait, exit, kill |
memory | Memory management | mmap, munmap, brk, mprotect |
signal | Signal handling | signal, sigaction, sigprocmask, kill |
ipc | Inter-process communication | pipe, shm_open, msgget, semop |
thread | Thread operations | pthread_create, bsdthread_register |
time | Time and timers | gettimeofday, setitimer, utimes |
sysinfo | System information | sysctl, getpid, getuid, uname |
security | Security/MAC operations | __mac_*, csops, csrctl |
debug | Debugging and tracing | ptrace, kdebug_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
| Feature | Linux strace | strace-macos |
|---|---|---|
| Filter by syscall name | ✅ -e trace=open,close | ✅ -e trace=open,close |
| Filter by category | ✅ -e trace=file | ✅ -e trace=file |
Negation (!) | ✅ -e trace=!open | ❌ Not yet |
| Regex filtering | ✅ -e trace=/^open/ | ❌ Not yet |
| Path filtering | ✅ -P /etc/passwd | ❌ Not yet |
| FD filtering | ✅ -e trace-fd=3 | ❌ Not yet |
%desc category | ✅ FD-related syscalls | ❌ Not yet |
| Percent prefix | ✅ %file or file | ⚠️ Only file |
/usr/bin/python3)Important: Must use macOS system Python - LLDB bindings don't work with Homebrew/pyenv/Nix Python.
Contributions are welcome! See CONTRIBUTING.md for:
Current Status: 3/13 tests passing (spawn functionality working)
strace-macos (Python CLI)
↓
LLDB Python API
↓
debugserver (macOS debugging APIs)
↓
Target Process
The tracer uses LLDB's Python bindings to:
Working:
-c) ✅Planned:
-f)-e trace=!open)-e trace=/^open/)-P /path)-e trace-fd=3)-s)-t, -tt, -ttt)macOS ships with dtruss, a DTrace-based syscall tracer. However:
strace-macos works with SIP enabled and provides richer output.
strace-macos aims for compatibility with Linux strace where possible:
| Feature | Linux strace | strace-macos |
|---|---|---|
| Basic tracing | ✅ | ✅ |
| Attach to PID | ✅ | ✅ |
| Syscall filtering* | ✅ | ✅ |
| Summary stats | ✅ | ✅ |
| Follow forks | ✅ | ⏳ |
| Symbolic decoding | ✅ | ✅ |
| JSON output | ❌ | ✅ |
| Color output | ❌ | ✅ |
* See Syscall Filtering for detailed feature comparison.
MIT License - see LICENSE file for details.
Jörg Thalheim joerg@thalheim.io
For commercial support, please contact Mic92 at joerg@thalheim.io or reach out to Numtide.
Python
99.5%
A system call tracer for macOS using the LLDB debugger API.
Status: Beta - Core functionality works, but some features are still in development.
dtruss, doesn't require disabling System Integrity Protection-e trace=file, -e trace=network)-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 categories.
strace -p 1234
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
# ...
strace-macos supports filtering syscalls by name or category using the -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 trace groups of related syscalls:
| Category | Description | Example Syscalls |
|---|---|---|
file | File operations | open, close, read, write, stat, unlink |
network | Network operations | socket, connect, send, recv, bind |
process | Process lifecycle | fork, exec, wait, exit, kill |
memory | Memory management | mmap, munmap, brk, mprotect |
signal | Signal handling | signal, sigaction, sigprocmask, kill |
ipc | Inter-process communication | pipe, shm_open, msgget, semop |
thread | Thread operations | pthread_create, bsdthread_register |
time | Time and timers | gettimeofday, setitimer, utimes |
sysinfo | System information | sysctl, getpid, getuid, uname |
security | Security/MAC operations | __mac_*, csops, csrctl |
debug | Debugging and tracing | ptrace, kdebug_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
| Feature | Linux strace | strace-macos |
|---|---|---|
| Filter by syscall name | ✅ -e trace=open,close | ✅ -e trace=open,close |
| Filter by category | ✅ -e trace=file | ✅ -e trace=file |
Negation (!) | ✅ -e trace=!open | ❌ Not yet |
| Regex filtering | ✅ -e trace=/^open/ | ❌ Not yet |
| Path filtering | ✅ -P /etc/passwd | ❌ Not yet |
| FD filtering | ✅ -e trace-fd=3 | ❌ Not yet |
%desc category | ✅ FD-related syscalls | ❌ Not yet |
| Percent prefix | ✅ %file or file | ⚠️ Only file |
/usr/bin/python3)Important: Must use macOS system Python - LLDB bindings don't work with Homebrew/pyenv/Nix Python.
Contributions are welcome! See CONTRIBUTING.md for:
Current Status: 3/13 tests passing (spawn functionality working)
strace-macos (Python CLI)
↓
LLDB Python API
↓
debugserver (macOS debugging APIs)
↓
Target Process
The tracer uses LLDB's Python bindings to:
Working:
-c) ✅Planned:
-f)-e trace=!open)-e trace=/^open/)-P /path)-e trace-fd=3)-s)-t, -tt, -ttt)macOS ships with dtruss, a DTrace-based syscall tracer. However:
strace-macos works with SIP enabled and provides richer output.
strace-macos aims for compatibility with Linux strace where possible:
| Feature | Linux strace | strace-macos |
|---|---|---|
| Basic tracing | ✅ | ✅ |
| Attach to PID | ✅ | ✅ |
| Syscall filtering* | ✅ | ✅ |
| Summary stats | ✅ | ✅ |
| Follow forks | ✅ | ⏳ |
| Symbolic decoding | ✅ | ✅ |
| JSON output | ❌ | ✅ |
| Color output | ❌ | ✅ |
* See Syscall Filtering for detailed feature comparison.
MIT License - see LICENSE file for details.
Jörg Thalheim joerg@thalheim.io
For commercial support, please contact Mic92 at joerg@thalheim.io or reach out to Numtide.
Python
99.5%