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  }