]> granicus.if.org Git - strace/blob - tests/perf_event_open_nonverbose.c
9cb432ca3e6ad87cc249e02ebdecf136c8903e39
[strace] / tests / perf_event_open_nonverbose.c
1 /*
2  * Check decoding of perf_event_open syscall.
3  *
4  * Copyright (c) 2016 Eugene Syromyatnikov <evgsyr@gmail.com>
5  * Copyright (c) 2016-2017 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: GPL-2.0-or-later
9  */
10
11 #include "tests.h"
12 #include <asm/unistd.h>
13
14 #if defined(__NR_perf_event_open) && defined(HAVE_LINUX_PERF_EVENT_H)
15
16 # include <limits.h>
17 # include <stdio.h>
18 # include <unistd.h>
19
20 # include <linux/perf_event.h>
21
22 # include "xlat.h"
23 # include "xlat/perf_event_open_flags.h"
24
25 #if ULONG_MAX > UINT_MAX
26 #define LONG_STR_PREFIX "ffffffff"
27 #else
28 #define LONG_STR_PREFIX ""
29 #endif
30
31 static const char *printaddr(void *ptr)
32 {
33         static char buf[sizeof("0x") + sizeof(void *) * 2];
34
35         if (ptr == NULL)
36                 return "NULL";
37
38         snprintf(buf, sizeof(buf), "%#lx", (unsigned long)ptr);
39
40         return buf;
41 }
42
43 int
44 main(void)
45 {
46         TAIL_ALLOC_OBJECT_CONST_PTR(struct perf_event_attr, attr);
47
48         attr->type = PERF_TYPE_HARDWARE;
49         attr->size = sizeof(*attr);
50
51         struct {
52                 struct perf_event_attr *attr;
53                 pid_t pid;
54                 int cpu;
55                 int group_fd;
56                 unsigned long flags;
57                 const char *flags_str;
58         } args[] = {
59                 { NULL,     0xfacef00d, 0xbadabba7, -1,
60                         (unsigned long) 0xFFFFFFFFFFFFFFFFLLU,
61                         "PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|"
62                         "PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC|"
63                         "0x" LONG_STR_PREFIX "fffffff0"
64                         },
65                 { attr + 1, 0,          0,          0,
66                         0, "0" },
67                 { attr,     -1,         -1,         1,
68                         PERF_FLAG_FD_CLOEXEC, "PERF_FLAG_FD_CLOEXEC" },
69                 { attr - 1, -100,       100,        0xface1e55,
70                         PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT |
71                         PERF_FLAG_PID_CGROUP | PERF_FLAG_FD_CLOEXEC,
72                         "PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|"
73                         "PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC" },
74         };
75         size_t i;
76         int rc;
77
78         for (i = 0; i < ARRAY_SIZE(args); i++) {
79                 rc = syscall(__NR_perf_event_open, args[i].attr, args[i].pid,
80                         args[i].cpu, args[i].group_fd, args[i].flags);
81                 printf("perf_event_open(%s, %d, %d, %d, %s) = %s\n",
82                         printaddr(args[i].attr), args[i].pid, args[i].cpu,
83                         args[i].group_fd, args[i].flags_str, sprintrc(rc));
84         }
85
86         puts("+++ exited with 0 +++");
87         return 0;
88 }
89
90 #else
91
92 SKIP_MAIN_UNDEFINED("__NR_perf_event_open && HAVE_LINUX_PERF_EVENT_H");
93
94 #endif