Home | History | Annotate | Download | only in tests
      1 #include "perf.h"
      2 #include "evlist.h"
      3 #include "evsel.h"
      4 #include "thread_map.h"
      5 #include "tests.h"
      6 
      7 int test__syscall_open_tp_fields(void)
      8 {
      9 	struct perf_record_opts opts = {
     10 		.target = {
     11 			.uid = UINT_MAX,
     12 			.uses_mmap = true,
     13 		},
     14 		.no_delay   = true,
     15 		.freq	    = 1,
     16 		.mmap_pages = 256,
     17 		.raw_samples = true,
     18 	};
     19 	const char *filename = "/etc/passwd";
     20 	int flags = O_RDONLY | O_DIRECTORY;
     21 	struct perf_evlist *evlist = perf_evlist__new();
     22 	struct perf_evsel *evsel;
     23 	int err = -1, i, nr_events = 0, nr_polls = 0;
     24 
     25 	if (evlist == NULL) {
     26 		pr_debug("%s: perf_evlist__new\n", __func__);
     27 		goto out;
     28 	}
     29 
     30 	evsel = perf_evsel__newtp("syscalls", "sys_enter_open", 0);
     31 	if (evsel == NULL) {
     32 		pr_debug("%s: perf_evsel__newtp\n", __func__);
     33 		goto out_delete_evlist;
     34 	}
     35 
     36 	perf_evlist__add(evlist, evsel);
     37 
     38 	err = perf_evlist__create_maps(evlist, &opts.target);
     39 	if (err < 0) {
     40 		pr_debug("%s: perf_evlist__create_maps\n", __func__);
     41 		goto out_delete_evlist;
     42 	}
     43 
     44 	perf_evsel__config(evsel, &opts);
     45 
     46 	evlist->threads->map[0] = getpid();
     47 
     48 	err = perf_evlist__open(evlist);
     49 	if (err < 0) {
     50 		pr_debug("perf_evlist__open: %s\n", strerror(errno));
     51 		goto out_delete_maps;
     52 	}
     53 
     54 	err = perf_evlist__mmap(evlist, UINT_MAX, false);
     55 	if (err < 0) {
     56 		pr_debug("perf_evlist__mmap: %s\n", strerror(errno));
     57 		goto out_close_evlist;
     58 	}
     59 
     60 	perf_evlist__enable(evlist);
     61 
     62 	/*
     63 	 * Generate the event:
     64 	 */
     65 	open(filename, flags);
     66 
     67 	while (1) {
     68 		int before = nr_events;
     69 
     70 		for (i = 0; i < evlist->nr_mmaps; i++) {
     71 			union perf_event *event;
     72 
     73 			while ((event = perf_evlist__mmap_read(evlist, i)) != NULL) {
     74 				const u32 type = event->header.type;
     75 				int tp_flags;
     76 				struct perf_sample sample;
     77 
     78 				++nr_events;
     79 
     80 				if (type != PERF_RECORD_SAMPLE) {
     81 					perf_evlist__mmap_consume(evlist, i);
     82 					continue;
     83 				}
     84 
     85 				err = perf_evsel__parse_sample(evsel, event, &sample);
     86 				if (err) {
     87 					pr_err("Can't parse sample, err = %d\n", err);
     88 					goto out_munmap;
     89 				}
     90 
     91 				tp_flags = perf_evsel__intval(evsel, &sample, "flags");
     92 
     93 				if (flags != tp_flags) {
     94 					pr_debug("%s: Expected flags=%#x, got %#x\n",
     95 						 __func__, flags, tp_flags);
     96 					goto out_munmap;
     97 				}
     98 
     99 				goto out_ok;
    100 			}
    101 		}
    102 
    103 		if (nr_events == before)
    104 			poll(evlist->pollfd, evlist->nr_fds, 10);
    105 
    106 		if (++nr_polls > 5) {
    107 			pr_debug("%s: no events!\n", __func__);
    108 			goto out_munmap;
    109 		}
    110 	}
    111 out_ok:
    112 	err = 0;
    113 out_munmap:
    114 	perf_evlist__munmap(evlist);
    115 out_close_evlist:
    116 	perf_evlist__close(evlist);
    117 out_delete_maps:
    118 	perf_evlist__delete_maps(evlist);
    119 out_delete_evlist:
    120 	perf_evlist__delete(evlist);
    121 out:
    122 	return err;
    123 }
    124