github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/examples/kprobepin/main.go (about) 1 // This program demonstrates attaching an eBPF program to a kernel symbol. 2 // The eBPF program will be attached to the start of the sys_execve 3 // kernel function and prints out the number of times it has been called 4 // every second. 5 package main 6 7 import ( 8 "log" 9 "os" 10 "path" 11 "time" 12 13 "github.com/cilium/ebpf" 14 "github.com/cilium/ebpf/link" 15 "github.com/cilium/ebpf/rlimit" 16 ) 17 18 //go:generate go run github.com/cilium/ebpf/cmd/bpf2go bpf kprobe_pin.c -- -I../headers 19 20 const ( 21 mapKey uint32 = 0 22 bpfFSPath = "/sys/fs/bpf" 23 ) 24 25 func main() { 26 27 // Name of the kernel function to trace. 28 fn := "sys_execve" 29 30 // Allow the current process to lock memory for eBPF resources. 31 if err := rlimit.RemoveMemlock(); err != nil { 32 log.Fatal(err) 33 } 34 35 pinPath := path.Join(bpfFSPath, fn) 36 if err := os.MkdirAll(pinPath, os.ModePerm); err != nil { 37 log.Fatalf("failed to create bpf fs subpath: %+v", err) 38 } 39 40 var objs bpfObjects 41 if err := loadBpfObjects(&objs, &ebpf.CollectionOptions{ 42 Maps: ebpf.MapOptions{ 43 // Pin the map to the BPF filesystem and configure the 44 // library to automatically re-write it in the BPF 45 // program so it can be re-used if it already exists or 46 // create it if not 47 PinPath: pinPath, 48 }, 49 }); err != nil { 50 log.Fatalf("loading objects: %v", err) 51 } 52 defer objs.Close() 53 54 // Open a Kprobe at the entry point of the kernel function and attach the 55 // pre-compiled program. Each time the kernel function enters, the program 56 // will increment the execution counter by 1. The read loop below polls this 57 // map value once per second. 58 kp, err := link.Kprobe(fn, objs.KprobeExecve, nil) 59 if err != nil { 60 log.Fatalf("opening kprobe: %s", err) 61 } 62 defer kp.Close() 63 64 // Read loop reporting the total amount of times the kernel 65 // function was entered, once per second. 66 ticker := time.NewTicker(1 * time.Second) 67 defer ticker.Stop() 68 69 log.Println("Waiting for events..") 70 71 for range ticker.C { 72 var value uint64 73 if err := objs.KprobeMap.Lookup(mapKey, &value); err != nil { 74 log.Fatalf("reading map: %v", err) 75 } 76 log.Printf("%s called %d times\n", fn, value) 77 } 78 }