diff options
Diffstat (limited to 'tools/perf')
-rw-r--r-- | tools/perf/builtin-test.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index e0c3f471f22d..6c991529f62b 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -234,6 +234,85 @@ out: | |||
234 | return err; | 234 | return err; |
235 | } | 235 | } |
236 | 236 | ||
237 | #include "util/evsel.h" | ||
238 | #include <sys/types.h> | ||
239 | |||
240 | static 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 | |||
262 | static 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("trace_event__id(\"sys_enter_open\") "); | ||
272 | return -1; | ||
273 | } | ||
274 | |||
275 | threads = thread_map__new(-1, getpid()); | ||
276 | if (threads == NULL) { | ||
277 | pr_debug("thread_map__new "); | ||
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 "); | ||
284 | goto out_thread_map_delete; | ||
285 | } | ||
286 | |||
287 | if (perf_evsel__open_per_thread(evsel, threads) < 0) { | ||
288 | pr_debug("perf_evsel__open_per_thread "); | ||
289 | goto out_evsel_delete; | ||
290 | } | ||
291 | |||
292 | for (i = 0; i < nr_open_calls; ++i) { | ||
293 | fd = open("/etc/passwd", O_RDONLY); | ||
294 | close(fd); | ||
295 | } | ||
296 | |||
297 | if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { | ||
298 | pr_debug("perf_evsel__open_read_on_cpu "); | ||
299 | goto out_close_fd; | ||
300 | } | ||
301 | |||
302 | if (evsel->counts->cpu[0].val != nr_open_calls) | ||
303 | pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %Ld ", | ||
304 | nr_open_calls, evsel->counts->cpu[0].val); | ||
305 | |||
306 | err = 0; | ||
307 | out_close_fd: | ||
308 | perf_evsel__close_fd(evsel, 1, threads->nr); | ||
309 | out_evsel_delete: | ||
310 | perf_evsel__delete(evsel); | ||
311 | out_thread_map_delete: | ||
312 | thread_map__delete(threads); | ||
313 | return err; | ||
314 | } | ||
315 | |||
237 | static struct test { | 316 | static struct test { |
238 | const char *desc; | 317 | const char *desc; |
239 | int (*func)(void); | 318 | int (*func)(void); |
@@ -243,6 +322,10 @@ static struct test { | |||
243 | .func = test__vmlinux_matches_kallsyms, | 322 | .func = test__vmlinux_matches_kallsyms, |
244 | }, | 323 | }, |
245 | { | 324 | { |
325 | .desc = "detect open syscall event", | ||
326 | .func = test__open_syscall_event, | ||
327 | }, | ||
328 | { | ||
246 | .func = NULL, | 329 | .func = NULL, |
247 | }, | 330 | }, |
248 | }; | 331 | }; |