Adding reattach tests for uprobe syscall tests to make sure
we can re-attach and optimize same uprobe multiple times.

Signed-off-by: Jiri Olsa <[email protected]>
---
 .../selftests/bpf/prog_tests/uprobe_syscall.c | 116 ++++++++++++++++--
 1 file changed, 106 insertions(+), 10 deletions(-)

diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c 
b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
index 9653fb5608f2..969f4deba9fd 100644
--- a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
+++ b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
@@ -430,21 +430,28 @@ static void *check_attach(struct uprobe_syscall_executed 
*skel, trigger_t trigge
        return tramp;
 }
 
-static void check_detach(void *addr, void *tramp)
+static bool check_detach(void *addr, void *tramp)
 {
+       static const char nop10_prefix[] = { 0x66, 0x2e, 0x0f, 0x1f, 0x84 };
+       bool ok = true;
+
        /* [uprobes_trampoline] stays after detach */
-       ASSERT_OK(find_uprobes_trampoline(tramp), "uprobes_trampoline");
-       ASSERT_OK(memcmp(addr, jmp2B, 2), "jmp2B");
+       if (!ASSERT_OK(find_uprobes_trampoline(tramp), "uprobes_trampoline"))
+               ok = false;
+       if (!ASSERT_OK(memcmp(addr, nop10_prefix, 5), "nop10_prefix"))
+               ok = false;
+       return ok;
 }
 
-static void check(struct uprobe_syscall_executed *skel, struct bpf_link *link,
-                 trigger_t trigger, void *addr, int executed)
+static void *check(struct uprobe_syscall_executed *skel, struct bpf_link *link,
+                  trigger_t trigger, void *addr, int executed)
 {
        void *tramp;
 
        tramp = check_attach(skel, trigger, addr, executed);
        bpf_link__destroy(link);
        check_detach(addr, tramp);
+       return tramp;
 }
 
 static void test_uprobe_legacy(void)
@@ -455,6 +462,7 @@ static void test_uprobe_legacy(void)
        );
        struct bpf_link *link;
        unsigned long offset;
+       void *tramp;
 
        offset = get_uprobe_offset(&uprobe_test);
        if (!ASSERT_GE(offset, 0, "get_uprobe_offset"))
@@ -472,7 +480,28 @@ static void test_uprobe_legacy(void)
        if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_opts"))
                goto cleanup;
 
-       check(skel, link, uprobe_test, uprobe_test, 2);
+       tramp = check(skel, link, uprobe_test, uprobe_test, 2);
+
+       /* reattach and detach without triggering optimization */
+       link = bpf_program__attach_uprobe_opts(skel->progs.test_uprobe,
+                                              0, "/proc/self/exe", offset, 
NULL);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_opts"))
+               goto cleanup;
+
+       bpf_link__destroy(link);
+       if (!check_detach(uprobe_test, tramp))
+               goto cleanup;
+
+       uprobe_test();
+       ASSERT_EQ(skel->bss->executed, 2, "executed_no_probe");
+
+       /* reattach with triggering optimization */
+       link = bpf_program__attach_uprobe_opts(skel->progs.test_uprobe,
+                               0, "/proc/self/exe", offset, NULL);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_opts"))
+               goto cleanup;
+
+       check(skel, link, uprobe_test, uprobe_test, 4);
 
        /* uretprobe */
        skel->bss->executed = 0;
@@ -494,6 +523,7 @@ static void test_uprobe_multi(void)
        LIBBPF_OPTS(bpf_uprobe_multi_opts, opts);
        struct bpf_link *link;
        unsigned long offset;
+       void *tramp;
 
        offset = get_uprobe_offset(&uprobe_test);
        if (!ASSERT_GE(offset, 0, "get_uprobe_offset"))
@@ -514,7 +544,28 @@ static void test_uprobe_multi(void)
        if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_multi"))
                goto cleanup;
 
-       check(skel, link, uprobe_test, uprobe_test, 2);
+       tramp = check(skel, link, uprobe_test, uprobe_test, 2);
+
+       /* reattach and detach without triggering optimization */
+       link = bpf_program__attach_uprobe_multi(skel->progs.test_uprobe_multi,
+                               0, "/proc/self/exe", NULL, &opts);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_multi"))
+               goto cleanup;
+
+       bpf_link__destroy(link);
+       if (!check_detach(uprobe_test, tramp))
+               goto cleanup;
+
+       uprobe_test();
+       ASSERT_EQ(skel->bss->executed, 2, "executed_no_probe");
+
+       /* reattach with triggering optimization */
+       link = bpf_program__attach_uprobe_multi(skel->progs.test_uprobe_multi,
+                               0, "/proc/self/exe", NULL, &opts);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_multi"))
+               goto cleanup;
+
+       check(skel, link, uprobe_test, uprobe_test, 4);
 
        /* uretprobe.multi */
        skel->bss->executed = 0;
@@ -538,6 +589,7 @@ static void test_uprobe_session(void)
        );
        struct bpf_link *link;
        unsigned long offset;
+       void *tramp;
 
        offset = get_uprobe_offset(&uprobe_test);
        if (!ASSERT_GE(offset, 0, "get_uprobe_offset"))
@@ -557,7 +609,28 @@ static void test_uprobe_session(void)
        if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_multi"))
                goto cleanup;
 
-       check(skel, link, uprobe_test, uprobe_test, 4);
+       tramp = check(skel, link, uprobe_test, uprobe_test, 4);
+
+       /* reattach and detach without triggering optimization */
+       link = bpf_program__attach_uprobe_multi(skel->progs.test_uprobe_session,
+                               0, "/proc/self/exe", NULL, &opts);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_multi"))
+               goto cleanup;
+
+       bpf_link__destroy(link);
+       if (!check_detach(uprobe_test, tramp))
+               goto cleanup;
+
+       uprobe_test();
+       ASSERT_EQ(skel->bss->executed, 4, "executed_no_probe");
+
+       /* reattach with triggering optimization */
+       link = bpf_program__attach_uprobe_multi(skel->progs.test_uprobe_session,
+                               0, "/proc/self/exe", NULL, &opts);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_uprobe_multi"))
+               goto cleanup;
+
+       check(skel, link, uprobe_test, uprobe_test, 8);
 
 cleanup:
        uprobe_syscall_executed__destroy(skel);
@@ -567,7 +640,7 @@ static void test_uprobe_usdt(void)
 {
        struct uprobe_syscall_executed *skel;
        struct bpf_link *link;
-       void *addr;
+       void *addr, *tramp;
 
        errno = 0;
        addr = find_nop10(usdt_test);
@@ -586,7 +659,30 @@ static void test_uprobe_usdt(void)
        if (!ASSERT_OK_PTR(link, "bpf_program__attach_usdt"))
                goto cleanup;
 
-       check(skel, link, usdt_test, addr, 2);
+       tramp = check(skel, link, usdt_test, addr, 2);
+
+       /* reattach and detach without triggering optimization */
+       link = bpf_program__attach_usdt(skel->progs.test_usdt,
+                               -1 /* all PIDs */, "/proc/self/exe",
+                               "optimized_uprobe", "usdt", NULL);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_usdt"))
+               goto cleanup;
+
+       bpf_link__destroy(link);
+       if (!check_detach(addr, tramp))
+               goto cleanup;
+
+       usdt_test();
+       ASSERT_EQ(skel->bss->executed, 2, "executed_no_probe");
+
+       /* reattach with triggering optimization */
+       link = bpf_program__attach_usdt(skel->progs.test_usdt,
+                               -1 /* all PIDs */, "/proc/self/exe",
+                               "optimized_uprobe", "usdt", NULL);
+       if (!ASSERT_OK_PTR(link, "bpf_program__attach_usdt"))
+               goto cleanup;
+
+       check(skel, link, usdt_test, addr, 4);
 
 cleanup:
        uprobe_syscall_executed__destroy(skel);
-- 
2.53.0


Reply via email to