The bolg post adoped from bcc/docs/ mainly. You just glance it.
lesson 1
from bcc import BPF
import signal
import sys
def bpf():
BPF(text='''
int kprobe__sys_sync(void *ctx)
{ bpf_trace_printk("Hello, yubo\\n");
return 0;}'''
).trace_print()
def signal_handler(signal, frame):
print('You pressed Ctrl+c!')
bpf()
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print('press Ctrl+c')
signal.pause()
lesson 2
from bcc import BPF
prog = """
int hello(void *ctx)
{
/* bpf_trace_printk will call it:
* /sys/kernel/debug/tracing/trace_pipe
*/
bpf_trace_printk("Hello, yubo\\n");
return 0;
}
"""
# load BPF program
b = BPF(text=prog)
b.attach_kprobe(event="sys_clone", fn_name="hello")
print("%-18s %-16s %-6s %s" % ("TIME(S)", "COMM", "PID", "MESSAGE"))
while 1:
try:
(task, pid, cpu, flags, ts, msg) = b.trace_fields()
except ValueError:
continue
print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))
Here, this time we declare the C program as a variable : prog
.
-
hello()
On a probe to execute a C program defined here.Maybe you need add_always_inline
function attribute to it. -
b.attach_kprobe()
: creates a kprobe for the sys_clone() kernel function, which will execute our definedhello
C program. -
b.trace_fields()
Returns a fixed set of fields from trace_pipe,which similar to trace_print() .We should switch to BPF_PERF_OUTPUT()
lesson 4
from bcc import BPF
b = BPF(text="""
#include <uapi/linux/ptrace.h>
#include <linux/blkdev.h>
BPF_HASH(last);
int do_trace(struct pt_regs *ctx){
u64 ts, *tsp, delta, key = 0;
/* attempt to read stored timestamp */
tsp = last.lookup(&key);
if (tsp != 0) {
delta = bpf_ktime_get_ns() - *tsp;
if (delta < 1000000000) {
bpf_trace_printk("%d\\n", delta / 1000000);
}
last.delete(&key);
}
/* update stored timestamp */
ts = bpf_ktime_get_ns();
last.update(&key, &ts);
return 0;
}
""")
b.attach_kprobe(event="sys_sync", fn_name="do_trace")
print("Tracing for quick sync's ... Ctrl -c to end ")
# format output
start = 0
while 1:
(task, pid, cpu, flags, ts, ms) = b.trace_fields()
if start == 0:
start = ts
ts = ts - start
print("At time %.2f s: multiple syncs detected, last %s ms ago " % (ts,ms))
Here, we introduce some new usage.BPF_HASH(last)
creates a BPF map object that is a hash called “last”.It is defaults key and value types of u64
last.lookup(&key)
: Lookup the key from the hash.last.delete(&key)
Delete the key from the hash.last.update(&key, &ts)
Associate the valuein the 2nd argument to the key.
Please note: the b.trace_fields
is a kernel debug trace pipe and return a tuple of the fields(task, pid, cpu,flags, timestamp, msg).This is trace debug.