Re: [PATCH bpf-next 10/13] selftests/bpf: Add uprobe/usdt optimized test

Andrii Nakryiko
2024-12-13T21:58:52Z

On Wed, Dec 11, 2024 at 5:35 AM Jiri Olsa <jolsa@kernel.org> wrote:
>
> Adding tests for optimized uprobe/usdt probes.
>
> Checking that we get expected trampoline and attached bpf programs
> get executed properly.
>
> Signed-off-by: Jiri Olsa <jolsa@kernel.org>
> ---
> .../selftests/bpf/prog_tests/uprobe_syscall.c | 203 ++++++++++++++++++
> .../selftests/bpf/progs/uprobe_optimized.c | 29 +++
> 2 files changed, 232 insertions(+)
> create mode 100644 tools/testing/selftests/bpf/progs/uprobe_optimized.c
>
> diff --git a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> index c397336fe1ed..1dbc26a1130c 100644
> --- a/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> +++ b/tools/testing/selftests/bpf/prog_tests/uprobe_syscall.c
> @@ -14,6 +14,8 @@
> #include <asm/prctl.h>
> #include "uprobe_syscall.skel.h"
> #include "uprobe_syscall_executed.skel.h"
> +#include "uprobe_optimized.skel.h"
> +#include "sdt.h"
>
> __naked unsigned long uretprobe_regs_trigger(void)
> {
> @@ -350,6 +352,186 @@ static void test_uretprobe_shadow_stack(void)
>
> ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK);
> }
> +
> +#define TRAMP "[uprobes-trampoline]"
> +
> +static unsigned char nop5[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
> +
> +noinline void uprobe_test(void)
> +{
> + asm volatile (" \n"
> + ".global uprobe_test_nop5 \n"
> + ".type uprobe_test_nop5, STT_FUNC \n"
> + "uprobe_test_nop5: \n"
> + ".byte 0x0f, 0x1f, 0x44, 0x00, 0x00 \n"
> + );
> +}
> +
> +extern u8 uprobe_test_nop5[];
> +
> +noinline void usdt_test(void)
> +{
> + STAP_PROBE(optimized_uprobe, usdt);
> +}
> +
> +static void *find_nop5(void *fn)
> +{
> + int i;
> +
> + for (i = 0; i < 10; i++) {
> + if (!memcmp(nop5, fn + i, 5))
> + return fn + i;
> + }
> + return NULL;
> +}
> +
> +static int find_uprobes_trampoline(void **start, void **end)
> +{
> + char line[128];
> + int ret = -1;
> + FILE *maps;
> +
> + maps = fopen("/proc/self/maps", "r");
> + if (!maps) {
> + fprintf(stderr, "cannot open maps\n");
> + return -1;
> + }
> +
> + while (fgets(line, sizeof(line), maps)) {
> + int m = -1;
> +
> + /* We care only about private r-x mappings. */
> + if (sscanf(line, "%p-%p r-xp %*x %*x:%*x %*u %n", start, end, &m) != 2)
> + continue;
> + if (m < 0)
> + continue;
> + if (!strncmp(&line[m], TRAMP, sizeof(TRAMP)-1)) {
> + ret = 0;
> + break;
> + }
> + }

you could have used PROCMAP_QUERY ;)

> +
> + fclose(maps);
> + return ret;
> +}
> + …