119 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright (c) 2024 Meta Platforms, Inc. and affiliates. */3#include <test_progs.h>4 5#include "test_build_id.skel.h"6 7static char build_id[BPF_BUILD_ID_SIZE];8static int build_id_sz;9 10static void print_stack(struct bpf_stack_build_id *stack, int frame_cnt)11{12 int i, j;13 14 for (i = 0; i < frame_cnt; i++) {15 printf("FRAME #%02d: ", i);16 switch (stack[i].status) {17 case BPF_STACK_BUILD_ID_EMPTY:18 printf("<EMPTY>\n");19 break;20 case BPF_STACK_BUILD_ID_VALID:21 printf("BUILD ID = ");22 for (j = 0; j < BPF_BUILD_ID_SIZE; j++)23 printf("%02hhx", (unsigned)stack[i].build_id[j]);24 printf(" OFFSET = %llx", (unsigned long long)stack[i].offset);25 break;26 case BPF_STACK_BUILD_ID_IP:27 printf("IP = %llx", (unsigned long long)stack[i].ip);28 break;29 default:30 printf("UNEXPECTED STATUS %d ", stack[i].status);31 break;32 }33 printf("\n");34 }35}36 37static void subtest_nofault(bool build_id_resident)38{39 struct test_build_id *skel;40 struct bpf_stack_build_id *stack;41 int frame_cnt;42 43 skel = test_build_id__open_and_load();44 if (!ASSERT_OK_PTR(skel, "skel_open"))45 return;46 47 skel->links.uprobe_nofault = bpf_program__attach(skel->progs.uprobe_nofault);48 if (!ASSERT_OK_PTR(skel->links.uprobe_nofault, "link"))49 goto cleanup;50 51 if (build_id_resident)52 ASSERT_OK(system("./uprobe_multi uprobe-paged-in"), "trigger_uprobe");53 else54 ASSERT_OK(system("./uprobe_multi uprobe-paged-out"), "trigger_uprobe");55 56 if (!ASSERT_GT(skel->bss->res_nofault, 0, "res"))57 goto cleanup;58 59 stack = skel->bss->stack_nofault;60 frame_cnt = skel->bss->res_nofault / sizeof(struct bpf_stack_build_id);61 if (env.verbosity >= VERBOSE_NORMAL)62 print_stack(stack, frame_cnt);63 64 if (build_id_resident) {65 ASSERT_EQ(stack[0].status, BPF_STACK_BUILD_ID_VALID, "build_id_status");66 ASSERT_EQ(memcmp(stack[0].build_id, build_id, build_id_sz), 0, "build_id_match");67 } else {68 ASSERT_EQ(stack[0].status, BPF_STACK_BUILD_ID_IP, "build_id_status");69 }70 71cleanup:72 test_build_id__destroy(skel);73}74 75static void subtest_sleepable(void)76{77 struct test_build_id *skel;78 struct bpf_stack_build_id *stack;79 int frame_cnt;80 81 skel = test_build_id__open_and_load();82 if (!ASSERT_OK_PTR(skel, "skel_open"))83 return;84 85 skel->links.uprobe_sleepable = bpf_program__attach(skel->progs.uprobe_sleepable);86 if (!ASSERT_OK_PTR(skel->links.uprobe_sleepable, "link"))87 goto cleanup;88 89 /* force build ID to not be paged in */90 ASSERT_OK(system("./uprobe_multi uprobe-paged-out"), "trigger_uprobe");91 92 if (!ASSERT_GT(skel->bss->res_sleepable, 0, "res"))93 goto cleanup;94 95 stack = skel->bss->stack_sleepable;96 frame_cnt = skel->bss->res_sleepable / sizeof(struct bpf_stack_build_id);97 if (env.verbosity >= VERBOSE_NORMAL)98 print_stack(stack, frame_cnt);99 100 ASSERT_EQ(stack[0].status, BPF_STACK_BUILD_ID_VALID, "build_id_status");101 ASSERT_EQ(memcmp(stack[0].build_id, build_id, build_id_sz), 0, "build_id_match");102 103cleanup:104 test_build_id__destroy(skel);105}106 107void serial_test_build_id(void)108{109 build_id_sz = read_build_id("uprobe_multi", build_id, sizeof(build_id));110 ASSERT_EQ(build_id_sz, BPF_BUILD_ID_SIZE, "parse_build_id");111 112 if (test__start_subtest("nofault-paged-out"))113 subtest_nofault(false /* not resident */);114 if (test__start_subtest("nofault-paged-in"))115 subtest_nofault(true /* resident */);116 if (test__start_subtest("sleepable"))117 subtest_sleepable();118}119