- stable rust toolchains:
rustup toolchain install stable - nightly rust toolchains:
rustup toolchain install nightly-2025-06-13 --component rust-src - (if cross-compiling) rustup target:
rustup target add ${ARCH}-unknown-linux-musl - (if cross-compiling) LLVM: (e.g.)
brew install llvm(on macOS) - (if cross-compiling) C toolchain: (e.g.)
brew install filosottile/musl-cross/musl-cross(on macOS) - bpf-linker:
cargo install bpf-linker(--no-default-featureson macOS)
IMPORTANT: note that we depend on a specific version of nightly to avoid breakage caused by LLVM or rust changes. You can use the latest nightly, but you need to change pinchy/build.rs.
Use cargo build, cargo check, etc. as normal. Run your program with:
cargo run --release --config 'target."cfg(all())".runner="sudo -E"'Cargo build scripts are used to automatically build the eBPF correctly and include it in the program.
You can run the UML efficiency benchmark with any traced command:
BENCH_COMMAND='find "$HOME/.local"' EVENTS='' ./scripts/measure-command-efficiency.shUseful parameters:
BENCH_COMMAND: command to run under tracing inside UMLEVENTS: comma-separated syscall filter (empty string means all supported events)RUNS: latency samples (default15)THROUGHPUT_RUNS: throughput loop count (default3)
Example:
RUNS=1 THROUGHPUT_RUNS=1 EVENTS='' BENCH_COMMAND='cat /etc/passwd' \
./scripts/measure-command-efficiency.shPinchy can trace syscalls for a running process or launch a new process and trace it. You can specify which syscalls to trace using the -e or --event option.
Trace all syscalls for a command:
pinchy ls /tmpTrace specific syscalls:
pinchy -e read,write,open ls /tmpAttach to a running process:
pinchy -p <PID> -e open,closePinchy supports common syscall aliases that users might be familiar with from libc or other tools.
On x86_64 and aarch64, signal-related syscalls use rt_* prefixes in the kernel, but you can use the more familiar names without the prefix:
# These are equivalent:
pinchy -e sigaction,sigprocmask ./myprogram
pinchy -e rt_sigaction,rt_sigprocmask ./myprogramSupported signal aliases (all architectures):
sigaction→rt_sigactionsigprocmask→rt_sigprocmasksigreturn→rt_sigreturnsigpending→rt_sigpendingsigtimedwait→rt_sigtimedwaitsigqueueinfo→rt_sigqueueinfosigsuspend→rt_sigsuspend
On aarch64, many traditional syscalls don't exist in the kernel but are provided by glibc as wrappers around newer *at variants. Pinchy supports these for convenience:
# On aarch64, these are equivalent:
pinchy -e open,stat ./myprogram
pinchy -e openat,newfstatat ./myprogramSupported aarch64 aliases:
open→openatstat→newfstatatlstat→newfstatatpoll→ppolldup2→dup3pipe→pipe2access→faccessatchmod→fchmodatchown→fchownatlink→linkatmkdir→mkdiratmknod→mknodatrename→renameatrmdir→unlinkatsymlink→symlinkatunlink→unlinkat
On x86_64, these traditional syscalls exist directly in the kernel, so no aliases are needed.
Cross compilation should work on both Intel and Apple Silicon Macs.
CC=${ARCH}-linux-musl-gcc cargo build --package pinchy --release \
--target=${ARCH}-unknown-linux-musl \
--config=target.${ARCH}-unknown-linux-musl.linker=\"${ARCH}-linux-musl-gcc\"The cross-compiled program target/${ARCH}-unknown-linux-musl/release/pinchy can be
copied to a Linux server or VM and run there.
With the exception of eBPF code, pinchy is distributed under the terms of either the MIT license or the Apache License (version 2.0), at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.
All eBPF code is distributed under either the terms of the GNU General Public License, Version 2 or the MIT license, at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this project by you, as defined in the GPL-2 license, shall be dual licensed as above, without any additional terms or conditions.
