1#include "thread_map.h" 2#include "evsel.h" 3#include "debug.h" 4#include "tests.h" 5 6int test__openat_syscall_event(void) 7{ 8 int err = -1, fd; 9 struct perf_evsel *evsel; 10 unsigned int nr_openat_calls = 111, i; 11 struct thread_map *threads = thread_map__new(-1, getpid(), UINT_MAX); 12 char sbuf[STRERR_BUFSIZE]; 13 14 if (threads == NULL) { 15 pr_debug("thread_map__new\n"); 16 return -1; 17 } 18 19 evsel = perf_evsel__newtp("syscalls", "sys_enter_openat"); 20 if (evsel == NULL) { 21 if (tracefs_configured()) 22 pr_debug("is tracefs mounted on /sys/kernel/tracing?\n"); 23 else if (debugfs_configured()) 24 pr_debug("is debugfs mounted on /sys/kernel/debug?\n"); 25 else 26 pr_debug("Neither tracefs or debugfs is enabled in this kernel\n"); 27 goto out_thread_map_delete; 28 } 29 30 if (perf_evsel__open_per_thread(evsel, threads) < 0) { 31 pr_debug("failed to open counter: %s, " 32 "tweak /proc/sys/kernel/perf_event_paranoid?\n", 33 strerror_r(errno, sbuf, sizeof(sbuf))); 34 goto out_evsel_delete; 35 } 36 37 for (i = 0; i < nr_openat_calls; ++i) { 38 fd = openat(0, "/etc/passwd", O_RDONLY); 39 close(fd); 40 } 41 42 if (perf_evsel__read_on_cpu(evsel, 0, 0) < 0) { 43 pr_debug("perf_evsel__read_on_cpu\n"); 44 goto out_close_fd; 45 } 46 47 if (perf_counts(evsel->counts, 0, 0)->val != nr_openat_calls) { 48 pr_debug("perf_evsel__read_on_cpu: expected to intercept %d calls, got %" PRIu64 "\n", 49 nr_openat_calls, perf_counts(evsel->counts, 0, 0)->val); 50 goto out_close_fd; 51 } 52 53 err = 0; 54out_close_fd: 55 perf_evsel__close_fd(evsel, 1, threads->nr); 56out_evsel_delete: 57 perf_evsel__delete(evsel); 58out_thread_map_delete: 59 thread_map__put(threads); 60 return err; 61} 62