This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# | |
from bcc import BPF | |
import ctypes as ct | |
# define BPF program | |
prog = """ | |
#include <linux/sched.h> | |
#include <linux/bpf.h> | |
// define output data structure in C | |
struct data_t { | |
u64 key; | |
char map[16]; | |
}; | |
struct fd_pid { | |
u32 fd; | |
u32 pid; | |
}; | |
BPF_PERF_OUTPUT(events); | |
BPF_HASH(currmap, u32, char*); | |
#Keep track of fd_pid to map name association | |
BPF_HASH(mapidfdpid,struct fd_pid,char*); | |
int kprobe__bpf_map_new_fd(struct pt_regs *ctx, struct bpf_map *map){ | |
u32 pid = bpf_get_current_pid_tgid(); | |
char mapname[16]; | |
bpf_probe_read_str(mapname,16,map->name); | |
currmap.update(&pid,&mapname); | |
} | |
int kretprobe__bpf_map_new_fd(struct pt_regs *ctx){ | |
int ret = PT_REGS_RC(ctx); | |
u32 pid = bpf_get_current_pid_tgid(); | |
char ** mapname = currmap.lookup(&pid); | |
if(mapname==0){ | |
return 0; | |
} | |
struct fd_pid fd_pid={}; | |
fd_pid.pid=pid; | |
fd_pid.fd=ret; | |
mapidfdpid.update(&fd_pid,mapname); | |
bpf_trace_printk("trace %d %d %s\\n", pid, ret, mapname); | |
} | |
int hello(struct pt_regs *ctx, union bpf_attr *attr) { | |
struct data_t data = {}; | |
u32 pid = bpf_get_current_pid_tgid(); | |
struct fd_pid fd_pid={}; | |
fd_pid.pid=pid; | |
fd_pid.fd=attr->map_fd; | |
#Recover mapname from current pid and fd | |
char** mapname=mapidfdpid.lookup(&fd_pid); | |
if(mapname==0){ | |
return 0; | |
} | |
__aligned_u64 key=attr->key; | |
bpf_probe_read_str(&(data.map),16U,mapname); | |
#doing the same operation of map_update elem | |
void __user *ukey = u64_to_user_ptr(key); | |
#TODO:!assume that key is a long | |
bpf_probe_read(&data.key, 8, ukey); | |
bpf_trace_printk("trace %d %d %s\\n", pid, attr->value, mapname); | |
events.perf_submit(ctx, &data, sizeof(data)); | |
bpf_trace_printk("trace \\n"); | |
return 0; | |
} | |
""" | |
# load BPF program | |
b = BPF(text=prog) | |
b.attach_kprobe(event="map_update_elem", fn_name="hello") | |
# define output data structure in Python | |
class Data(ct.Structure): | |
_fields_ = [("key", ct.c_ulonglong), | |
("map",ct.c_char*16),] | |
# process event | |
start = 0 | |
def print_event(cpu, data, size): | |
event = ct.cast(data, ct.POINTER(Data)).contents | |
print("%s %d" % (event.map, event.key)) | |
# loop with callback to print_event | |
b["events"].open_perf_buffer(print_event) | |
while 1: | |
b.perf_buffer_poll() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment