Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
mariux64
/
linux
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Issues
2
Pull requests
0
Actions
Projects
0
Wiki
Security
Insights
Additional navigation options
Code
Issues
Pull requests
Actions
Projects
Wiki
Security
Insights
Files
379d19e
Breadcrumbs
linux
/
tools
/
testing
/
selftests
/
bpf
/
prog_tests
/
stacktrace_build_id_nmi.c
Copy path
Blame
Blame
Latest commit
History
History
151 lines (129 loc) · 4.35 KB
Breadcrumbs
linux
/
tools
/
testing
/
selftests
/
bpf
/
prog_tests
/
stacktrace_build_id_nmi.c
Top
File metadata and controls
Code
Blame
151 lines (129 loc) · 4.35 KB
Raw
// SPDX-License-Identifier: GPL-2.0 #include <test_progs.h> #include "test_stacktrace_build_id.skel.h" static __u64 read_perf_max_sample_freq(void) { __u64 sample_freq = 5000; /* fallback to 5000 on error */ FILE *f; __u32 duration = 0; f = fopen("/proc/sys/kernel/perf_event_max_sample_rate", "r"); if (f == NULL) return sample_freq; CHECK(fscanf(f, "%llu", &sample_freq) != 1, "Get max sample rate", "return default value: 5000,err %d\n", -errno); fclose(f); return sample_freq; } void test_stacktrace_build_id_nmi(void) { int control_map_fd, stackid_hmap_fd, stackmap_fd; struct test_stacktrace_build_id *skel; int err, pmu_fd; struct perf_event_attr attr = { .freq = 1, .type = PERF_TYPE_HARDWARE, .config = PERF_COUNT_HW_CPU_CYCLES, }; __u32 key, previous_key, val, duration = 0; char buf[256]; int i, j; struct bpf_stack_build_id id_offs[PERF_MAX_STACK_DEPTH]; int build_id_matches = 0; int retry = 1; attr.sample_freq = read_perf_max_sample_freq(); retry: skel = test_stacktrace_build_id__open(); if (CHECK(!skel, "skel_open", "skeleton open failed\n")) return; /* override program type */ bpf_program__set_type(skel->progs.oncpu, BPF_PROG_TYPE_PERF_EVENT); err = test_stacktrace_build_id__load(skel); if (CHECK(err, "skel_load", "skeleton load failed: %d\n", err)) goto cleanup; pmu_fd = syscall(__NR_perf_event_open, &attr, -1 /* pid */, 0 /* cpu 0 */, -1 /* group id */, 0 /* flags */); if (pmu_fd < 0 && errno == ENOENT) { printf("%s:SKIP:no PERF_COUNT_HW_CPU_CYCLES\n", __func__); test__skip(); goto cleanup; } if (CHECK(pmu_fd < 0, "perf_event_open", "err %d errno %d\n", pmu_fd, errno)) goto cleanup; skel->links.oncpu = bpf_program__attach_perf_event(skel->progs.oncpu, pmu_fd); if (!ASSERT_OK_PTR(skel->links.oncpu, "attach_perf_event")) { close(pmu_fd); goto cleanup; } /* find map fds */ control_map_fd = bpf_map__fd(skel->maps.control_map); stackid_hmap_fd = bpf_map__fd(skel->maps.stackid_hmap); stackmap_fd = bpf_map__fd(skel->maps.stackmap); if (CHECK_FAIL(system("dd if=/dev/urandom of=/dev/zero count=4 2> /dev/null"))) goto cleanup; if (CHECK_FAIL(system("taskset 0x1 ./urandom_read 100000"))) goto cleanup; /* disable stack trace collection */ key = 0; val = 1; bpf_map_update_elem(control_map_fd, &key, &val, 0); /* for every element in stackid_hmap, we can find a corresponding one * in stackmap, and vise versa. */ err = compare_map_keys(stackid_hmap_fd, stackmap_fd); if (CHECK(err, "compare_map_keys stackid_hmap vs. stackmap", "err %d errno %d\n", err, errno)) goto cleanup; err = compare_map_keys(stackmap_fd, stackid_hmap_fd); if (CHECK(err, "compare_map_keys stackmap vs. stackid_hmap", "err %d errno %d\n", err, errno)) goto cleanup; err = extract_build_id(buf, 256); if (CHECK(err, "get build_id with readelf", "err %d errno %d\n", err, errno)) goto cleanup; err = bpf_map_get_next_key(stackmap_fd, NULL, &key); if (CHECK(err, "get_next_key from stackmap", "err %d, errno %d\n", err, errno)) goto cleanup; do { char build_id[64]; err = bpf_map_lookup_elem(stackmap_fd, &key, id_offs); if (CHECK(err, "lookup_elem from stackmap", "err %d, errno %d\n", err, errno)) goto cleanup; for (i = 0; i < PERF_MAX_STACK_DEPTH; ++i) if (id_offs[i].status == BPF_STACK_BUILD_ID_VALID && id_offs[i].offset != 0) { for (j = 0; j < 20; ++j) sprintf(build_id + 2 * j, "%02x", id_offs[i].build_id[j] & 0xff); if (strstr(buf, build_id) != NULL) build_id_matches = 1; } previous_key = key; } while (bpf_map_get_next_key(stackmap_fd, &previous_key, &key) == 0); /* stack_map_get_build_id_offset() is racy and sometimes can return * BPF_STACK_BUILD_ID_IP instead of BPF_STACK_BUILD_ID_VALID; * try it one more time. */ if (build_id_matches < 1 && retry--) { test_stacktrace_build_id__destroy(skel); printf("%s:WARN:Didn't find expected build ID from the map, retrying\n", __func__); goto retry; } if (CHECK(build_id_matches < 1, "build id match", "Didn't find expected build ID from the map\n")) goto cleanup; /* * We intentionally skip compare_stack_ips(). This is because we * only support one in_nmi() ips-to-build_id translation per cpu * at any time, thus stack_amap here will always fallback to * BPF_STACK_BUILD_ID_IP; */ cleanup: test_stacktrace_build_id__destroy(skel); }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
You can’t perform that action at this time.