eBPF Course · Reference

bpftrace Cheat Sheet

The probe syntax, builtins, functions, and greatest-hits one-liners — quick reference, built to print.

🎯 Ask the running kernel a precise question, get an answer in seconds
⚠️ Before you copy anything bpftrace is Linux-only (no macOS, no Windows). Almost every command needs sudo (tracing the kernel is privileged). Run these later on a Linux box or VM. Probe names, builtins, and functions below are verified against the bpftrace Reference Guide and the One-Liner Tutorial.

Jump: Glossary · Lesson 3: Anatomy of a one-liner

01 Invocation

The whole tool runs from the command line. You either inline a tiny program with -e, or point it at a .bt script file.

CommandWhat it does
sudo bpftrace -e 'program'Run a one-liner program given inline as text.
sudo bpftrace file.btRun a program saved in a script file (.bt by convention).
sudo bpftrace -l 'pattern'List probes matching a wildcard pattern (does not run anything). Omit the pattern to list all probes.
sudo bpftrace -l -e 'program'List which probes the given program would attach to.
-p PIDAttach to / filter on one process. bpftrace exits when that process exits.
-c 'command'Launch command as a child and trace it; bpftrace exits when it does.
-V / --versionPrint the bpftrace version.
# list every syscall-entry tracepoint
sudo bpftrace -l 'tracepoint:syscalls:sys_enter_*'

# run a one-liner; ^C to stop and print results
sudo bpftrace -e 'BEGIN { printf("hello world\n"); }'
Linux-only — copy and try later on a Linux box (needs sudo).

Source: bpftrace CLI man page.

02 Program structure

A bpftrace program is one or more action blocks. Each block says where to hook (the probe), an optional condition (the filter), and what to do (the action). Read a one-liner left-to-right and it always fits this shape:

probe[,probe] /filter/ { action }
PROBE where to hook /FILTER/ run only if true { ACTION } what to do optional required
Every bpftrace block: a probe, an optional /filter/, and an { action }.
PieceMeaning
probe[,probe]One or more probes (comma-separated) sharing the same action.
/filter/Optional predicate; the action runs only when it is true, e.g. /pid == 181/.
{ action }The code: printf, map updates, aggregations, etc.
BEGIN { … }Special probe — fires once before any other probe attaches (set up headers / variables).
END { … }Special probe — fires once after detaching (print final results). bpftrace prints leftover maps here automatically.
// …   /* … */Single-line and multi-line comments.
💡 BEGIN/END vs begin/end Recent bpftrace also accepts lowercase begin/end. The uppercase BEGIN/END form is the classic one you'll see everywhere and still works — this sheet uses it.

Source: bpftrace Language Reference.

03 Probe types

The probe is the hook point. The leading word picks the kind of event; the rest names the specific target.

ProbeHooks…Example
tracepointA stable, named kernel event (best first choice — args have field names).tracepoint:syscalls:sys_enter_openat
kprobeEntry of any kernel function (dynamic; less stable across versions).kprobe:vfs_read
kretprobeReturn of a kernel function — gives you retval.kretprobe:vfs_read
uprobeEntry of a function in a user-space binary / library.uprobe:/bin/bash:readline
uretprobeReturn of a user-space function — gives you retval.uretprobe:/bin/bash:readline
usdtA user-level statically-defined tracepoint baked into an app.usdt:/path/bin:provider:probe
profileTimed sampling on every CPU — for CPU profiling / flame graphs.profile:hz:99
intervalFires on a timer on one CPU — for periodic summaries.interval:s:1
softwareA kernel software event (e.g. page faults) at a given count.software:faults:100
hardwareA CPU performance-counter event (e.g. cache misses) at a given count.hardware:cache-misses:1000000
💡 Field-name shapes to know tracepoint:<subsys>:<event> · kprobe:<fn> · uprobe:<binary>:<fn> · profile:hz:<rate> · interval:s:<count>. Wildcards (*) work in probe names and in -l.

Source: bpftrace Language Reference — Probes.

04 Builtins

Builtins are read-only values available inside an action — context about who and what triggered the probe.

BuiltinMeaning
commProcess (command) name, e.g. "bash".
pidProcess ID.
tidThread ID.
uidUser ID.
gidGroup ID.
nsecsTimestamp in nanoseconds — subtract two to time something.
elapsedNanoseconds since bpftrace started.
cpuThe CPU number the probe fired on.
argsStruct of the probe's arguments by name (tracepoints, fentry/fexit). Access fields with a dot: args.filename.
arg0 … argNPositional arguments by index (kprobe, uprobe, usdt) — raw, untyped.
retvalReturn value (only in kretprobe / uretprobe).
curtaskPointer to the current kernel task struct.
kstackKernel stack trace (use as a map key or print it).
ustackUser-space stack trace.
probeFull name of the probe that fired — great map key for multi-probe blocks.
funcName of the function being traced.
usernameUsername of the current user.
⚠️ args vs argN Tracepoints give you named args.field (self-documenting — list them with bpftrace -lv 'tracepoint:…'). kprobes/uprobes give you raw arg0, arg1… that you must cast yourself. args.x is the modern dot form; the old args->x arrow still works as an alias.

Source: bpftrace Language Reference — Builtins.

05 Functions

Two families: plain functions you call for output/strings, and aggregating functions that you assign into a map (@) to summarize across many events.

Output, strings & control

FunctionMeaning
printf(fmt, …)C-style formatted print to the terminal.
str(ptr [, len])Read a NUL-terminated string from a pointer (e.g. a filename arg).
time(fmt)Print the current wall-clock time using a strftime-style format.
print(@map [, top, div])Print a value or map now; optional top-N and divisor for scaling.
delete(@map, key)Remove one key from a map (e.g. drop a finished thread's start time).
clear(@map)Empty an entire map — pair with interval for rolling stats.
exit([code])Stop bpftrace (prints maps, then quits). Often in an interval block.
kstack / ustackCapture a kernel / user stack trace — usable as a value or a map key.
ntop([af,] addr)Format an IP address (IPv4/IPv6) into a printable string.

Aggregating (assign into a @ map)

FunctionMeaning
count()Count how often this fired — the workhorse.
sum(n)Running total of n.
avg(n)Running average of n.
min(n)Smallest n seen.
max(n)Largest n seen.
stats(n)count + avg + sum of n in one shot.
hist(n)Power-of-2 (log2) histogram of n — shows distribution shape.
lhist(n, min, max, step)Linear histogram with fixed-width buckets.
💡 Aggregations are free at print time You never loop. Assign @x = count() or @x = hist(n) and bpftrace keeps the running summary in the kernel; on exit it auto-prints every map — histograms render as ASCII bars.

Source: bpftrace Standard Library Reference.

06 Maps & aggregation

A map is bpftrace's one data structure: a global associative array whose name starts with @. It lives in the kernel, survives across probe firings, and prints automatically at exit.

FormMeaning
@name = …A single global value (scalar map).
@name[key] = …Keyed map — one slot per key (e.g. per comm, per pid).
@name[k1, k2] = …Multi-key map (tuple key), e.g. @[comm, pid].
@[key]Shorthand: an anonymous map named @ keyed by key.
# count syscalls per process name
tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }

# histogram of read() sizes, keyed by process
tracepoint:syscalls:sys_exit_read { @bytes[comm] = hist(args.ret); }
Linux-only — copy and try later on a Linux box (needs sudo).

Source: bpftrace One-Liner Tutorial.

07 Greatest-hits one-liners

Verified, copy-ready. Each runs until you press ^C (or hits an exit()), then prints its maps. Prefix every one with sudo.

Files opened (opensnoop-style)

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args.filename)); }'
Linux-only — who is opening which file, live. Needs sudo.

New processes / exec

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_execve { printf("%-16s %-6d %s\n", comm, pid, str(args.filename)); }'
Linux-only — every program that gets exec'd, with its parent's name. Needs sudo.

Syscall counts by process

sudo bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
Linux-only — which processes are the busiest syscall callers. Needs sudo.

Read-size distribution (histogram)

sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read { @bytes = hist(args.ret); }'
Linux-only — distribution of bytes returned by read(). Needs sudo.

Syscall / function latency (histogram)

sudo bpftrace -e 'kprobe:vfs_read { @start[tid] = nsecs; }
  kretprobe:vfs_read /@start[tid]/ { @ns[comm] = hist(nsecs - @start[tid]); delete(@start, tid); }'
Linux-only — time spent in vfs_read() as a per-process histogram. Needs sudo.

CPU profiling at 99 Hz (kernel stacks)

sudo bpftrace -e 'profile:hz:99 { @[kstack] = count(); }'
Linux-only — sampled on-CPU kernel stacks; feed the output to a flame graph. Needs sudo.

Signals sent (killsnoop-style)

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_kill { printf("%s -> PID %d SIG %d\n", comm, args.pid, args.sig); }'
Linux-only — who is signalling whom (catch a mystery SIGKILL). Needs sudo.
🎯 Bonus: list before you trace Forgot a tracepoint's exact name or its field names? Discover them, then trace:
sudo bpftrace -l 'tracepoint:syscalls:sys_enter_open*'   # find the probe
sudo bpftrace -lv 'tracepoint:syscalls:sys_enter_openat'  # show its args fields

Sources: One-Liner Tutorial, killsnoop.bt, execsnoop.bt.