github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/examples/tracepoint_in_c/main.go (about) 1 // This program demonstrates attaching an eBPF program to a kernel tracepoint. 2 // The eBPF program will be attached to the page allocation tracepoint and 3 // prints out the number of times it has been reached. The tracepoint fields 4 // are printed into /sys/kernel/tracing/trace_pipe. 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 //go:generate go run github.com/cilium/ebpf/cmd/bpf2go bpf tracepoint.c -- -I../headers 16 17 const mapKey uint32 = 0 18 19 func main() { 20 // Allow the current process to lock memory for eBPF resources. 21 if err := rlimit.RemoveMemlock(); err != nil { 22 log.Fatal(err) 23 } 24 25 // Load pre-compiled programs and maps into the kernel. 26 objs := bpfObjects{} 27 if err := loadBpfObjects(&objs, nil); err != nil { 28 log.Fatalf("loading objects: %v", err) 29 } 30 defer objs.Close() 31 32 // Open a tracepoint and attach the pre-compiled program. Each time 33 // the kernel function enters, the program will increment the execution 34 // counter by 1. The read loop below polls this map value once per 35 // second. 36 // The first two arguments are taken from the following pathname: 37 // /sys/kernel/tracing/events/kmem/mm_page_alloc 38 kp, err := link.Tracepoint("kmem", "mm_page_alloc", objs.MmPageAlloc, nil) 39 if err != nil { 40 log.Fatalf("opening tracepoint: %s", err) 41 } 42 defer kp.Close() 43 44 // Read loop reporting the total amount of times the kernel 45 // function was entered, once per second. 46 ticker := time.NewTicker(1 * time.Second) 47 defer ticker.Stop() 48 49 log.Println("Waiting for events..") 50 for range ticker.C { 51 var value uint64 52 if err := objs.CountingMap.Lookup(mapKey, &value); err != nil { 53 log.Fatalf("reading map: %v", err) 54 } 55 log.Printf("%v times", value) 56 } 57 }