tools/testing/selftests/bpf/prog_tests/uretprobe_stack.c
Source file repositories/reference/linux-study-clean/tools/testing/selftests/bpf/prog_tests/uretprobe_stack.c
File Facts
- System
- Linux kernel
- Corpus path
tools/testing/selftests/bpf/prog_tests/uretprobe_stack.c- Extension
.c- Size
- 5791 bytes
- Lines
- 187
- Domain
- Support Tooling And Documentation
- Bucket
- tools
- Inferred role
- Support Tooling And Documentation: implementation source
- Status
- source implementation candidate
Why This File Exists
Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.
- Defines or uses C structs; map object ownership, embedded links, reference counts, and lock ownership.
Dependency Surface
test_progs.huretprobe_stack.skel.h../sdt.h
Detected Declarations
struct rangefunction target_4function target_3function target_2function target_1function validate_stackfunction test_uretprobe_stack
Annotated Snippet
struct range {
long start;
long stop;
};
static struct range targets[] = {
{}, /* we want target_1 to map to target[1], so need 1-based indexing */
{ (long)&__start_uprobe__target_1, (long)&__stop_uprobe__target_1 },
{ (long)&__start_uprobe__target_2, (long)&__stop_uprobe__target_2 },
{ (long)&__start_uprobe__target_3, (long)&__stop_uprobe__target_3 },
{ (long)&__start_uprobe__target_4, (long)&__stop_uprobe__target_4 },
};
static struct range caller = {
(long)&__start_uretprobe_stack_sec,
(long)&__stop_uretprobe_stack_sec,
};
static void validate_stack(__u64 *ips, int stack_len, int cnt, ...)
{
int i, j;
va_list args;
if (!ASSERT_GT(stack_len, 0, "stack_len"))
return;
stack_len /= 8;
/* check if we have enough entries to satisfy test expectations */
if (!ASSERT_GE(stack_len, cnt, "stack_len2"))
return;
if (env.verbosity >= VERBOSE_NORMAL) {
printf("caller: %#lx - %#lx\n", caller.start, caller.stop);
for (i = 1; i < ARRAY_SIZE(targets); i++)
printf("target_%d: %#lx - %#lx\n", i, targets[i].start, targets[i].stop);
for (i = 0; i < stack_len; i++) {
for (j = 1; j < ARRAY_SIZE(targets); j++) {
if (ips[i] >= targets[j].start && ips[i] < targets[j].stop)
break;
}
if (j < ARRAY_SIZE(targets)) { /* found target match */
printf("ENTRY #%d: %#lx (in target_%d)\n", i, (long)ips[i], j);
} else if (ips[i] >= caller.start && ips[i] < caller.stop) {
printf("ENTRY #%d: %#lx (in caller)\n", i, (long)ips[i]);
} else {
printf("ENTRY #%d: %#lx\n", i, (long)ips[i]);
}
}
}
va_start(args, cnt);
for (i = cnt - 1; i >= 0; i--) {
/* most recent entry is the deepest target function */
const struct range *t = va_arg(args, const struct range *);
ASSERT_GE(ips[i], t->start, "addr_start");
ASSERT_LT(ips[i], t->stop, "addr_stop");
}
va_end(args);
}
/* __weak prevents inlining */
__attribute__((section("uretprobe_stack_sec")))
__weak void test_uretprobe_stack(void)
{
LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts);
struct uretprobe_stack *skel;
int err;
skel = uretprobe_stack__open_and_load();
if (!ASSERT_OK_PTR(skel, "skel_open"))
return;
err = uretprobe_stack__attach(skel);
if (!ASSERT_OK(err, "skel_attach"))
goto cleanup;
/* trigger */
ASSERT_EQ(target_1(0), 42 + 1, "trigger_return");
/*
* Stacks captured on ENTRY uprobes
*/
/* (uprobe 1) target_1 in stack trace*/
validate_stack(skel->bss->entry_stack1, skel->bss->entry1_len,
2, &caller, &targets[1]);
Annotation
- Immediate include surface: `test_progs.h`, `uretprobe_stack.skel.h`, `../sdt.h`.
- Detected declarations: `struct range`, `function target_4`, `function target_3`, `function target_2`, `function target_1`, `function validate_stack`, `function test_uretprobe_stack`.
- Atlas domain: Support Tooling And Documentation / tools.
- Implementation status: source implementation candidate.
Implementation Notes
- This generated page is the file-by-file coverage layer; curated subsystem chapters should link here when they synthesize a multi-file control flow.
- Core OS pages should be promoted from atlas-only to deep-reviewed when they explain data structures, invariants, locking, lifecycle, and C implementation snippets.
- Driver-family pages are intentionally pattern-oriented unless they are part of the selected PCIe/NVMe representative device path.