100 lines
2.0 KiB
Go
100 lines
2.0 KiB
Go
package btf_test
|
|
|
|
import (
|
|
"fmt"
|
|
"testing"
|
|
|
|
"github.com/cilium/ebpf/btf"
|
|
"github.com/cilium/ebpf/internal/testutils"
|
|
)
|
|
|
|
func TestHandleIterator(t *testing.T) {
|
|
// There is no guarantee that there is a BTF ID allocated, but loading a module
|
|
// triggers loading vmlinux.
|
|
// See https://github.com/torvalds/linux/commit/5329722057d41aebc31e391907a501feaa42f7d9
|
|
testutils.SkipOnOldKernel(t, "5.11", "vmlinux BTF ID")
|
|
|
|
it := new(btf.HandleIterator)
|
|
defer it.Handle.Close()
|
|
|
|
if !it.Next() {
|
|
t.Fatalf("No BTF loaded")
|
|
}
|
|
if it.Handle == nil {
|
|
t.Fatal("Next doesn't assign handle")
|
|
}
|
|
prev := it.ID
|
|
for it.Next() {
|
|
// Iterate all loaded BTF.
|
|
if it.Handle == nil {
|
|
t.Fatal("Next doesn't assign handle")
|
|
}
|
|
if it.ID == prev {
|
|
t.Fatal("Iterator doesn't advance ID")
|
|
}
|
|
prev = it.ID
|
|
}
|
|
if err := it.Err(); err != nil {
|
|
t.Fatal("Iteration returned an error:", err)
|
|
}
|
|
|
|
if it.Handle != nil {
|
|
t.Fatal("Next doesn't clean up handle on last iteration")
|
|
}
|
|
if prev != it.ID {
|
|
t.Fatal("Next changes ID on last iteration")
|
|
}
|
|
}
|
|
|
|
func TestParseModuleSplitSpec(t *testing.T) {
|
|
// See TestNewHandleFromID for reasoning.
|
|
testutils.SkipOnOldKernel(t, "5.11", "vmlinux BTF ID")
|
|
|
|
module, err := btf.FindHandle(func(info *btf.HandleInfo) bool {
|
|
if info.IsModule() {
|
|
t.Log("Using module", info.Name)
|
|
return true
|
|
}
|
|
return false
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer module.Close()
|
|
|
|
vmlinux, err := btf.FindHandle(func(info *btf.HandleInfo) bool {
|
|
return info.IsVmlinux()
|
|
})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer vmlinux.Close()
|
|
|
|
base, err := vmlinux.Spec(nil)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
_, err = module.Spec(base)
|
|
if err != nil {
|
|
t.Fatal("Parse module BTF:", err)
|
|
}
|
|
}
|
|
|
|
func ExampleHandleIterator() {
|
|
it := new(btf.HandleIterator)
|
|
defer it.Handle.Close()
|
|
|
|
for it.Next() {
|
|
info, err := it.Handle.Info()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
fmt.Printf("Found handle with ID %d and name %s\n", it.ID, info.Name)
|
|
}
|
|
if err := it.Err(); err != nil {
|
|
panic(err)
|
|
}
|
|
}
|