Skip to content

Commit

Permalink
link: add test for uprobe multi link
Browse files Browse the repository at this point in the history
This commit adds test for uprobe multi link.

Signed-off-by: Jiri Olsa <jolsa@kernel.org>
  • Loading branch information
olsajiri committed Dec 19, 2023
1 parent ab08e04 commit 4a069fa
Showing 1 changed file with 159 additions and 0 deletions.
159 changes: 159 additions & 0 deletions link/uprobe_multi_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
package link

import (
"errors"
"os/exec"
"testing"

"github.com/cilium/ebpf"
"github.com/cilium/ebpf/internal/testutils"
"github.com/go-quicktest/qt"
)

func TestUprobeMulti(t *testing.T) {
testutils.SkipIfNotSupported(t, haveBPFLinkUprobeMulti())

prog := mustLoadProgram(t, ebpf.Kprobe, ebpf.AttachTraceUprobeMulti, "")

um, err := bashEx.UprobeMulti([]string{"bash_logout", "main"}, prog, nil)
if err != nil {
t.Fatal(err)
}
defer um.Close()

testLink(t, um, prog)
}

func TestUprobeMultiInput(t *testing.T) {
testutils.SkipIfNotSupported(t, haveBPFLinkUprobeMulti())

prog := mustLoadProgram(t, ebpf.Kprobe, ebpf.AttachTraceUprobeMulti, "")

// One of symbols or offsets must be given.
_, err := bashEx.UprobeMulti([]string{}, prog, nil)
qt.Assert(t, qt.ErrorIs(err, errInvalidInput))

// One address, two cookies.
_, err = bashEx.UprobeMulti([]string{}, prog, &UprobeMultiOptions{
Addresses: []uint64{1},
Cookies: []uint64{2, 3},
})
qt.Assert(t, qt.ErrorIs(err, errInvalidInput))

// Two addresses, ont refctr offset.
_, err = bashEx.UprobeMulti([]string{}, prog, &UprobeMultiOptions{
Addresses: []uint64{1, 2},
RefCtrOffsets: []uint64{4},
})
qt.Assert(t, qt.ErrorIs(err, errInvalidInput))

// It's either symbols or addresses.
_, err = bashEx.UprobeMulti([]string{"main"}, prog, &UprobeMultiOptions{
Addresses: []uint64{1},
})
qt.Assert(t, qt.ErrorIs(err, errInvalidInput))
}

func TestUprobeMultiAddresses(t *testing.T) {
addrSym1, err := bashEx.address("main")
if err != nil {
t.Fatal(err)
}
addrSym2, err := bashEx.address("_start")
if err != nil {
t.Fatal(err)
}

addresses, err := bashEx.uprobeMultiAddresses([]string{"main", "_start"}, &UprobeMultiOptions{})
if err != nil {
t.Fatal(err)
}

qt.Assert(t, qt.Equals(len(addresses), 2))
qt.Assert(t, qt.Equals(addresses[0], addrSym1))
qt.Assert(t, qt.Equals(addresses[1], addrSym2))

addresses, err = bashEx.uprobeMultiAddresses([]string{"main", "_start"},
&UprobeMultiOptions{Offsets: []uint64{5, 10}})
if err != nil {
t.Fatal(err)
}

qt.Assert(t, qt.Equals(len(addresses), 2))
qt.Assert(t, qt.Equals(addresses[0], addrSym1+5))
qt.Assert(t, qt.Equals(addresses[1], addrSym2+10))
}

func TestUprobeMultiCookie(t *testing.T) {
testutils.SkipIfNotSupported(t, haveBPFLinkUprobeMulti())

prog := mustLoadProgram(t, ebpf.Kprobe, ebpf.AttachTraceUprobeMulti, "")

um, err := bashEx.UprobeMulti([]string{"bash_logout", "main"}, prog,
&UprobeMultiOptions{
Cookies: []uint64{1, 2},
})
if err != nil {
t.Fatal(err)
}
_ = um.Close()
}

func TestUprobeMultiProgramCall(t *testing.T) {
testutils.SkipIfNotSupported(t, haveBPFLinkUprobeMulti())

args := []string{"--help"}
elf := "/bin/bash"

m, p := newUpdaterMapProg(t, ebpf.Kprobe, ebpf.AttachTraceUprobeMulti)

// Load the executable.
ex, err := OpenExecutable(elf)
if err != nil {
t.Fatal(err)
}

// Open UprobeMulti on the executable for the given symbol
// and attach it to the ebpf program created above.
um, err := ex.UprobeMulti([]string{"main", "_start"}, p, nil)
if errors.Is(err, ErrNoSymbol) {
// Assume bash::main and go::main.main always exists
// and skip the test if the symbol can't be found as
// certain OS (eg. Debian) strip binaries.
t.Skipf("executable %s appear to be stripped, skipping", elf)
}
if err != nil {
t.Fatal(err)
}

// Trigger ebpf program call.
trigger := func(t *testing.T) {
if err := exec.Command(elf, args...).Run(); err != nil {
t.Fatal(err)
}
}
trigger(t)

// Assert that the value at index 0 has been updated to 2.
assertMapValueGE(t, m, 0, 2)

// Detach the Uprobe.
if err := um.Close(); err != nil {
t.Fatal(err)
}

// Reset map value to 0 at index 0.
if err := m.Update(uint32(0), uint32(0), ebpf.UpdateExist); err != nil {
t.Fatal(err)
}

// Retrigger the ebpf program call.
trigger(t)

// Assert that this time the value has not been updated.
assertMapValue(t, m, 0, 0)
}

func TestHaveBPFLinkUprobeMulti(t *testing.T) {
testutils.CheckFeatureTest(t, haveBPFLinkUprobeMulti)
}

0 comments on commit 4a069fa

Please sign in to comment.