github.com/cilium/ebpf@v0.10.0/examples/kprobe/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 "time" 10 11 "github.com/cilium/ebpf/link" 12 "github.com/cilium/ebpf/rlimit" 13 ) 14 15 // $BPF_CLANG and $BPF_CFLAGS are set by the Makefile. 16 //go:generate go run github.com/cilium/ebpf/cmd/bpf2go -cc $BPF_CLANG -cflags $BPF_CFLAGS bpf kprobe.c -- -I../headers 17 18 const mapKey uint32 = 0 19 20 func main() { 21 22 // Name of the kernel function to trace. 23 fn := "sys_execve" 24 25 // Allow the current process to lock memory for eBPF resources. 26 if err := rlimit.RemoveMemlock(); err != nil { 27 log.Fatal(err) 28 } 29 30 // Load pre-compiled programs and maps into the kernel. 31 objs := bpfObjects{} 32 if err := loadBpfObjects(&objs, nil); err != nil { 33 log.Fatalf("loading objects: %v", err) 34 } 35 defer objs.Close() 36 37 // Open a Kprobe at the entry point of the kernel function and attach the 38 // pre-compiled program. Each time the kernel function enters, the program 39 // will increment the execution counter by 1. The read loop below polls this 40 // map value once per second. 41 kp, err := link.Kprobe(fn, objs.KprobeExecve, nil) 42 if err != nil { 43 log.Fatalf("opening kprobe: %s", err) 44 } 45 defer kp.Close() 46 47 // Read loop reporting the total amount of times the kernel 48 // function was entered, once per second. 49 ticker := time.NewTicker(1 * time.Second) 50 defer ticker.Stop() 51 52 log.Println("Waiting for events..") 53 54 for range ticker.C { 55 var value uint64 56 if err := objs.KprobeMap.Lookup(mapKey, &value); err != nil { 57 log.Fatalf("reading map: %v", err) 58 } 59 log.Printf("%s called %d times\n", fn, value) 60 } 61 }