From: Eugene Syromyatnikov Date: Mon, 5 Sep 2016 17:39:04 +0000 (+0300) Subject: tests: check decoding of perf_event_open syscall X-Git-Tag: v4.14~105 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=06d0a0eaa31fc190225b5d725a2a65c6ca00b72f;p=strace tests: check decoding of perf_event_open syscall * tests/perf_event_open.c: New file. * tests/perf_event_open.test: New test. * tests/.gitignore: Add perf_event_open. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add perf_event_open.test. --- diff --git a/tests/.gitignore b/tests/.gitignore index 8c41bea6..84a795d0 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -170,6 +170,7 @@ open openat pause pc +perf_event_open personality pipe poll diff --git a/tests/Makefile.am b/tests/Makefile.am index 0b3b818d..3e3d073e 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -227,6 +227,7 @@ check_PROGRAMS = \ openat \ pause \ pc \ + perf_event_open \ personality \ pipe \ poll \ @@ -555,6 +556,7 @@ DECODER_TESTS = \ open.test \ openat.test \ pause.test \ + perf_event_open.test \ personality.test \ pipe.test \ poll.test \ diff --git a/tests/perf_event_open.c b/tests/perf_event_open.c new file mode 100644 index 00000000..72f5d3ce --- /dev/null +++ b/tests/perf_event_open.c @@ -0,0 +1,113 @@ +/* + * Check decoding of perf_event_open syscall. + * + * Copyright (c) 2016 Eugene Syromiatnikov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "tests.h" +#include + +#if defined(__NR_perf_event_open) && defined(HAVE_LINUX_PERF_EVENT_H) + +# include +# include +# include + +# include + +# include "xlat.h" +# include "xlat/perf_event_open_flags.h" + +#if ULONG_MAX > UINT_MAX +#define LONG_STR_PREFIX "ffffffff" +#else +#define LONG_STR_PREFIX "" +#endif + +static const char *printaddr(void *ptr) +{ + static char buf[sizeof("0x") + sizeof(void *) * 2]; + + if (ptr == NULL) + return "NULL"; + + snprintf(buf, sizeof(buf), "%#lx", (unsigned long)ptr); + + return buf; +} + +int +main(void) +{ + struct perf_event_attr *attr = tail_alloc(sizeof(*attr)); + + attr->type = PERF_TYPE_HARDWARE; + attr->size = sizeof(*attr); + + struct { + struct perf_event_attr *attr; + pid_t pid; + int cpu; + int group_fd; + unsigned long flags; + const char *flags_str; + } args[] = { + { NULL, 0xfacef00d, 0xbadabba7, -1, + (unsigned long) 0xFFFFFFFFFFFFFFFFLLU, + "PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|" + "PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC|" + "0x" LONG_STR_PREFIX "fffffff0" + }, + { attr + 1, 0, 0, 0, + 0, "0" }, + { attr, -1, -1, 1, + PERF_FLAG_FD_CLOEXEC, "PERF_FLAG_FD_CLOEXEC" }, + { attr - 1, -100, 100, 0xface1e55, + PERF_FLAG_FD_NO_GROUP | PERF_FLAG_FD_OUTPUT | + PERF_FLAG_PID_CGROUP | PERF_FLAG_FD_CLOEXEC, + "PERF_FLAG_FD_NO_GROUP|PERF_FLAG_FD_OUTPUT|" + "PERF_FLAG_PID_CGROUP|PERF_FLAG_FD_CLOEXEC" }, + }; + size_t i; + int rc; + + for (i = 0; i < ARRAY_SIZE(args); i++) { + rc = syscall(__NR_perf_event_open, args[i].attr, args[i].pid, + args[i].cpu, args[i].group_fd, args[i].flags); + printf("perf_event_open(%s, %d, %d, %d, %s) = %s\n", + printaddr(args[i].attr), args[i].pid, args[i].cpu, + args[i].group_fd, args[i].flags_str, sprintrc(rc)); + } + + puts("+++ exited with 0 +++"); + return 0; +} + +#else + +SKIP_MAIN_UNDEFINED("__NR_perf_event_open && HAVE_LINUX_PERF_EVENT_H"); + +#endif diff --git a/tests/perf_event_open.test b/tests/perf_event_open.test new file mode 100755 index 00000000..0e46556a --- /dev/null +++ b/tests/perf_event_open.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check decoding of perf_event_open syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -a34