Skip to content

Operations

Install, verify kernel readiness, and drive bpftrace day-to-day. Commands are taken from upstream README/docs (verified via Context7, August 2026) — nothing fabricated.

Installation

Debian / Ubuntu and derivatives:

sudo apt install bpftrace

Fedora / CentOS family:

sudo dnf install bpftrace

Building from source (documented developer flow):

mkdir build
cmake -B build -DCMAKE_BUILD_TYPE=Release
make -C build -j$(nproc)

Nix environments must pull git submodules (libbpf among them) because flakes reconstruct source from Git metadata only:

nix build .?submodules=1

Run everything privileged — eBPF loading requires root or equivalent capability grants:

$ sudo bpftrace --info   # environment/kernel feature report shipped with the tool

Discover What You Can Trace

Enumeration is always step one on an unknown host:

sudo bpftrace -l 'tracepoint:syscalls:*'
sudo bpftrace -l 'kprobe:tcp_*'          # wildcard class matching, per upstream docs
sudo bpftrace -l my_script.bt            # list probes a script would activate

Filter further by piping through grep for narrower families.

One-Liner Cookbook

Trace open-family syscalls (canonical example from the upstream language guide):

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%-6d %-16s %s\n", pid, comm, str(args.filename)); }'

Log2 latency histogram of read return values (stdlib reference example):

sudo bpftrace -e 'kretprobe:vfs_read { @bytes = hist(retval); }'

Count/sampling loop with periodic async drain (exact pattern from stdlib docs):

sudo bpftrace -e '
interval:ms:100 { @ = count(); }
interval:s:10   { print(@); clear(@); }'

Time-series windows with parameterized aggregation:

@ = tseries(@v, 1s, 5, "avg")
@ = tseries(@v, 1s, 5, "max")

Linear histograms over bounded ranges:

interval:ms:1 { @ = lhist(rand % 10, 0, 10, 1); }

Scripts belong in .bt files with a shebang for reuse; probe clauses group comma-separated targets sharing one body:

tracepoint:syscalls:sys_enter_open,
tracepoint:syscalls:sys_enter_openat {
    printf("%-6d %-16s %s\n", pid, comm, str(args.filename));
}

Verify Kernel Readiness

Upstream ships check_kernel_features; the required option set (from dependency_support.md) includes:

zgrep -E "CONFIG_BPF_SYSCALL=|CONFIG_BPF_JIT=|CONFIG_KPROBE_EVENTS=|CONFIG_UPROBE_EVENTS=" /proc/config.gz

Baseline documented requirements: CONFIG_BPF=y, CONFIG_BPF_SYSCALL=y, CONFIG_BPF_JIT=y, CONFIG_HAVE_EBPF_JIT=y, CONFIG_BPF_EVENTS=y, CONFIG_FTRACE_SYSCALLS=y, CONFIG_FUNCTION_TRACER=y, CONFIG_KPROBES=y, CONFIG_KPROBE_EVENTS=y, CONFIG_UPROBES=y, CONFIG_UPROBE_EVENTS=y, CONFIG_DEBUG_FS=y. Missing pieces explain most "unknown probe type" failures on hardened or vendor-trimmed kernels.

Troubleshooting

Permission denied under sudo-less shells

Every load needs root or capabilities. In containers this means privileged mode or explicitly exported BPF/perf capability sets — plain root inside a restricted namespace can still fail attach.

  • "tracepoint not found" — event absent from /sys/kernel/tracing/events/ on this kernel; re-run -l discovery rather than trusting script portability across hosts.
  • Verifier rejects with file/line output — reduce the action body; verifier errors name the failing construct, and unbounded loops or oversized stacks are typical culprits.
  • Empty output but clean start — confirm events actually occur (generate traffic), remember interval clauses only fire while the session lives.
  • Slow sync map checks — documented expense of inline CPU iteration; move threshold logic into consumer intervals using async print()/clear().
  • macOS/Windows desktops — unsupported platforms; point investigations at a Linux VM target instead.

Field Notes

  • Pair sessions: leave the openat one-liner running while reproducing an app bug; paste output directly into incident channels.
  • For fleet-persistent use prefer scripts checked into the ops repo with their .bt treated as code (reviewed diffs).
  • On frequency-sensitive hosts watch profiler-class providers; interval producers at ms granularity exist precisely so you sample, not saturate.