...

Source file src/github.com/cilium/ebpf/btf/handle_test.go

Documentation: github.com/cilium/ebpf/btf

     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  	var h *btf.Handle
    18  	defer h.Close()
    19  
    20  	it := new(btf.HandleIterator)
    21  	if !it.Next(&h) {
    22  		t.Fatalf("No BTF loaded")
    23  	}
    24  	if h == nil {
    25  		t.Fatal("Next doesn't assign handle")
    26  	}
    27  	prev := it.ID
    28  	for it.Next(&h) {
    29  		// Iterate all loaded BTF.
    30  		if h == nil {
    31  			t.Fatal("Next doesn't assign handle")
    32  		}
    33  		if it.ID == prev {
    34  			t.Fatal("Iterator doesn't advance ID")
    35  		}
    36  		prev = it.ID
    37  	}
    38  	if err := it.Err(); err != nil {
    39  		t.Fatal("Iteration returned an error:", err)
    40  	}
    41  
    42  	if h != nil {
    43  		t.Fatal("Next doesn't clean up handle on last iteration")
    44  	}
    45  	if prev != it.ID {
    46  		t.Fatal("Next changes ID on last iteration")
    47  	}
    48  }
    49  
    50  func TestParseModuleSplitSpec(t *testing.T) {
    51  	// See TestNewHandleFromID for reasoning.
    52  	testutils.SkipOnOldKernel(t, "5.11", "vmlinux BTF ID")
    53  
    54  	var module *btf.Handle
    55  	defer module.Close()
    56  
    57  	it := new(btf.HandleIterator)
    58  	for it.Next(&module) {
    59  		info, err := module.Info()
    60  		if err != nil {
    61  			t.Fatal(err)
    62  		}
    63  
    64  		if !info.IsModule() {
    65  			continue
    66  		}
    67  
    68  		t.Log("Using module", info.Name)
    69  		break
    70  	}
    71  	if err := it.Err(); err != nil {
    72  		t.Fatal(err)
    73  	}
    74  
    75  	if module == nil {
    76  		t.Fatal("No BTF for kernel module found")
    77  	}
    78  
    79  	var vmlinux *btf.Handle
    80  	defer vmlinux.Close()
    81  
    82  	it = new(btf.HandleIterator)
    83  	for it.Next(&vmlinux) {
    84  		info, err := vmlinux.Info()
    85  		if err != nil {
    86  			t.Fatal(err)
    87  		}
    88  
    89  		if !info.IsVmlinux() {
    90  			continue
    91  		}
    92  
    93  		break
    94  	}
    95  	if err := it.Err(); err != nil {
    96  		t.Fatal(err)
    97  	}
    98  
    99  	if vmlinux == nil {
   100  		t.Fatal("No BTF for kernel found")
   101  	}
   102  
   103  	vmlinuxSpec, err := vmlinux.Spec(nil)
   104  	if err != nil {
   105  		t.Fatal("Parse vmlinux BTF:", err)
   106  	}
   107  
   108  	_, err = module.Spec(vmlinuxSpec)
   109  	if err != nil {
   110  		t.Fatal("Parse module BTF:", err)
   111  	}
   112  
   113  	_, err = module.Spec(nil)
   114  	if err == nil {
   115  		t.Fatal("Parsing module BTF without vmlinux base didn't fail")
   116  	}
   117  }
   118  
   119  func ExampleHandleIterator() {
   120  	var handle *btf.Handle
   121  	// Ensure that handle is cleaned up. This is valid for nil handles as well.
   122  	defer handle.Close()
   123  
   124  	it := new(btf.HandleIterator)
   125  	for it.Next(&handle) {
   126  		fmt.Printf("Found handle with ID %d\n", it.ID)
   127  	}
   128  	if err := it.Err(); err != nil {
   129  		panic(err)
   130  	}
   131  }
   132  

View as plain text