main.go 1.7 KB

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