Skip to content

Commit 198034a

Browse files
anakryikoAlexei Starovoitov
authored and
Alexei Starovoitov
committed
selftests/bpf: extend multi-uprobe tests with USDTs
Validate libbpf's USDT-over-multi-uprobe logic by adding USDTs to existing multi-uprobe tests. This checks correct libbpf fallback to singular uprobes (when run on older kernels with buggy PID filtering). We reuse already established child process and child thread testing infrastructure, so additions are minimal. These test fail on either older kernels or older version of libbpf that doesn't detect PID filtering problems. Acked-by: Jiri Olsa <[email protected]> Signed-off-by: Andrii Nakryiko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alexei Starovoitov <[email protected]>
1 parent 7034242 commit 198034a

File tree

2 files changed

+56
-2
lines changed

2 files changed

+56
-2
lines changed

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "uprobe_multi_usdt.skel.h"
99
#include "bpf/libbpf_internal.h"
1010
#include "testing_helpers.h"
11+
#include "../sdt.h"
1112

1213
static char test_data[] = "test_data";
1314

@@ -26,6 +27,11 @@ noinline void uprobe_multi_func_3(void)
2627
asm volatile ("");
2728
}
2829

30+
noinline void usdt_trigger(void)
31+
{
32+
STAP_PROBE(test, pid_filter_usdt);
33+
}
34+
2935
struct child {
3036
int go[2];
3137
int c2p[2]; /* child -> parent channel */
@@ -90,6 +96,7 @@ static struct child *spawn_child(void)
9096
uprobe_multi_func_1();
9197
uprobe_multi_func_2();
9298
uprobe_multi_func_3();
99+
usdt_trigger();
93100

94101
exit(errno);
95102
}
@@ -117,6 +124,7 @@ static void *child_thread(void *ctx)
117124
uprobe_multi_func_1();
118125
uprobe_multi_func_2();
119126
uprobe_multi_func_3();
127+
usdt_trigger();
120128

121129
err = 0;
122130
pthread_exit(&err);
@@ -182,6 +190,7 @@ static void uprobe_multi_test_run(struct uprobe_multi *skel, struct child *child
182190
uprobe_multi_func_1();
183191
uprobe_multi_func_2();
184192
uprobe_multi_func_3();
193+
usdt_trigger();
185194
}
186195

187196
if (child)
@@ -269,8 +278,24 @@ __test_attach_api(const char *binary, const char *pattern, struct bpf_uprobe_mul
269278
if (!ASSERT_OK_PTR(skel->links.uprobe_extra, "bpf_program__attach_uprobe_multi"))
270279
goto cleanup;
271280

281+
/* Attach (uprobe-backed) USDTs */
282+
skel->links.usdt_pid = bpf_program__attach_usdt(skel->progs.usdt_pid, pid, binary,
283+
"test", "pid_filter_usdt", NULL);
284+
if (!ASSERT_OK_PTR(skel->links.usdt_pid, "attach_usdt_pid"))
285+
goto cleanup;
286+
287+
skel->links.usdt_extra = bpf_program__attach_usdt(skel->progs.usdt_extra, -1, binary,
288+
"test", "pid_filter_usdt", NULL);
289+
if (!ASSERT_OK_PTR(skel->links.usdt_extra, "attach_usdt_extra"))
290+
goto cleanup;
291+
272292
uprobe_multi_test_run(skel, child);
273293

294+
ASSERT_FALSE(skel->bss->bad_pid_seen_usdt, "bad_pid_seen_usdt");
295+
if (child) {
296+
ASSERT_EQ(skel->bss->child_pid_usdt, child->pid, "usdt_multi_child_pid");
297+
ASSERT_EQ(skel->bss->child_tid_usdt, child->tid, "usdt_multi_child_tid");
298+
}
274299
cleanup:
275300
uprobe_multi__destroy(skel);
276301
}

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

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// SPDX-License-Identifier: GPL-2.0
2-
#include <linux/bpf.h>
2+
#include "vmlinux.h"
33
#include <bpf/bpf_helpers.h>
44
#include <bpf/bpf_tracing.h>
5-
#include <stdbool.h>
5+
#include <bpf/usdt.bpf.h>
66

77
char _license[] SEC("license") = "GPL";
88

@@ -23,9 +23,12 @@ __u64 uprobe_multi_sleep_result = 0;
2323
int pid = 0;
2424
int child_pid = 0;
2525
int child_tid = 0;
26+
int child_pid_usdt = 0;
27+
int child_tid_usdt = 0;
2628

2729
int expect_pid = 0;
2830
bool bad_pid_seen = false;
31+
bool bad_pid_seen_usdt = false;
2932

3033
bool test_cookie = false;
3134
void *user_ptr = 0;
@@ -112,3 +115,29 @@ int uprobe_extra(struct pt_regs *ctx)
112115
/* we need this one just to mix PID-filtered and global uprobes */
113116
return 0;
114117
}
118+
119+
SEC("usdt")
120+
int usdt_pid(struct pt_regs *ctx)
121+
{
122+
__u64 cur_pid_tgid = bpf_get_current_pid_tgid();
123+
__u32 cur_pid;
124+
125+
cur_pid = cur_pid_tgid >> 32;
126+
if (pid && cur_pid != pid)
127+
return 0;
128+
129+
if (expect_pid && cur_pid != expect_pid)
130+
bad_pid_seen_usdt = true;
131+
132+
child_pid_usdt = cur_pid_tgid >> 32;
133+
child_tid_usdt = (__u32)cur_pid_tgid;
134+
135+
return 0;
136+
}
137+
138+
SEC("usdt")
139+
int usdt_extra(struct pt_regs *ctx)
140+
{
141+
/* we need this one just to mix PID-filtered and global USDT probes */
142+
return 0;
143+
}

0 commit comments

Comments
 (0)