Skip to content

Commit a0f37f5

Browse files
committed
selftests/bpf: Add stacktrace test for kprobe_multi/kretprobe_multi
Signed-off-by: Jiri Olsa <[email protected]>
1 parent 803d10d commit a0f37f5

File tree

3 files changed

+140
-0
lines changed

3 files changed

+140
-0
lines changed

tools/testing/selftests/bpf/prog_tests/stacktrace_map.c

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,98 @@ static void test_stacktrace_map_tp(bool raw_tp)
7373
stacktrace_map__destroy(skel);
7474
}
7575

76+
static int check_stacktrace_ips(int fd, __u32 key, int cnt, ...)
77+
{
78+
__u64 ips[PERF_MAX_STACK_DEPTH];
79+
struct ksyms *ksyms = NULL;
80+
int i, err = 0;
81+
va_list args;
82+
83+
/* sorted by addr */
84+
ksyms = load_kallsyms_local();
85+
if (!ASSERT_OK_PTR(ksyms, "load_kallsyms_local"))
86+
return -1;
87+
88+
/* unlikely, but... */
89+
if (!ASSERT_LT(cnt, PERF_MAX_STACK_DEPTH, "check_max"))
90+
return -1;
91+
92+
err = bpf_map_lookup_elem(fd, &key, ips);
93+
if (err)
94+
goto out;
95+
96+
va_start(args, cnt);
97+
98+
for (i = 0; i < cnt; i++) {
99+
unsigned long val;
100+
struct ksym *ksym;
101+
102+
if (!ASSERT_NEQ(ips[i], 0, "ip_not_zero"))
103+
break;
104+
val = va_arg(args, unsigned long);
105+
ksym = ksym_search_local(ksyms, ips[i]);
106+
if (!ASSERT_OK_PTR(ksym, "ksym_search_local"))
107+
break;
108+
ASSERT_EQ(ksym->addr, val, "stack_cmp");
109+
}
110+
111+
va_end(args);
112+
113+
out:
114+
free_kallsyms_local(ksyms);
115+
return err;
116+
}
117+
118+
static void test_stacktrace_kprobe_multi(bool retprobe)
119+
{
120+
LIBBPF_OPTS(bpf_kprobe_multi_opts, opts,
121+
.retprobe = retprobe
122+
);
123+
LIBBPF_OPTS(bpf_test_run_opts, topts);
124+
struct stacktrace_map *skel;
125+
int prog_fd, err;
126+
127+
skel = stacktrace_map__open_and_load();
128+
if (!ASSERT_OK_PTR(skel, "stacktrace_map__open_and_load"))
129+
return;
130+
131+
skel->links.kprobe_multi_stack_test = bpf_program__attach_kprobe_multi_opts(
132+
skel->progs.kprobe_multi_stack_test,
133+
"bpf_testmod_stacktrace_test", &opts);
134+
if (!ASSERT_OK_PTR(skel->links.kprobe_multi_stack_test, "bpf_program__attach_kprobe_multi_opts"))
135+
goto cleanup;
136+
137+
prog_fd = bpf_program__fd(skel->progs.trigger);
138+
err = bpf_prog_test_run_opts(prog_fd, &topts);
139+
ASSERT_OK(err, "test_run");
140+
ASSERT_EQ(topts.retval, 0, "test_run");
141+
142+
trigger_module_test_read(1);
143+
144+
load_kallsyms();
145+
146+
check_stacktrace_ips(bpf_map__fd(skel->maps.stackmap), skel->bss->stack_key, 4,
147+
ksym_get_addr("bpf_testmod_stacktrace_test_4"),
148+
ksym_get_addr("bpf_testmod_stacktrace_test_3"),
149+
ksym_get_addr("bpf_testmod_stacktrace_test_2"),
150+
ksym_get_addr("bpf_testmod_stacktrace_test_1"));
151+
152+
cleanup:
153+
stacktrace_map__destroy(skel);
154+
}
155+
76156
void test_stacktrace_map(void)
77157
{
78158
if (test__start_subtest("tp"))
79159
test_stacktrace_map_tp(false);
80160
if (test__start_subtest("raw_tp"))
81161
test_stacktrace_map_tp(true);
82162
}
163+
164+
void test_stacktrace(void)
165+
{
166+
if (test__start_subtest("kprobe_multi"))
167+
test_stacktrace_kprobe_multi(false);
168+
if (test__start_subtest("kretprobe_multi"))
169+
test_stacktrace_kprobe_multi(true);
170+
}

tools/testing/selftests/bpf/progs/stacktrace_map.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <vmlinux.h>
55
#include <bpf/bpf_helpers.h>
6+
#include <bpf/bpf_tracing.h>
67

78
#ifndef PERF_MAX_STACK_DEPTH
89
#define PERF_MAX_STACK_DEPTH 127
@@ -92,4 +93,23 @@ int raw_tp(struct sched_switch_args *ctx)
9293
return 0;
9394
}
9495

96+
__u32 stack_key;
97+
98+
/*
99+
* No tests in here, just to trigger 'bpf_fentry_test*'
100+
* through tracing test_run.
101+
*/
102+
SEC("fentry/bpf_modify_return_test")
103+
int BPF_PROG(trigger)
104+
{
105+
return 0;
106+
}
107+
108+
SEC("kprobe.multi")
109+
int kprobe_multi_stack_test(struct pt_regs *ctx)
110+
{
111+
stack_key = bpf_get_stackid(ctx, &stackmap, 0);
112+
return 0;
113+
}
114+
95115
char _license[] SEC("license") = "GPL";

tools/testing/selftests/bpf/test_kmods/bpf_testmod.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -417,6 +417,36 @@ noinline int bpf_testmod_fentry_test11(u64 a, void *b, short c, int d,
417417
return a + (long)b + c + d + (long)e + f + g + h + i + j + k;
418418
}
419419

420+
noinline void bpf_testmod_stacktrace_test(void)
421+
{
422+
/* used for stacktrace test as attach function */
423+
asm volatile ("");
424+
}
425+
426+
noinline void bpf_testmod_stacktrace_test_4(void)
427+
{
428+
bpf_testmod_stacktrace_test();
429+
asm volatile ("");
430+
}
431+
432+
noinline void bpf_testmod_stacktrace_test_3(void)
433+
{
434+
bpf_testmod_stacktrace_test_4();
435+
asm volatile ("");
436+
}
437+
438+
noinline void bpf_testmod_stacktrace_test_2(void)
439+
{
440+
bpf_testmod_stacktrace_test_3();
441+
asm volatile ("");
442+
}
443+
444+
noinline void bpf_testmod_stacktrace_test_1(void)
445+
{
446+
bpf_testmod_stacktrace_test_2();
447+
asm volatile ("");
448+
}
449+
420450
int bpf_testmod_fentry_ok;
421451

422452
noinline ssize_t
@@ -497,6 +527,8 @@ bpf_testmod_test_read(struct file *file, struct kobject *kobj,
497527
21, 22, 23, 24, 25, 26) != 231)
498528
goto out;
499529

530+
bpf_testmod_stacktrace_test_1();
531+
500532
bpf_testmod_fentry_ok = 1;
501533
out:
502534
return -EIO; /* always fail */

0 commit comments

Comments
 (0)