aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/builtin-test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/builtin-test.c')
-rw-r--r--tools/perf/builtin-test.c110
1 files changed, 106 insertions, 4 deletions
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c
index 035b9fa063a..1c984342a57 100644
--- a/tools/perf/builtin-test.c
+++ b/tools/perf/builtin-test.c
@@ -119,10 +119,16 @@ static int test__vmlinux_matches_kallsyms(void)
119 * end addresses too. 119 * end addresses too.
120 */ 120 */
121 for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) { 121 for (nd = rb_first(&vmlinux_map->dso->symbols[type]); nd; nd = rb_next(nd)) {
122 struct symbol *pair; 122 struct symbol *pair, *first_pair;
123 bool backwards = true;
123 124
124 sym = rb_entry(nd, struct symbol, rb_node); 125 sym = rb_entry(nd, struct symbol, rb_node);
125 pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL); 126
127 if (sym->start == sym->end)
128 continue;
129
130 first_pair = machine__find_kernel_symbol(&kallsyms, type, sym->start, NULL, NULL);
131 pair = first_pair;
126 132
127 if (pair && pair->start == sym->start) { 133 if (pair && pair->start == sym->start) {
128next_pair: 134next_pair:
@@ -143,8 +149,10 @@ next_pair:
143 pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n", 149 pr_debug("%#Lx: diff end addr for %s v: %#Lx k: %#Lx\n",
144 sym->start, sym->name, sym->end, pair->end); 150 sym->start, sym->name, sym->end, pair->end);
145 } else { 151 } else {
146 struct rb_node *nnd = rb_prev(&pair->rb_node); 152 struct rb_node *nnd;
147 153detour:
154 nnd = backwards ? rb_prev(&pair->rb_node) :
155 rb_next(&pair->rb_node);
148 if (nnd) { 156 if (nnd) {
149 struct symbol *next = rb_entry(nnd, struct symbol, rb_node); 157 struct symbol *next = rb_entry(nnd, struct symbol, rb_node);
150 158
@@ -153,6 +161,13 @@ next_pair:
153 goto next_pair; 161 goto next_pair;
154 } 162 }
155 } 163 }
164
165 if (backwards) {
166 backwards = false;
167 pair = first_pair;
168 goto detour;
169 }
170
156 pr_debug("%#Lx: diff name v: %s k: %s\n", 171 pr_debug("%#Lx: diff name v: %s k: %s\n",
157 sym->start, sym->name, pair->name); 172 sym->start, sym->name, pair->name);
158 } 173 }
@@ -219,6 +234,89 @@ out:
219 return err; 234 return err;
220} 235}
221 236
237#include "util/evsel.h"
238#include <sys/types.h>
239
240static int trace_event__id(const char *event_name)
241{
242 char *filename;
243 int err = -1, fd;
244
245 if (asprintf(&filename,
246 "/sys/kernel/debug/tracing/events/syscalls/%s/id",
247 event_name) < 0)
248 return -1;
249
250 fd = open(filename, O_RDONLY);
251 if (fd >= 0) {
252 char id[16];
253 if (read(fd, id, sizeof(id)) > 0)
254 err = atoi(id);
255 close(fd);
256 }
257
258 free(filename);
259 return err;
260}
261
262static int test__open_syscall_event(void)
263{
264 int err = -1, fd;
265 struct thread_map *threads;
266 struct perf_evsel *evsel;
267 unsigned int nr_open_calls = 111, i;
268 int id = trace_event__id("sys_enter_open");
269
270 if (id < 0) {
271 pr_debug("is debugfs mounted on /sys/kernel/debug?\n");
272 return -1;
273 }
274
275 threads = thread_map__new(-1, getpid());
276 if (threads == NULL) {
277 pr_debug("thread_map__new\n");
278 return -1;
279 }
280
281 evsel = perf_evsel__new(PERF_TYPE_TRACEPOINT, id, 0);
282 if (evsel == NULL) {
283 pr_debug("perf_evsel__new\n");
284 goto out_thread_map_delete;
285 }
286
287 if (perf_evsel__open_per_thread(evsel, threads) < 0) {
288 pr_debug("failed to open counter: %s, "
289 "tweak /proc/sys/kernel/perf_event_paranoid?\n",
290 strerror(errno));
291 goto out_evsel_delete;
292 }
293
294 for (i = 0; i < nr_open_calls; ++i) {
295 fd = open("/etc/passwd", O_RDONLY);
296 close(fd);
297 }
298
299 if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) {
300 pr_debug("perf_evsel__open_read_on_cpu\n");
301 goto out_close_fd;
302 }
303
304 if (evsel->counts->cpu[0].val != nr_open_calls) {
305 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %Ld\n",
306 nr_open_calls, evsel->counts->cpu[0].val);
307 goto out_close_fd;
308 }
309
310 err = 0;
311out_close_fd:
312 perf_evsel__close_fd(evsel, 1, threads->nr);
313out_evsel_delete:
314 perf_evsel__delete(evsel);
315out_thread_map_delete:
316 thread_map__delete(threads);
317 return err;
318}
319
222static struct test { 320static struct test {
223 const char *desc; 321 const char *desc;
224 int (*func)(void); 322 int (*func)(void);
@@ -228,6 +326,10 @@ static struct test {
228 .func = test__vmlinux_matches_kallsyms, 326 .func = test__vmlinux_matches_kallsyms,
229 }, 327 },
230 { 328 {
329 .desc = "detect open syscall event",
330 .func = test__open_syscall_event,
331 },
332 {
231 .func = NULL, 333 .func = NULL,
232 }, 334 },
233}; 335};