From 18811933bf3b4f89a6caae2d8d1dc7a0fe41d7ad Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 30 Sep 2025 20:52:41 +0530 Subject: [PATCH 1/2] cleanup stray files and add return paths --- pythonbpf/bpf_helper_handler.py | 2 ++ pythonbpf/trace.py | 54 --------------------------------- 2 files changed, 2 insertions(+), 54 deletions(-) delete mode 100644 pythonbpf/trace.py diff --git a/pythonbpf/bpf_helper_handler.py b/pythonbpf/bpf_helper_handler.py index ceff09a..ed229cc 100644 --- a/pythonbpf/bpf_helper_handler.py +++ b/pythonbpf/bpf_helper_handler.py @@ -219,6 +219,7 @@ def bpf_printk_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, builder.call(fn_ptr, [fmt_ptr, ir.Constant( ir.IntType(32), len(fmt_str))], tail=True) + return None def bpf_map_update_elem_emitter(call, map_ptr, module, builder, func, local_sym_tab=None, struct_sym_tab=None, local_var_metadata=None): @@ -496,3 +497,4 @@ def handle_helper_call(call, module, builder, func, local_sym_tab=None, map_sym_ else: raise NotImplementedError( "Attribute not supported for map method calls.") + return None diff --git a/pythonbpf/trace.py b/pythonbpf/trace.py deleted file mode 100644 index 14cc2a6..0000000 --- a/pythonbpf/trace.py +++ /dev/null @@ -1,54 +0,0 @@ -class TraceEvent: - def __init__(self, timestamp, comm, pid, cpu, flags, message): - """Represents a parsed trace pipe event""" - self.timestamp = timestamp # float: timestamp in seconds - self.comm = comm # str: command name - self.pid = pid # int: process ID - self.cpu = cpu # int: CPU number - self.flags = flags # str: trace flags - self.message = message # str: the actual message - - def __iter__(self): - """Allow unpacking like the original BCC tuple""" - yield self.comm - yield self.pid - yield self.cpu - yield self.flags - yield self.timestamp - yield self.message - - -class TraceReader: - def __init__(self, trace_pipe_path="/sys/kernel/debug/tracing/trace_pipe"): - self.trace_pipe_path = trace_pipe_path - self.file = None - - def __enter__(self): - self.file = open(self.trace_pipe_path, "r") - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - if self.file: - self.file.close() - - def __iter__(self): - while True: - event = self.trace_fields() - if event: - yield event - - def trace_fields(self): - """Read and parse one line from the trace pipe""" - if not self.file: - self.file = open(self.trace_pipe_path, "r") - line = self.file.readline() - if not line: - return None - # Parse the line into components (simplified) - # Real implementation would need more robust parsing - parts = self._parse_trace_line(line) - return TraceEvent(*parts) - - def _parse_trace_line(self, line): - # TODO: Implement - pass From 0d0a318e466ed4d86f7ca5f2ea60cdfb3ac32549 Mon Sep 17 00:00:00 2001 From: varun-r-mallya Date: Tue, 30 Sep 2025 21:05:07 +0530 Subject: [PATCH 2/2] cleanup and rename --- examples/{pybpf3.py => binops_demo.py} | 4 +- examples/{execve4.py => blk_request.py} | 0 examples/{pybpf4.py => clone_plot.py} | 2 +- examples/execve2.py | 35 ---------------- examples/execve3.py | 45 --------------------- examples/{pybpf0.py => hello_world.py} | 15 ++++--- examples/{execve5.py => struct_and_perf.py} | 0 examples/{pybpf2.py => sys_sync.py} | 4 +- examples/{pybpf1.py => xdp_pass.py} | 6 +-- {examples => tests}/c-form/Makefile | 0 {examples => tests}/c-form/ex2.bpf.c | 0 {examples => tests}/c-form/ex3-2.bpf.c | 0 {examples => tests}/c-form/ex3.bpf.c | 0 {examples => tests}/c-form/ex4.bpf.c | 0 {examples => tests}/c-form/ex5.bpf.c | 0 {examples => tests}/c-form/ex6.bpf.c | 0 {examples => tests}/c-form/ex7.bpf.c | 0 {examples => tests}/c-form/ex8.bpf.c | 0 {examples => tests}/c-form/example.bpf.c | 0 {examples => tests}/c-form/vmlinux.h | 0 {examples => tools}/check.sh | 0 tools/compile.py | 20 --------- 22 files changed, 18 insertions(+), 113 deletions(-) rename examples/{pybpf3.py => binops_demo.py} (89%) rename examples/{execve4.py => blk_request.py} (100%) rename examples/{pybpf4.py => clone_plot.py} (96%) delete mode 100644 examples/execve2.py delete mode 100644 examples/execve3.py rename examples/{pybpf0.py => hello_world.py} (51%) rename examples/{execve5.py => struct_and_perf.py} (100%) rename examples/{pybpf2.py => sys_sync.py} (88%) rename examples/{pybpf1.py => xdp_pass.py} (83%) rename {examples => tests}/c-form/Makefile (100%) rename {examples => tests}/c-form/ex2.bpf.c (100%) rename {examples => tests}/c-form/ex3-2.bpf.c (100%) rename {examples => tests}/c-form/ex3.bpf.c (100%) rename {examples => tests}/c-form/ex4.bpf.c (100%) rename {examples => tests}/c-form/ex5.bpf.c (100%) rename {examples => tests}/c-form/ex6.bpf.c (100%) rename {examples => tests}/c-form/ex7.bpf.c (100%) rename {examples => tests}/c-form/ex8.bpf.c (100%) rename {examples => tests}/c-form/example.bpf.c (100%) rename {examples => tests}/c-form/vmlinux.h (100%) rename {examples => tools}/check.sh (100%) delete mode 100755 tools/compile.py diff --git a/examples/pybpf3.py b/examples/binops_demo.py similarity index 89% rename from examples/pybpf3.py rename to examples/binops_demo.py index 13897c1..f3b65ba 100644 --- a/examples/pybpf3.py +++ b/examples/binops_demo.py @@ -6,8 +6,8 @@ # Instructions to how to run this program # 1. Install PythonBPF: pip install pythonbpf -# 2. Run the program: python demo/pybpf3.py -# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf3.o +# 2. Run the program: python examples/binops_demo.py +# 3. Run the program with sudo: sudo tools/check.sh run examples/binops_demo.py # 4. Start up any program and watch the output @bpf diff --git a/examples/execve4.py b/examples/blk_request.py similarity index 100% rename from examples/execve4.py rename to examples/blk_request.py diff --git a/examples/pybpf4.py b/examples/clone_plot.py similarity index 96% rename from examples/pybpf4.py rename to examples/clone_plot.py index 8e9fd87..28c5c1a 100644 --- a/examples/pybpf4.py +++ b/examples/clone_plot.py @@ -12,7 +12,7 @@ # and then plots the distribution as a histogram using matplotlib. # It provides a quick view of process creation activity over 10 seconds. # Everything is done with Python only code and with the new pylibbpf library. -# Run `sudo /path/to/python/binary/ pybpf4.py` +# Run `sudo /path/to/python/binary/ clone_plot.py` @bpf @map diff --git a/examples/execve2.py b/examples/execve2.py deleted file mode 100644 index fadc396..0000000 --- a/examples/execve2.py +++ /dev/null @@ -1,35 +0,0 @@ -from pythonbpf.decorators import bpf, map, section, bpfglobal -from ctypes import c_void_p, c_int64, c_int32, c_uint64 -from pythonbpf.helpers import ktime -from pythonbpf.maps import HashMap - - -@bpf -@map -def last() -> HashMap: - return HashMap(key=c_uint64, value=c_uint64, max_entries=1) - - -@bpf -@section("tracepoint/syscalls/sys_enter_execve") -def hello(ctx: c_void_p) -> c_int32: - print("entered") - print("multi constant support") - return c_int32(0) - - -@bpf -@section("tracepoint/syscalls/sys_exit_execve") -def hello_again(ctx: c_void_p) -> c_int64: - print("exited") - key = 0 - tsp = last().lookup(key) - print(tsp) - ts = ktime() - return c_int64(0) - - -@bpf -@bpfglobal -def LICENSE() -> str: - return "GPL" diff --git a/examples/execve3.py b/examples/execve3.py deleted file mode 100644 index 510d6fa..0000000 --- a/examples/execve3.py +++ /dev/null @@ -1,45 +0,0 @@ -from pythonbpf import bpf, map, section, bpfglobal, compile -from pythonbpf.helpers import ktime, deref -from pythonbpf.maps import HashMap - -from ctypes import c_void_p, c_int64, c_int32, c_uint64 - - -@bpf -@map -def last() -> HashMap: - return HashMap(key=c_uint64, value=c_uint64, max_entries=3) - -@bpf -@section("tracepoint/syscalls/sys_exit_execve") -def hello_again(ctx: c_void_p) -> c_int64: - print("multi constant support") - print("exited") - key = 0 - delta = 0 - dddelta = 0 - tsp = last().lookup(key) - if True: - delta = ktime() - ddelta = deref(delta) - ttsp = deref(deref(tsp)) - dddelta = ddelta - ttsp - if dddelta < 1000000000: - print("execve called within last second") - last().delete(key) - ts = ktime() - last().update(key, ts) - - va = 8 - nm = 5 + va - al = 6 & 3 - print(f"this is a variable {nm}") - - return c_int64(0) - -@bpf -@bpfglobal -def LICENSE() -> str: - return "GPL" - -compile() diff --git a/examples/pybpf0.py b/examples/hello_world.py similarity index 51% rename from examples/pybpf0.py rename to examples/hello_world.py index b292ced..7fc9927 100644 --- a/examples/pybpf0.py +++ b/examples/hello_world.py @@ -1,11 +1,9 @@ -from pythonbpf import bpf, section, bpfglobal, compile - +from pythonbpf import bpf, section, bpfglobal, compile, BPF from ctypes import c_void_p, c_int64 # Instructions to how to run this program # 1. Install PythonBPF: pip install pythonbpf -# 2. Run the program: python demo/pybpf0.py -# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf0.o +# 2. Run the program: sudo python examples/hello_world.py # 4. Start up any program and watch the output @@ -20,4 +18,11 @@ def hello_world(ctx: c_void_p) -> c_int64: def LICENSE() -> str: return "GPL" -compile() +b = BPF() +b.load_and_attach() +if b.is_loaded() and b.is_attached(): + print("Successfully loaded and attached") +else: + print("Could not load successfully") + +# Now cat /sys/kernel/debug/tracing/trace_pipe to see results of the execve syscall. diff --git a/examples/execve5.py b/examples/struct_and_perf.py similarity index 100% rename from examples/execve5.py rename to examples/struct_and_perf.py diff --git a/examples/pybpf2.py b/examples/sys_sync.py similarity index 88% rename from examples/pybpf2.py rename to examples/sys_sync.py index 94e0d6a..953cb11 100644 --- a/examples/pybpf2.py +++ b/examples/sys_sync.py @@ -6,8 +6,8 @@ # Instructions to how to run this program # 1. Install PythonBPF: pip install pythonbpf -# 2. Run the program: python demo/pybpf2.py -# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf2.o +# 2. Run the program: python examples/sys_sync.py +# 3. Run the program with sudo: sudo tools/check.sh run examples/sys_sync.o # 4. Start a Python repl and `import os` and then keep entering `os.sync()` to see reponses. @bpf diff --git a/examples/pybpf1.py b/examples/xdp_pass.py similarity index 83% rename from examples/pybpf1.py rename to examples/xdp_pass.py index 409e553..74d6f5f 100644 --- a/examples/pybpf1.py +++ b/examples/xdp_pass.py @@ -6,9 +6,9 @@ # Instructions to how to run this program # 1. Install PythonBPF: pip install pythonbpf -# 2. Run the program: python demo/pybpf1.py -# 3. Run the program with sudo: sudo examples/check.sh run demo/pybpf1.o -# 4. Attach object file to any network device with something like ./check.sh xdp ../demo/pybpf1.o tailscale0 +# 2. Run the program: python examples/xdp_pass.py +# 3. Run the program with sudo: sudo tools/check.sh run examples/xdp_pass.o +# 4. Attach object file to any network device with something like ./check.sh xdp examples/xdp_pass.o tailscale0 # 5. send traffic through the device and observe effects @bpf diff --git a/examples/c-form/Makefile b/tests/c-form/Makefile similarity index 100% rename from examples/c-form/Makefile rename to tests/c-form/Makefile diff --git a/examples/c-form/ex2.bpf.c b/tests/c-form/ex2.bpf.c similarity index 100% rename from examples/c-form/ex2.bpf.c rename to tests/c-form/ex2.bpf.c diff --git a/examples/c-form/ex3-2.bpf.c b/tests/c-form/ex3-2.bpf.c similarity index 100% rename from examples/c-form/ex3-2.bpf.c rename to tests/c-form/ex3-2.bpf.c diff --git a/examples/c-form/ex3.bpf.c b/tests/c-form/ex3.bpf.c similarity index 100% rename from examples/c-form/ex3.bpf.c rename to tests/c-form/ex3.bpf.c diff --git a/examples/c-form/ex4.bpf.c b/tests/c-form/ex4.bpf.c similarity index 100% rename from examples/c-form/ex4.bpf.c rename to tests/c-form/ex4.bpf.c diff --git a/examples/c-form/ex5.bpf.c b/tests/c-form/ex5.bpf.c similarity index 100% rename from examples/c-form/ex5.bpf.c rename to tests/c-form/ex5.bpf.c diff --git a/examples/c-form/ex6.bpf.c b/tests/c-form/ex6.bpf.c similarity index 100% rename from examples/c-form/ex6.bpf.c rename to tests/c-form/ex6.bpf.c diff --git a/examples/c-form/ex7.bpf.c b/tests/c-form/ex7.bpf.c similarity index 100% rename from examples/c-form/ex7.bpf.c rename to tests/c-form/ex7.bpf.c diff --git a/examples/c-form/ex8.bpf.c b/tests/c-form/ex8.bpf.c similarity index 100% rename from examples/c-form/ex8.bpf.c rename to tests/c-form/ex8.bpf.c diff --git a/examples/c-form/example.bpf.c b/tests/c-form/example.bpf.c similarity index 100% rename from examples/c-form/example.bpf.c rename to tests/c-form/example.bpf.c diff --git a/examples/c-form/vmlinux.h b/tests/c-form/vmlinux.h similarity index 100% rename from examples/c-form/vmlinux.h rename to tests/c-form/vmlinux.h diff --git a/examples/check.sh b/tools/check.sh similarity index 100% rename from examples/check.sh rename to tools/check.sh diff --git a/tools/compile.py b/tools/compile.py deleted file mode 100755 index 7a12159..0000000 --- a/tools/compile.py +++ /dev/null @@ -1,20 +0,0 @@ -#!/usr/bin/env python3 -import argparse, subprocess, os -from pythonbpf import codegen - -def main(): - parser = argparse.ArgumentParser() - parser.add_argument("source", help="Python BPF program") - args = parser.parse_args() - - ll_file = os.path.splitext(args.source)[0] + ".ll" - o_file = os.path.splitext(args.source)[0] + ".o" - - print(f"[+] Compiling {args.source} → {ll_file}") - codegen.compile_to_ir(args.source, ll_file) - - print("[+] Running llc -march=bpf") - subprocess.run(["llc", "-march=bpf", "-filetype=obj", "-O2", ll_file, "-o", o_file], check=True) - -if __name__ == "__main__": - main()