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  }