github.com/cilium/ebpf@v0.15.1-0.20240517100537-8079b37aa138/btf/handle_test.go (about)

     1  package btf_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/cilium/ebpf/btf"
     8  	"github.com/cilium/ebpf/internal/testutils"
     9  )
    10  
    11  func TestHandleIterator(t *testing.T) {
    12  	// There is no guarantee that there is a BTF ID allocated, but loading a module
    13  	// triggers loading vmlinux.
    14  	// See https://github.com/torvalds/linux/commit/5329722057d41aebc31e391907a501feaa42f7d9
    15  	testutils.SkipOnOldKernel(t, "5.11", "vmlinux BTF ID")
    16  
    17  	it := new(btf.HandleIterator)
    18  	defer it.Handle.Close()
    19  
    20  	if !it.Next() {
    21  		t.Fatalf("No BTF loaded")
    22  	}
    23  	if it.Handle == nil {
    24  		t.Fatal("Next doesn't assign handle")
    25  	}
    26  	prev := it.ID
    27  	for it.Next() {
    28  		// Iterate all loaded BTF.
    29  		if it.Handle == nil {
    30  			t.Fatal("Next doesn't assign handle")
    31  		}
    32  		if it.ID == prev {
    33  			t.Fatal("Iterator doesn't advance ID")
    34  		}
    35  		prev = it.ID
    36  	}
    37  	if err := it.Err(); err != nil {
    38  		t.Fatal("Iteration returned an error:", err)
    39  	}
    40  
    41  	if it.Handle != nil {
    42  		t.Fatal("Next doesn't clean up handle on last iteration")
    43  	}
    44  	if prev != it.ID {
    45  		t.Fatal("Next changes ID on last iteration")
    46  	}
    47  }
    48  
    49  func TestParseModuleSplitSpec(t *testing.T) {
    50  	// See TestNewHandleFromID for reasoning.
    51  	testutils.SkipOnOldKernel(t, "5.11", "vmlinux BTF ID")
    52  
    53  	module, err := btf.FindHandle(func(info *btf.HandleInfo) bool {
    54  		if info.IsModule() {
    55  			t.Log("Using module", info.Name)
    56  			return true
    57  		}
    58  		return false
    59  	})
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  	defer module.Close()
    64  
    65  	vmlinux, err := btf.FindHandle(func(info *btf.HandleInfo) bool {
    66  		return info.IsVmlinux()
    67  	})
    68  	if err != nil {
    69  		t.Fatal(err)
    70  	}
    71  	defer vmlinux.Close()
    72  
    73  	base, err := vmlinux.Spec(nil)
    74  	if err != nil {
    75  		t.Fatal(err)
    76  	}
    77  
    78  	_, err = module.Spec(base)
    79  	if err != nil {
    80  		t.Fatal("Parse module BTF:", err)
    81  	}
    82  }
    83  
    84  func ExampleHandleIterator() {
    85  	it := new(btf.HandleIterator)
    86  	defer it.Handle.Close()
    87  
    88  	for it.Next() {
    89  		info, err := it.Handle.Info()
    90  		if err != nil {
    91  			panic(err)
    92  		}
    93  
    94  		fmt.Printf("Found handle with ID %d and name %s\n", it.ID, info.Name)
    95  	}
    96  	if err := it.Err(); err != nil {
    97  		panic(err)
    98  	}
    99  }