Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
18d62d6
Add hello_world BCC example
r41k0u Oct 13, 2025
edc3373
Add trace_pipe utility
r41k0u Oct 13, 2025
37d1e1b
Add sys_sync BCC example
r41k0u Oct 13, 2025
263402d
Add trace_fields
r41k0u Oct 13, 2025
903654d
Add hello_fields BCC Example
r41k0u Oct 13, 2025
d7329ad
Add BCC sync_timing example
r41k0u Oct 14, 2025
b676a5e
Fix return in BCC-Examples
r41k0u Oct 14, 2025
4a79f9b
Add sync_count BCC-Example
r41k0u Oct 14, 2025
dd3fc74
Add support for tuple style multiiassignment in allocation_pass
r41k0u Oct 14, 2025
c56928b
Add create_targets_and_rvals, use it in handle_assign to enable tuple…
r41k0u Oct 14, 2025
0a1557e
Add sync_count BCC example to use tuple-like assignment
r41k0u Oct 14, 2025
b105c70
Add hello_perf_output BCC-Example skeleton
r41k0u Oct 15, 2025
a0d954b
Register bpf_get_current_comm_emitter for comm
r41k0u Oct 15, 2025
13a804f
Implement bpf_get_current_comm_emitter
r41k0u Oct 15, 2025
fb48063
Make char array struct fields work
r41k0u Oct 15, 2025
81f72a7
Support var-to-var and var-to-struct-fld allocations
r41k0u Oct 15, 2025
fd63029
Remove duplicate alignment logic from allocation_pass
r41k0u Oct 15, 2025
9fc3c85
Add struct-field to named-var assignment of char arrays
r41k0u Oct 15, 2025
009b11a
Implement bpf_probe_read_kernel_str helper, Allow i8* to i8 ArrayType…
r41k0u Oct 15, 2025
c143739
Add passing test struct_field_to_var_str for strings
r41k0u Oct 16, 2025
fc55b7e
Add passing ptr_to_char_array test for strings
r41k0u Oct 16, 2025
60737d9
Improve error handling in compile, pass structs_sym_tab and maps_sym_…
r41k0u Oct 16, 2025
8c976e4
Fix loglevel and pylibbpf import in codegen
r41k0u Oct 19, 2025
5bba8dc
Complete hello_perf_output BCC example
r41k0u Oct 19, 2025
aa85d0e
Remove unnecessary attached var in hello_perf_output
r41k0u Oct 20, 2025
dd9411b
Fix userspace calling in hello_world
r41k0u Oct 20, 2025
54c97e6
Fix userspace calling in hello_fields
r41k0u Oct 20, 2025
610cbe8
Fix userspace calling in sync_count
r41k0u Oct 20, 2025
3273620
Fix userspace calling in sync_timing
r41k0u Oct 20, 2025
1740959
Fix userspace calling in sys_sync
r41k0u Oct 20, 2025
d0fecbc
Add sync_perf_output BCC example
r41k0u Oct 20, 2025
c07707a
Add vfsreadlat.py BCC example
r41k0u Oct 20, 2025
e98d568
Add enhanced live vfsreadlat.py monitor BCC example with rich library
r41k0u Oct 20, 2025
798f079
Add enhanced vfsreadlat BCC example with live plotly and dash graphs …
r41k0u Oct 21, 2025
f9494c8
Fix logical fallacy in get_char_array_ptr_and_size
r41k0u Oct 21, 2025
f4d903d
Fix create_targets_and_rvals early returns
r41k0u Oct 21, 2025
84fdf52
Merge branch 'master' into bcc_examples
varun-r-mallya Oct 21, 2025
77c0d13
Add permission error handling in trace_pipe
r41k0u Oct 21, 2025
37af7d2
Janitorial fix format
r41k0u Oct 21, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions BCC-Examples/hello_fields.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
from pythonbpf import bpf, section, bpfglobal, BPF, trace_fields
from ctypes import c_void_p, c_int64


@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def hello_world(ctx: c_void_p) -> c_int64:
print("Hello, World!")
return 0 # type: ignore [return-value]


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()

# header
print(f"{'TIME(s)':<18} {'COMM':<16} {'PID':<6} {'MESSAGE'}")

# format output
while True:
try:
(task, pid, cpu, flags, ts, msg) = trace_fields()
except ValueError:
continue
except KeyboardInterrupt:
exit()
print(f"{ts:<18} {task:<16} {pid:<6} {msg}")
61 changes: 61 additions & 0 deletions BCC-Examples/hello_perf_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from pythonbpf import bpf, map, struct, section, bpfglobal, BPF
from pythonbpf.helper import ktime, pid, comm
from pythonbpf.maps import PerfEventArray
from ctypes import c_void_p, c_int64


@bpf
@struct
class data_t:
pid: c_int64
ts: c_int64
comm: str(16) # type: ignore [valid-type]


@bpf
@map
def events() -> PerfEventArray:
return PerfEventArray(key_size=c_int64, value_size=c_int64)


@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def hello(ctx: c_void_p) -> c_int64:
dataobj = data_t()
dataobj.pid, dataobj.ts = pid(), ktime()
comm(dataobj.comm)
events.output(dataobj)
return 0 # type: ignore [return-value]


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()

start = 0


def callback(cpu, event):
global start
if start == 0:
start = event.ts
ts = (event.ts - start) / 1e9
print(f"[CPU {cpu}] PID: {event.pid}, TS: {ts}, COMM: {event.comm.decode()}")


perf = b["events"].open_perf_buffer(callback, struct_name="data_t")
print("Starting to poll... (Ctrl+C to stop)")
print("Try running: fork() or clone() system calls to trigger events")

try:
while True:
b["events"].poll(1000)
except KeyboardInterrupt:
print("Stopping...")
23 changes: 23 additions & 0 deletions BCC-Examples/hello_world.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pythonbpf import bpf, section, bpfglobal, BPF, trace_pipe
from ctypes import c_void_p, c_int64


@bpf
@section("tracepoint/syscalls/sys_enter_clone")
def hello_world(ctx: c_void_p) -> c_int64:
print("Hello, World!")
return 0 # type: ignore [return-value]


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()

trace_pipe()
58 changes: 58 additions & 0 deletions BCC-Examples/sync_count.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
from pythonbpf import bpf, map, section, bpfglobal, BPF, trace_fields
from pythonbpf.helper import ktime
from pythonbpf.maps import HashMap

from ctypes import c_void_p, c_int64


@bpf
@map
def last() -> HashMap:
return HashMap(key=c_int64, value=c_int64, max_entries=2)


@bpf
@section("tracepoint/syscalls/sys_enter_sync")
def do_trace(ctx: c_void_p) -> c_int64:
ts_key, cnt_key = 0, 1
tsp, cntp = last.lookup(ts_key), last.lookup(cnt_key)
if not cntp:
last.update(cnt_key, 0)
cntp = last.lookup(cnt_key)
if tsp:
delta = ktime() - tsp
if delta < 1000000000:
time_ms = delta // 1000000
print(f"{time_ms} {cntp}")
last.delete(ts_key)
else:
last.update(ts_key, ktime())
last.update(cnt_key, cntp + 1)
return 0 # type: ignore [return-value]


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()

print("Tracing for quick sync's... Ctrl-C to end")

# format output
start = 0
while True:
try:
task, pid, cpu, flags, ts, msg = trace_fields()
if start == 0:
start = ts
ts -= start
ms, cnt = msg.split()
print(f"At time {ts} s: Multiple syncs detected, last {ms} ms ago. Count {cnt}")
except KeyboardInterrupt:
exit()
78 changes: 78 additions & 0 deletions BCC-Examples/sync_perf_output.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
from pythonbpf import bpf, map, struct, section, bpfglobal, BPF
from pythonbpf.helper import ktime
from pythonbpf.maps import HashMap
from pythonbpf.maps import PerfEventArray
from ctypes import c_void_p, c_int64


@bpf
@struct
class data_t:
ts: c_int64
ms: c_int64


@bpf
@map
def events() -> PerfEventArray:
return PerfEventArray(key_size=c_int64, value_size=c_int64)


@bpf
@map
def last() -> HashMap:
return HashMap(key=c_int64, value=c_int64, max_entries=1)


@bpf
@section("tracepoint/syscalls/sys_enter_sync")
def do_trace(ctx: c_void_p) -> c_int64:
dat, dat.ts, key = data_t(), ktime(), 0
tsp = last.lookup(key)
if tsp:
delta = ktime() - tsp
if delta < 1000000000:
dat.ms = delta // 1000000
events.output(dat)
last.delete(key)
else:
last.update(key, ktime())
return 0 # type: ignore [return-value]


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()

print("Tracing for quick sync's... Ctrl-C to end")

# format output
start = 0


def callback(cpu, event):
global start
if start == 0:
start = event.ts
event.ts -= start
print(
f"At time {event.ts / 1e9} s: Multiple sync detected, Last sync: {event.ms} ms ago"
)


perf = b["events"].open_perf_buffer(callback, struct_name="data_t")
print("Starting to poll... (Ctrl+C to stop)")
print("Try running: fork() or clone() system calls to trigger events")

try:
while True:
b["events"].poll(1000)
except KeyboardInterrupt:
print("Stopping...")
53 changes: 53 additions & 0 deletions BCC-Examples/sync_timing.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
from pythonbpf import bpf, map, section, bpfglobal, BPF, trace_fields
from pythonbpf.helper import ktime
from pythonbpf.maps import HashMap

from ctypes import c_void_p, c_int64


@bpf
@map
def last() -> HashMap:
return HashMap(key=c_int64, value=c_int64, max_entries=1)


@bpf
@section("tracepoint/syscalls/sys_enter_sync")
def do_trace(ctx: c_void_p) -> c_int64:
key = 0
tsp = last.lookup(key)
if tsp:
delta = ktime() - tsp
if delta < 1000000000:
time_ms = delta // 1000000
print(f"{time_ms}")
last.delete(key)
else:
last.update(key, ktime())
return 0 # type: ignore [return-value]


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()

print("Tracing for quick sync's... Ctrl-C to end")

# format output
start = 0
while True:
try:
task, pid, cpu, flags, ts, ms = trace_fields()
if start == 0:
start = ts
ts -= start
print(f"At time {ts} s: Multiple syncs detected, last {ms} ms ago")
except KeyboardInterrupt:
exit()
23 changes: 23 additions & 0 deletions BCC-Examples/sys_sync.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from pythonbpf import bpf, section, bpfglobal, BPF, trace_pipe
from ctypes import c_void_p, c_int64


@bpf
@section("tracepoint/syscalls/sys_enter_sync")
def hello_world(ctx: c_void_p) -> c_int64:
print("sys_sync() called")
return c_int64(0)


@bpf
@bpfglobal
def LICENSE() -> str:
return "GPL"


# Compile and load
b = BPF()
b.load()
b.attach_all()
print("Tracing sys_sync()... Ctrl-C to end.")
trace_pipe()
Loading