diff --git a/internal/unix/types_linux.go b/internal/unix/types_linux.go index 0b43d5724..8a030da28 100644 --- a/internal/unix/types_linux.go +++ b/internal/unix/types_linux.go @@ -24,6 +24,7 @@ const ( E2BIG = linux.E2BIG EFAULT = linux.EFAULT EACCES = linux.EACCES + EILSEQ = linux.EILSEQ BPF_F_NO_PREALLOC = linux.BPF_F_NO_PREALLOC BPF_F_NUMA_NODE = linux.BPF_F_NUMA_NODE diff --git a/internal/unix/types_other.go b/internal/unix/types_other.go index 2fc2d2de1..b1318f607 100644 --- a/internal/unix/types_other.go +++ b/internal/unix/types_other.go @@ -25,6 +25,7 @@ const ( E2BIG = syscall.Errno(0) EFAULT = syscall.EFAULT EACCES = syscall.Errno(0) + EILSEQ = syscall.Errno(0) BPF_F_NO_PREALLOC = 0 BPF_F_NUMA_NODE = 0 diff --git a/link/kprobe.go b/link/kprobe.go index 7d93e4f3f..10fcf8ee0 100644 --- a/link/kprobe.go +++ b/link/kprobe.go @@ -307,9 +307,10 @@ func pmuProbe(typ probeType, args probeArgs) (*perfEvent, error) { if errors.Is(err, os.ErrNotExist) { return nil, fmt.Errorf("symbol '%s+%#x' not found: %w", args.symbol, args.offset, os.ErrNotExist) } - // Since commit ab105a4fb894, -EILSEQ is returned when a kprobe sym+offset is resolved - // to an invalid insn boundary. - if errors.Is(err, syscall.EILSEQ) { + // Since commit ab105a4fb894, EILSEQ is returned when a kprobe sym+offset is resolved + // to an invalid insn boundary. The exact conditions that trigger this error are + // arch specific however. + if errors.Is(err, unix.EILSEQ) { return nil, fmt.Errorf("symbol '%s+%#x' not found (bad insn boundary): %w", args.symbol, args.offset, os.ErrNotExist) } // Since at least commit cb9a19fe4aa51, ENOTSUPP is returned diff --git a/link/kprobe_amd64_test.go b/link/kprobe_amd64_test.go deleted file mode 100644 index 7bcad454e..000000000 --- a/link/kprobe_amd64_test.go +++ /dev/null @@ -1,32 +0,0 @@ -//go:build amd64 -// +build amd64 - -package link - -import ( - "errors" - "os" - "testing" - - "github.com/cilium/ebpf" -) - -func TestKprobeOffset(t *testing.T) { - prog := mustLoadProgram(t, ebpf.Kprobe, 0, "") - - for i := uint64(2); i < 10; i++ { - k, err := Kprobe("inet6_release", prog, &KprobeOptions{Offset: i}) - if err != nil { - continue - } - k.Close() - - _, err = Kprobe("inet6_release", prog, &KprobeOptions{Offset: i - 1}) - if !errors.Is(err, os.ErrNotExist) { - t.Fatalf("expected 'os.ErrNotExist', got: '%v'", err) - } - return - } - - t.Fatal("no valid offsets found") -} diff --git a/link/kprobe_test.go b/link/kprobe_test.go index 1b95a9489..081b5c63a 100644 --- a/link/kprobe_test.go +++ b/link/kprobe_test.go @@ -53,6 +53,23 @@ func TestKprobe(t *testing.T) { testLink(t, k, prog) } +func TestKprobeOffset(t *testing.T) { + prog := mustLoadProgram(t, ebpf.Kprobe, 0, "") + + // The layout of a function is compiler and arch dependent, so we try to + // find a valid attach target in the first few bytes of the function. + for i := uint64(1); i < 16; i++ { + k, err := Kprobe("inet6_release", prog, &KprobeOptions{Offset: i}) + if err != nil { + continue + } + k.Close() + return + } + + t.Fatal("Can't attach with non-zero offset") +} + func TestKretprobe(t *testing.T) { prog := mustLoadProgram(t, ebpf.Kprobe, 0, "")