Tests: select_poll_epoll: Add support for _time64
authorJérémie Galarneau <jeremie.galarneau@efficios.com>
Fri, 11 Nov 2022 22:35:12 +0000 (17:35 -0500)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Mon, 17 Apr 2023 20:36:38 +0000 (16:36 -0400)
Add support for the 64-bit time_t syscalls SYS_ppoll_time64
and SYS_pselect6_time64.

These syscalls exist on 32-bit platforms since the 5.1 kernel. 32-bit
platforms with a 64-bit time_t only have these and don't have the
original syscalls (such as 32-bit RISC-V).

In doing so, the original syscalls were renamed to add the `_time32`
suffix which causes the validation steps to fail.

This patch ensures that the 64-bit version of the pselect and ppoll
syscalls are called whenever they are available, allowing the tests to
succeed.

It also ensures that we don't attempt to use the 32-bit versions that
don't exist on newer 32-bit platforms like RISCV-32.

The test is also cleaned-up:

  - The *invalid_pointer, *invalid_fd, *ulong_max, and *buffer_overflow
    tests are identical except for the syscall(...) invocation. They are
    combined to share as much code as possible regardless of which
    syscalls the platform's ABI supports.

  - Harmonized test names between the test script and test application

  - Test names are printed when using the list option and used to launch
    a test (rather than a numeric id)

  - Allow the test application to print the list of supported tested
    syscalls

Fixes: https://github.com/lttng/lttng-tools/pull/162
Change-Id: I974f780022441fedfa45414d672092606e657cf6
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
tests/regression/kernel/select_poll_epoll.cpp
tests/regression/kernel/test_select_poll_epoll
tests/regression/kernel/validate_select_poll_epoll.py

index f4e947497123b7b5c8e02a32230ad8035e7df095..b6f0210d503d24a03bf9e50235019d4b37c718be 100644 (file)
@@ -16,6 +16,7 @@
 #include <common/compat/time.hpp>
 #include <common/error.hpp>
 
+#include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
 #include <poll.h>
@@ -55,35 +56,84 @@ static int wait_fd;
 int lttng_opt_quiet, lttng_opt_verbose, lttng_opt_mi;
 
 static void run_working_cases(FILE *validation_output_file);
-static void pselect_invalid_fd(FILE *validation_output_file);
 static void test_ppoll_big(FILE *validation_output_file);
-static void ppoll_fds_buffer_overflow(FILE *validation_output_file);
 static void pselect_invalid_pointer(FILE *validation_output_file);
+static void pselect_invalid_fd(FILE *validation_output_file);
 static void ppoll_fds_ulong_max(FILE *validation_output_file);
+static void ppoll_fds_buffer_overflow(FILE *validation_output_file);
 static void epoll_pwait_invalid_pointer(FILE *validation_output_file);
 static void epoll_pwait_int_max(FILE *validation_output_file);
 static void ppoll_concurrent_write(FILE *validation_output_file);
 static void epoll_pwait_concurrent_munmap(FILE *validation_output_file);
 
-using test_case_cb = void (*)(FILE *);
+typedef void (*test_case_cb)(FILE *output_file);
 
 namespace {
 const struct test_case {
        test_case_cb run;
        bool produces_validation_info;
        int timeout;
+       const char *name;
+       const char *description;
 } test_cases[] = {
-       { .run = run_working_cases, .produces_validation_info = true, .timeout = -1 },
-       { .run = run_working_cases, .produces_validation_info = true, .timeout = 1 },
-       { .run = pselect_invalid_fd, .produces_validation_info = false, .timeout = 0 },
-       { .run = test_ppoll_big, .produces_validation_info = false, .timeout = 0 },
-       { .run = ppoll_fds_buffer_overflow, .produces_validation_info = false, .timeout = 0 },
-       { .run = pselect_invalid_pointer, .produces_validation_info = false, .timeout = 0 },
-       { .run = ppoll_fds_ulong_max, .produces_validation_info = false, .timeout = 0 },
-       { .run = epoll_pwait_invalid_pointer, .produces_validation_info = true, .timeout = 0 },
-       { .run = epoll_pwait_int_max, .produces_validation_info = true, .timeout = 0 },
-       { .run = ppoll_concurrent_write, .produces_validation_info = false, .timeout = 0 },
-       { .run = epoll_pwait_concurrent_munmap, .produces_validation_info = true, .timeout = 0 },
+       { .run = run_working_cases,
+         .produces_validation_info = true,
+         .timeout = -1,
+         .name = "working_cases",
+         .description =
+                 "Working cases for select, pselect6, poll, ppoll and epoll, waiting for input" },
+       { .run = run_working_cases,
+         .produces_validation_info = true,
+         .timeout = 1,
+         .name = "working_cases_timeout",
+         .description = "Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll" },
+       { .run = test_ppoll_big,
+         .produces_validation_info = false,
+         .timeout = 0,
+         .name = "ppoll_big",
+         .description = "ppoll with " XSTR(MAX_FDS) " FDs" },
+       { .run = epoll_pwait_invalid_pointer,
+         .produces_validation_info = true,
+         .timeout = 0,
+         .name = "epoll_pwait_invalid_pointer",
+         .description = "epoll_pwait with an invalid pointer, waits for input" },
+       { .run = epoll_pwait_int_max,
+         .produces_validation_info = true,
+         .timeout = 0,
+         .name = "epoll_pwait_int_max",
+         .description = "epoll_pwait with maxevents set to INT_MAX waits for input" },
+       { .run = ppoll_concurrent_write,
+         .produces_validation_info = false,
+         .timeout = 0,
+         .name = "ppoll_concurrent_write",
+         .description =
+                 "ppoll with concurrent updates of the structure from user-space, stress test (3000 iterations) waits for input + timeout 1ms" },
+       { .run = epoll_pwait_concurrent_munmap,
+         .produces_validation_info = true,
+         .timeout = 0,
+         .name = "epoll_pwait_concurrent_munmap",
+         .description =
+                 "epoll_pwait with concurrent munmap of the buffer from user-space, should randomly segfault, run multiple times, waits for input + timeout 1ms" },
+       { .run = pselect_invalid_pointer,
+         .produces_validation_info = false,
+         .timeout = 0,
+         .name = "pselect_invalid_pointer",
+         .description = "pselect with an invalid pointer, waits for input" },
+       { .run = pselect_invalid_fd,
+         .produces_validation_info = false,
+         .timeout = 0,
+         .name = "pselect_invalid_fd",
+         .description = "pselect with an invalid fd" },
+       { .run = ppoll_fds_ulong_max,
+         .produces_validation_info = false,
+         .timeout = 0,
+         .name = "ppoll_fds_ulong_max",
+         .description = "ppoll with ulong_max fds, waits for input" },
+       { .run = ppoll_fds_buffer_overflow,
+         .produces_validation_info = false,
+         .timeout = 0,
+         .name = "ppoll_fds_buffer_overflow",
+         .description = "ppoll buffer overflow, should segfault, waits for input" },
 };
 
 struct ppoll_thread_data {
@@ -92,7 +142,7 @@ struct ppoll_thread_data {
 };
 } /* namespace */
 
-static void test_select_big()
+static void test_select_big(void)
 {
        fd_set rfds, wfds, exfds;
        struct timeval tv;
@@ -117,7 +167,7 @@ static void test_select_big()
        if (timeout > 0) {
                ret = select(fd2 + 1, &rfds, &wfds, &exfds, &tv);
        } else {
-               ret = select(fd2 + 1, &rfds, &wfds, &exfds, nullptr);
+               ret = select(fd2 + 1, &rfds, &wfds, &exfds, NULL);
        }
 
        if (ret == -1) {
@@ -138,7 +188,7 @@ end:
        return;
 }
 
-static void test_pselect()
+static void test_pselect_generic(long int syscall_id)
 {
        fd_set rfds;
        struct timespec tv;
@@ -152,9 +202,9 @@ static void test_pselect()
        tv.tv_nsec = timeout * MSEC_PER_NSEC;
 
        if (timeout > 0) {
-               ret = pselect(1, &rfds, nullptr, nullptr, &tv, nullptr);
+               ret = syscall(syscall_id, 1, &rfds, NULL, NULL, &tv, NULL);
        } else {
-               ret = pselect(1, &rfds, nullptr, nullptr, nullptr, nullptr);
+               ret = syscall(syscall_id, 1, &rfds, NULL, NULL, NULL, NULL);
        }
 
        if (ret == -1) {
@@ -167,7 +217,12 @@ static void test_pselect()
        }
 }
 
-static void test_select()
+static void test_pselect(void)
+{
+       test_pselect_generic(SYS_pselect6);
+}
+
+static void test_select(void)
 {
        fd_set rfds;
        struct timeval tv;
@@ -181,9 +236,9 @@ static void test_select()
        tv.tv_usec = timeout * MSEC_PER_USEC;
 
        if (timeout > 0) {
-               ret = select(1, &rfds, nullptr, nullptr, &tv);
+               ret = select(1, &rfds, NULL, NULL, &tv);
        } else {
-               ret = select(1, &rfds, nullptr, nullptr, nullptr);
+               ret = select(1, &rfds, NULL, NULL, NULL);
        }
 
        if (ret == -1) {
@@ -196,7 +251,7 @@ static void test_select()
        }
 }
 
-static void test_poll()
+static void test_poll(void)
 {
        struct pollfd ufds[NB_FD];
        char buf[BUF_SIZE];
@@ -217,7 +272,7 @@ static void test_poll()
        }
 }
 
-static void test_ppoll()
+static void test_ppoll_generic(long int syscall_id)
 {
        struct pollfd ufds[NB_FD];
        char buf[BUF_SIZE];
@@ -230,9 +285,9 @@ static void test_ppoll()
        if (timeout > 0) {
                ts.tv_sec = 0;
                ts.tv_nsec = timeout * MSEC_PER_NSEC;
-               ret = ppoll(ufds, 1, &ts, nullptr);
+               ret = syscall(syscall_id, ufds, 1, &ts, NULL);
        } else {
-               ret = ppoll(ufds, 1, nullptr, nullptr);
+               ret = syscall(syscall_id, ufds, 1, NULL, NULL);
        }
 
        if (ret < 0) {
@@ -245,6 +300,11 @@ static void test_ppoll()
        }
 }
 
+static void test_ppoll(void)
+{
+       test_ppoll_generic(SYS_ppoll);
+}
+
 static void test_ppoll_big(FILE *validation_output_file __attribute__((unused)))
 {
        struct pollfd ufds[MAX_FDS];
@@ -260,7 +320,7 @@ static void test_ppoll_big(FILE *validation_output_file __attribute__((unused)))
                ufds[i].events = POLLIN | POLLPRI;
        }
 
-       ret = ppoll(ufds, MAX_FDS, nullptr, nullptr);
+       ret = ppoll(ufds, MAX_FDS, NULL, NULL);
 
        if (ret < 0) {
                PERROR("ppoll");
@@ -358,9 +418,9 @@ static void test_epoll_pwait(FILE *validation_output_file)
        }
 
        if (timeout > 0) {
-               ret = epoll_pwait(epollfd, &epoll_event, 1, timeout, nullptr);
+               ret = epoll_pwait(epollfd, &epoll_event, 1, timeout, NULL);
        } else {
-               ret = epoll_pwait(epollfd, &epoll_event, 1, -1, nullptr);
+               ret = epoll_pwait(epollfd, &epoll_event, 1, -1, NULL);
        }
 
        if (ret == 1) {
@@ -400,12 +460,21 @@ static void run_working_cases(FILE *validation_output_file)
                wait_fd = pipe_fds[0];
        }
        test_select();
+#ifdef sys_pselect6_time64
+       test_pselect_time64();
+#else
        test_pselect();
+#endif /* sys_pselect6_time64 */
        test_select_big();
        test_poll();
        test_ppoll();
+#ifdef sys_ppoll_time64
+       test_ppoll_time64();
+#else
+       test_ppoll();
+#endif /* sys_ppoll_time64 */
 
-       ret = fprintf(validation_output_file, "{ \"pid\": %i", getpid());
+       ret = fprintf(validation_output_file, "{\"pid\": %i", getpid());
        if (ret < 0) {
                PERROR("Failed to write pid to test validation file");
                goto end;
@@ -436,11 +505,11 @@ end:
 }
 
 /*
- * Ask for 100 FDs in a buffer for allocated for only 1 FD, should
- * segfault (eventually with a "*** stack smashing detected ***" message).
- * The event should contain an array of 100 FDs filled with garbage.
+ * Ask for ULONG_MAX FDs in a buffer for allocated for only 1 FD, should
+ * cleanly fail with a "Invalid argument".
+ * The event should contain an empty array of FDs and overflow = 1.
  */
-static void ppoll_fds_buffer_overflow(FILE *validation_output_file __attribute__((unused)))
+static void generic_ppoll_fds_ulong_max(long int syscall_id)
 {
        struct pollfd ufds[NB_FD];
        char buf[BUF_SIZE];
@@ -449,24 +518,24 @@ static void ppoll_fds_buffer_overflow(FILE *validation_output_file __attribute__
        ufds[0].fd = wait_fd;
        ufds[0].events = POLLIN | POLLPRI;
 
-       ret = syscall(SYS_ppoll, ufds, 100, NULL, NULL);
-
+       /* ppoll and/or ppoll_time64 are used, depending on platform support. */
+       ret = syscall(syscall_id, ufds, ULONG_MAX, NULL, NULL);
        if (ret < 0) {
-               PERROR("ppoll");
+               /* Expected error. */
        } else if (ret > 0) {
                ret = read(wait_fd, buf, BUF_SIZE);
                if (ret < 0) {
-                       PERROR("[ppoll] read");
+                       PERROR("Failed to read from wait file descriptor");
                }
        }
 }
 
 /*
- * Ask for ULONG_MAX FDs in a buffer for allocated for only 1 FD, should
- * cleanly fail with a "Invalid argument".
- * The event should contain an empty array of FDs and overflow = 1.
+ * Ask for 100 FDs in a buffer for allocated for only 1 FD, should
+ * segfault (eventually with a "*** stack smashing detected ***" message).
+ * The event should contain an array of 100 FDs filled with garbage.
  */
-static void ppoll_fds_ulong_max(FILE *validation_output_file __attribute__((unused)))
+static void generic_ppoll_fds_buffer_overflow(long int syscall_id)
 {
        struct pollfd ufds[NB_FD];
        char buf[BUF_SIZE];
@@ -475,22 +544,41 @@ static void ppoll_fds_ulong_max(FILE *validation_output_file __attribute__((unus
        ufds[0].fd = wait_fd;
        ufds[0].events = POLLIN | POLLPRI;
 
-       ret = syscall(SYS_ppoll, ufds, ULONG_MAX, NULL, NULL);
+       /* ppoll and/or ppoll_time64 are used, depending on platform support. */
+       ret = syscall(syscall_id, ufds, 100, NULL, NULL);
        if (ret < 0) {
-               /* Expected error. */
+               PERROR("Failed to wait using ppoll/ppoll_time64");
        } else if (ret > 0) {
                ret = read(wait_fd, buf, BUF_SIZE);
                if (ret < 0) {
-                       PERROR("[ppoll] read");
+                       PERROR("Failed to read from wait file descriptor");
                }
        }
 }
 
+static void ppoll_fds_ulong_max(FILE *validation_output_file __attribute__((unused)))
+{
+#ifdef SYS_ppoll_time64
+       generic_ppoll_fds_ulong_max(SYS_ppoll_time64);
+#else
+       generic_ppoll_fds_ulong_max(SYS_ppoll);
+#endif /* SYS_ppoll_time64 */
+}
+
+static void ppoll_fds_buffer_overflow(FILE *validation_output_file __attribute__((unused)))
+{
+#ifdef SYS_ppoll_time64
+       generic_ppoll_fds_buffer_overflow(SYS_ppoll_time64);
+#else
+       generic_ppoll_fds_buffer_overflow(SYS_ppoll);
+#endif /* SYS_ppoll_time64 */
+}
+
 /*
  * Pass an invalid file descriptor to pselect6(). The syscall should return
  * -EBADF. The recorded event should contain a "ret = -EBADF (-9)".
  */
-static void pselect_invalid_fd(FILE *validation_output_file __attribute__((unused)))
+static void generic_invalid_fd(long int syscall_id)
 {
        fd_set rfds;
        int ret;
@@ -502,26 +590,26 @@ static void pselect_invalid_fd(FILE *validation_output_file __attribute__((unuse
         */
        fd = open("/dev/null", O_RDONLY);
        if (fd == -1) {
-               PERROR("open");
+               PERROR("Failed to open /dev/null");
                goto error;
        }
 
        ret = close(fd);
        if (ret == -1) {
-               PERROR("close");
+               PERROR("Failed to close /dev/null file descriptor");
                goto error;
        }
 
        FD_ZERO(&rfds);
        FD_SET(fd, &rfds);
 
-       ret = syscall(SYS_pselect6, fd + 1, &rfds, NULL, NULL, NULL, NULL);
+       ret = syscall(syscall_id, fd + 1, &rfds, NULL, NULL, NULL, NULL);
        if (ret == -1) {
                /* Expected error. */
        } else if (ret) {
                ret = read(wait_fd, buf, BUF_SIZE);
                if (ret < 0) {
-                       PERROR("[pselect] read");
+                       PERROR("Failed to read from wait file descriptor");
                }
        }
 error:
@@ -532,7 +620,7 @@ error:
  * Invalid pointer as writefds, should output a ppoll event
  * with 0 FDs.
  */
-static void pselect_invalid_pointer(FILE *validation_output_file __attribute__((unused)))
+static void generic_invalid_pointer(int syscall_id)
 {
        fd_set rfds;
        int ret;
@@ -542,17 +630,39 @@ static void pselect_invalid_pointer(FILE *validation_output_file __attribute__((
        FD_ZERO(&rfds);
        FD_SET(wait_fd, &rfds);
 
-       ret = syscall(SYS_pselect6, 1, &rfds, (fd_set *) invalid, NULL, NULL, NULL);
+       ret = syscall(syscall_id, 1, &rfds, (fd_set *) invalid, NULL, NULL, NULL);
        if (ret == -1) {
                /* Expected error. */
        } else if (ret) {
                ret = read(wait_fd, buf, BUF_SIZE);
                if (ret < 0) {
-                       PERROR("[pselect] read");
+                       PERROR("Failed to read from wait file descriptor");
                }
        }
 }
 
+static void pselect_invalid_fd(FILE *validation_output_file __attribute__((unused)))
+{
+#ifdef SYS_pselect6_time64
+       generic_invalid_fd(SYS_pselect6_time64);
+#else
+       generic_invalid_fd(SYS_pselect6);
+#endif /* SYS_pselect6_time64 */
+}
+
+/*
+ * Invalid pointer as writefds, should output a ppoll event
+ * with 0 FDs.
+ */
+static void pselect_invalid_pointer(FILE *validation_output_file __attribute__((unused)))
+{
+#ifdef SYS_pselect6_time64
+       generic_invalid_pointer(SYS_pselect6_time64);
+#else
+       generic_invalid_pointer(SYS_pselect6);
+#endif /* SYS_pselect6_time64 */
+}
+
 /*
  * Pass an invalid pointer to epoll_pwait, should fail with
  * "Bad address", the event returns 0 FDs.
@@ -570,8 +680,7 @@ static void epoll_pwait_invalid_pointer(FILE *validation_output_file)
                goto end;
        }
 
-       ret = fprintf(
-               validation_output_file, "{ \"epollfd\": %i, \"pid\": %i }", epollfd, getpid());
+       ret = fprintf(validation_output_file, "{\"epollfd\": %i, \"pid\": %i }", epollfd, getpid());
        if (ret < 0) {
                PERROR("[epoll_pwait] Failed to write test validation output");
                goto error;
@@ -621,8 +730,7 @@ static void epoll_pwait_int_max(FILE *validation_output_file)
                goto end;
        }
 
-       ret = fprintf(
-               validation_output_file, "{ \"epollfd\": %i, \"pid\": %i }", epollfd, getpid());
+       ret = fprintf(validation_output_file, "{\"epollfd\": %i, \"pid\": %i }", epollfd, getpid());
        if (ret < 0) {
                PERROR("[epoll_pwait] Failed to write test validation output");
                goto error;
@@ -665,7 +773,7 @@ static void *ppoll_writer(void *arg)
                usleep(100);
        }
 
-       return nullptr;
+       return NULL;
 }
 
 static void do_ppoll(int *fds, struct pollfd *ufds)
@@ -682,7 +790,7 @@ static void do_ppoll(int *fds, struct pollfd *ufds)
                ufds[i].events = POLLIN | POLLPRI;
        }
 
-       ret = ppoll(ufds, MAX_FDS, &ts, nullptr);
+       ret = ppoll(ufds, MAX_FDS, &ts, NULL);
 
        if (ret < 0) {
                PERROR("ppoll");
@@ -705,7 +813,7 @@ static void stress_ppoll(int *fds, int value)
        thread_data.value = value;
 
        stop_thread = 0;
-       ret = pthread_create(&writer, nullptr, &ppoll_writer, (void *) &thread_data);
+       ret = pthread_create(&writer, NULL, &ppoll_writer, (void *) &thread_data);
        if (ret != 0) {
                fprintf(stderr, "[error] pthread_create\n");
                goto end;
@@ -714,7 +822,7 @@ static void stress_ppoll(int *fds, int value)
                do_ppoll(fds, ufds);
        }
        stop_thread = 1;
-       ret = pthread_join(writer, nullptr);
+       ret = pthread_join(writer, NULL);
        if (ret) {
                fprintf(stderr, "[error] pthread_join\n");
                goto end;
@@ -762,14 +870,14 @@ static void ppoll_concurrent_write(FILE *validation_output_file __attribute__((u
 
 static void *epoll_pwait_writer(void *addr)
 {
-       srand(time(nullptr));
+       srand(time(NULL));
 
        while (!stop_thread) {
                usleep(rand() % 30);
                munmap(addr, MAX_FDS * sizeof(struct epoll_event));
        }
 
-       return nullptr;
+       return NULL;
 }
 
 /*
@@ -793,14 +901,13 @@ static void epoll_pwait_concurrent_munmap(FILE *validation_output_file)
                goto end;
        }
 
-       ret = fprintf(
-               validation_output_file, "{ \"epollfd\": %i, \"pid\": %i }", epollfd, getpid());
+       ret = fprintf(validation_output_file, "{\"epollfd\": %i, \"pid\": %i }", epollfd, getpid());
        if (ret < 0) {
                PERROR("[epoll_pwait] Failed to write test validation output");
                goto error;
        }
 
-       epoll_event = (struct epoll_event *) mmap(nullptr,
+       epoll_event = (struct epoll_event *) mmap(NULL,
                                                  MAX_FDS * sizeof(struct epoll_event),
                                                  PROT_READ | PROT_WRITE,
                                                  MAP_PRIVATE | MAP_ANONYMOUS,
@@ -825,13 +932,13 @@ static void epoll_pwait_concurrent_munmap(FILE *validation_output_file)
                }
        }
        stop_thread = 0;
-       ret = pthread_create(&writer, nullptr, &epoll_pwait_writer, (void *) epoll_event);
+       ret = pthread_create(&writer, NULL, &epoll_pwait_writer, (void *) epoll_event);
        if (ret != 0) {
                fprintf(stderr, "[error] pthread_create\n");
                goto error_unmap;
        }
 
-       ret = epoll_pwait(epollfd, epoll_event, 1, 1, nullptr);
+       ret = epoll_pwait(epollfd, epoll_event, 1, 1, NULL);
 
        if (ret == 1) {
                ret = read(wait_fd, buf, BUF_SIZE);
@@ -843,7 +950,7 @@ static void epoll_pwait_concurrent_munmap(FILE *validation_output_file)
        }
 
        stop_thread = 1;
-       ret = pthread_join(writer, nullptr);
+       ret = pthread_join(writer, NULL);
        if (ret) {
                fprintf(stderr, "[error] pthread_join\n");
                goto error_unmap;
@@ -870,62 +977,87 @@ end:
        return;
 }
 
-static void print_list()
+static void print_list(void)
+{
+       printf("Test list (-t X):\n");
+
+       for (size_t test_id = 0; test_id < ARRAY_SIZE(test_cases); test_id++) {
+               printf("\t%zu: %s - %s\n",
+                      test_id + 1,
+                      test_cases[test_id].name,
+                      test_cases[test_id].description);
+       }
+}
+
+static void print_test_syscalls(void)
 {
-       fprintf(stderr, "Test list (-t X):\n");
-       fprintf(stderr,
-               "\t1: Working cases for select, pselect6, poll, ppoll "
-               "and epoll, waiting for input\n");
-       fprintf(stderr,
-               "\t2: Timeout cases (1ms) for select, pselect6, poll, "
-               "ppoll and epoll\n");
-       fprintf(stderr, "\t3: pselect with an invalid fd\n");
-       fprintf(stderr, "\t4: ppoll with %d FDs\n", MAX_FDS);
-       fprintf(stderr,
-               "\t5: ppoll buffer overflow, should segfault, waits "
-               "for input\n");
-       fprintf(stderr,
-               "\t6: pselect with an invalid pointer, waits for "
-               "input\n");
-       fprintf(stderr, "\t7: ppoll with ulong_max fds, waits for input\n");
-       fprintf(stderr,
-               "\t8: epoll_pwait with an invalid pointer, waits for "
-               "input\n");
-       fprintf(stderr,
-               "\t9: epoll_pwait with maxevents set to INT_MAX, "
-               "waits for input\n");
-       fprintf(stderr,
-               "\t10: ppoll with concurrent updates of the structure "
-               "from user-space, stress test (3000 iterations), "
-               "waits for input + timeout 1ms\n");
-       fprintf(stderr,
-               "\t11: epoll_pwait with concurrent munmap of the buffer "
-               "from user-space, should randomly segfault, run "
-               "multiple times, waits for input + timeout 1ms\n");
+       const char *supported_syscalls[] = {
+#ifdef SYS_select
+               "select",
+#endif
+#if defined SYS_pselect6_time64 && defined SYS_pselect6
+               "pselect6",
+               "pselect6_time32",
+#elif defined SYS_pselect6_time32 ^ defined SYS_pselect6
+               "pselect6",
+#endif /* SYS_pselect6_time64 && defined SYS_pselect6 */
+#ifdef SYS_poll
+               "poll",
+#endif
+#if defined SYS_ppoll && defined SYS_ppoll_time64
+               "ppoll",
+               "ppoll_time32",
+#elif defined SYS_ppoll ^ defined SYS_ppoll_time64
+               "ppoll",
+#endif /* defined SYS_ppoll && defined SYS_ppoll_time64 */
+#ifdef SYS_epoll_ctl
+               "epoll_ctl",
+#endif
+#ifdef SYS_epoll_wait
+               "epoll_wait",
+#endif
+#ifdef SYS_epoll_pwait
+               "epoll_pwait",
+#endif
+       };
+
+       for (size_t i = 0; i < ARRAY_SIZE(supported_syscalls); i++) {
+               fputs(supported_syscalls[i], stdout);
+               fputs(i != ARRAY_SIZE(supported_syscalls) - 1 ? "," : "\n", stdout);
+       }
 }
 
 int main(int argc, const char **argv)
 {
-       int c, ret, test = -1;
+       int c, ret;
+       const char *test_name;
        poptContext optCon;
        struct rlimit open_lim;
-       FILE *test_validation_output_file = nullptr;
-       const char *test_validation_output_file_path = nullptr;
+       FILE *test_validation_output_file = NULL;
+       const char *test_validation_output_file_path = NULL;
        struct poptOption optionsTable[] = {
-               { "test", 't', POPT_ARG_INT, &test, 0, "Test to run", nullptr },
-               { "list", 'l', 0, nullptr, 'l', "List of tests (-t X)", nullptr },
+               { "test", 't', POPT_ARG_STRING, &test_name, 0, "Name of test to run", NULL },
+               { "list-tests", 'l', 0, 0, 'l', "List tests (-t X)", NULL },
+               { "list-supported-test-syscalls",
+                 's',
+                 0,
+                 0,
+                 's',
+                 "List supported test syscalls",
+                 NULL },
                { "validation-file",
                  'o',
                  POPT_ARG_STRING,
                  &test_validation_output_file_path,
                  0,
                  "Test case output",
-                 nullptr },
-               POPT_AUTOHELP{ nullptr, 0, 0, nullptr, 0, nullptr, nullptr }
+                 NULL },
+               POPT_AUTOHELP{ NULL, 0, 0, NULL, 0, NULL, NULL }
        };
        const struct test_case *test_case;
+       size_t test_case_id;
 
-       optCon = poptGetContext(nullptr, argc, argv, optionsTable, 0);
+       optCon = poptGetContext(NULL, argc, argv, optionsTable, 0);
 
        if (argc < 2) {
                poptPrintUsage(optCon, stderr, 0);
@@ -940,6 +1072,9 @@ int main(int argc, const char **argv)
                case 'l':
                        print_list();
                        goto end;
+               case 's':
+                       print_test_syscalls();
+                       goto end;
                }
        }
 
@@ -971,16 +1106,23 @@ int main(int argc, const char **argv)
         * for the validation, disabling the buffering on the validation file
         * works.
         */
-       setbuf(test_validation_output_file, nullptr);
+       setbuf(test_validation_output_file, NULL);
        wait_fd = STDIN_FILENO;
 
        /* Test case id is 1-based. */
-       if (test < 1 || test > ARRAY_SIZE(test_cases)) {
+       for (test_case_id = 0; test_case_id < ARRAY_SIZE(test_cases); test_case_id++) {
+               if (!strcmp(test_cases[test_case_id].name, test_name)) {
+                       break;
+               }
+       }
+
+       if (test_case_id == ARRAY_SIZE(test_cases)) {
                poptPrintUsage(optCon, stderr, 0);
                ret = -1;
+               goto end;
        }
 
-       test_case = &test_cases[test - 1];
+       test_case = &test_cases[test_case_id];
 
        timeout = test_case->timeout;
        if (!test_case->produces_validation_info) {
@@ -988,7 +1130,7 @@ int main(int argc, const char **argv)
                 * All test cases need to provide, at minimum, the pid of the
                 * test application.
                 */
-               ret = fprintf(test_validation_output_file, "{ \"pid\": %i }", getpid());
+               ret = fprintf(test_validation_output_file, "{\"pid\": %i }", getpid());
                if (ret < 0) {
                        PERROR("Failed to write application pid to test validation file");
                        goto end;
index db4ffae88734bea21b246dd8962c5fb26823f9a3..cdde1ea4f04c281eef142fe4466d6f93e31b9e6b 100755 (executable)
@@ -10,7 +10,6 @@ TEST_DESC="Kernel tracer - select, poll and epoll payload extraction"
 CURDIR=$(dirname "$0")/
 TESTDIR=$CURDIR/../..
 VALIDATE_SCRIPT="$CURDIR/validate_select_poll_epoll.py"
-NUM_TESTS=102
 
 DISABLE_VALIDATE=0
 # Babeltrace python bindings are required for the validation, but
@@ -27,6 +26,12 @@ LAST_WARNING=$(dmesg | grep " WARNING:" | cut -d' ' -f1 | tail -1)
 LAST_OOPS=$(dmesg | grep " OOPS:" | cut -d' ' -f1 | tail -1)
 LAST_BUG=$(dmesg | grep " BUG:" | cut -d' ' -f1 | tail -1)
 
+SUPPORTED_SYSCALLS_LIST=$("$CURDIR"/select_poll_epoll --list-supported-test-syscalls)
+SUPPORTED_SYSCALLS_COUNT=$(echo $SUPPORTED_SYSCALLS_LIST | awk -F '[\t,]' '{print NF}')
+
+# Two tests validate their trace for every supported syscall
+NUM_TESTS=$((88+(2*SUPPORTED_SYSCALLS_COUNT)))
+
 # shellcheck source=../../utils/utils.sh
 source $TESTDIR/utils/utils.sh
 
@@ -51,27 +56,19 @@ function test_working_cases()
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
-       # arm64 does not have epoll_wait
-       uname -m | grep -E "aarch64" >/dev/null 2>&1
-       if test $? = 0; then
-               SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
-       else
-               SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
-       fi
-
        diag "Working cases for select, pselect6, poll, ppoll and epoll, waiting for input"
 
        create_lttng_session_ok $SESSION_NAME "$TRACE_PATH"
 
-       lttng_enable_kernel_syscall_ok $SESSION_NAME $SYSCALL_LIST
+       lttng_enable_kernel_syscall_ok $SESSION_NAME $SUPPORTED_SYSCALLS_LIST
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 1
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t working_cases
        stop_lttng_tracing_ok
 
-       validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 1 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH"
+       validate_trace "$SUPPORTED_SYSCALLS_LIST" "$TRACE_PATH"
+       check_trace_content -t working_cases --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH"
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -85,27 +82,19 @@ function test_timeout_cases()
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
-       # arm64 does not have epoll_wait
-       uname -m | grep -E "aarch64" >/dev/null 2>&1
-       if test $? = 0; then
-               SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_pwait"
-       else
-               SYSCALL_LIST="select,pselect6,poll,ppoll,epoll_ctl,epoll_wait,epoll_pwait"
-       fi
-
        diag "Timeout cases (1ms) for select, pselect6, poll, ppoll and epoll"
 
        create_lttng_session_ok $SESSION_NAME "$TRACE_PATH"
 
-       lttng_enable_kernel_syscall_ok $SESSION_NAME "$SYSCALL_LIST"
+       lttng_enable_kernel_syscall_ok $SESSION_NAME "$SUPPORTED_SYSCALLS_LIST"
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 2
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t working_cases_timeout
        stop_lttng_tracing_ok
 
-       validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 2 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       validate_trace "$SUPPORTED_SYSCALLS_LIST" "$TRACE_PATH"
+       check_trace_content -t working_cases_timeout --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -116,7 +105,7 @@ function test_timeout_cases()
 function test_pselect_invalid_fd()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="pselect6"
+       local SYSCALL_LIST="pselect6"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -128,11 +117,11 @@ function test_pselect_invalid_fd()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 3
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t pselect_invalid_fd
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 3 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t pselect_invalid_fd --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -140,10 +129,10 @@ function test_pselect_invalid_fd()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_big_ppoll()
+function test_ppoll_big()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="ppoll"
+       local SYSCALL_LIST="ppoll"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -155,11 +144,11 @@ function test_big_ppoll()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 4
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_big
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 4 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t ppoll_big --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -167,10 +156,10 @@ function test_big_ppoll()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_ppoll_overflow()
+function test_ppoll_fds_buffer_overflow()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="ppoll"
+       local SYSCALL_LIST="ppoll"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -183,12 +172,12 @@ function test_ppoll_overflow()
 
        start_lttng_tracing_ok
        diag "Expect segfaults"
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 5
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_fds_buffer_overflow
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
 
-       check_trace_content -t 5 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t ppoll_fds_buffer_overflow --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -196,10 +185,10 @@ function test_ppoll_overflow()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_pselect_invalid_ptr()
+function test_pselect_invalid_pointer()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="pselect6"
+       local SYSCALL_LIST="pselect6"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -211,11 +200,11 @@ function test_pselect_invalid_ptr()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 6
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t pselect_invalid_pointer
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 6 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t pselect_invalid_pointer --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -223,10 +212,10 @@ function test_pselect_invalid_ptr()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_ppoll_ulong_max()
+function test_ppoll_fds_ulong_max()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="ppoll"
+       local SYSCALL_LIST="ppoll"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -238,11 +227,11 @@ function test_ppoll_ulong_max()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 7
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_fds_ulong_max
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 7 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t ppoll_fds_ulong_max --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -250,10 +239,10 @@ function test_ppoll_ulong_max()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_epoll_pwait_invalid_ptr()
+function test_epoll_pwait_invalid_pointer()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="epoll_pwait"
+       local SYSCALL_LIST="epoll_pwait"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -265,11 +254,11 @@ function test_epoll_pwait_invalid_ptr()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 8
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t epoll_pwait_invalid_pointer
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 8 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t epoll_pwait_invalid_pointer --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -277,10 +266,10 @@ function test_epoll_pwait_invalid_ptr()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_epoll_pwait_int_max()
+function test_epoll_pwait_fds_int_max()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="epoll_pwait"
+       local SYSCALL_LIST="epoll_pwait"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -292,11 +281,11 @@ function test_epoll_pwait_int_max()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 9
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t epoll_pwait_int_max
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 9 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t epoll_pwait_int_max --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -304,10 +293,10 @@ function test_epoll_pwait_int_max()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_ppoll_concurrent()
+function test_ppoll_concurrent_write()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="ppoll"
+       local SYSCALL_LIST="ppoll"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -319,11 +308,11 @@ function test_ppoll_concurrent()
        add_context_kernel_ok $SESSION_NAME channel0 pid
 
        start_lttng_tracing_ok
-       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 10
+       yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t ppoll_concurrent_write
        stop_lttng_tracing_ok
 
        validate_trace "$SYSCALL_LIST" "$TRACE_PATH"
-       check_trace_content -t 10 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t ppoll_concurrent_write --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -331,10 +320,10 @@ function test_ppoll_concurrent()
        rm -f "$TEST_VALIDATION_OUTPUT_PATH"
 }
 
-function test_epoll_pwait_concurrent()
+function test_epoll_pwait_concurrent_unmap()
 {
        SESSION_NAME="syscall_payload"
-       SYSCALL_LIST="epoll_ctl,epoll_pwait"
+       local SYSCALL_LIST="epoll_ctl,epoll_pwait"
        TRACE_PATH=$(mktemp -d -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_trace_path.XXXXXX")
        TEST_VALIDATION_OUTPUT_PATH=$(mktemp -u -t "tmp.test_kernel_select_poll_epoll_${FUNCNAME[0]}_validation.XXXXXX")
 
@@ -348,13 +337,13 @@ function test_epoll_pwait_concurrent()
        start_lttng_tracing_ok
        diag "Expect segfaults"
        for i in $(seq 1 100); do
-               yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t 11
+               yes | "$CURDIR"/select_poll_epoll --validation-file "$TEST_VALIDATION_OUTPUT_PATH" -t epoll_pwait_concurrent_munmap
        done
        stop_lttng_tracing_ok
 
        # epoll_wait is not always generated in the trace (stress test)
        validate_trace "epoll_ctl" "$TRACE_PATH"
-       check_trace_content -t 11 --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
+       check_trace_content -t epoll_pwait_concurrent_munmap --validation-file "$TEST_VALIDATION_OUTPUT_PATH" "$TRACE_PATH" 2>/dev/null
 
        destroy_lttng_session_ok $SESSION_NAME
 
@@ -380,6 +369,8 @@ else
        isroot=0
 fi
 
+diag "Supported syscalls are $SUPPORTED_SYSCALLS_LIST"
+
 skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
 {
        validate_lttng_modules_present
@@ -389,14 +380,14 @@ skip $isroot "Root access is needed. Skipping all tests." $NUM_TESTS ||
        test_working_cases
        test_timeout_cases
        test_pselect_invalid_fd
-       test_big_ppoll
-       test_ppoll_overflow
-       test_pselect_invalid_ptr
-       test_ppoll_ulong_max
-       test_epoll_pwait_invalid_ptr
-       test_epoll_pwait_int_max
-       test_ppoll_concurrent
-       test_epoll_pwait_concurrent
+       test_ppoll_big
+       test_ppoll_fds_buffer_overflow
+       test_pselect_invalid_pointer
+       test_ppoll_fds_ulong_max
+       test_epoll_pwait_invalid_pointer
+       test_epoll_pwait_fds_int_max
+       test_ppoll_concurrent_write
+       test_epoll_pwait_concurrent_unmap
 
        stop_lttng_sessiond
 
index 97c7764c0a9fbb4975539a20d159e490271e7912..7340280c72b806d050c206ad6b585918085f2bd3 100755 (executable)
@@ -228,7 +228,7 @@ class TraceParser:
         pass
 
 
-class Test1(TraceParser):
+class WorkingCases(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
 
@@ -403,7 +403,7 @@ class Test1(TraceParser):
         # Save values of local variables to print in case of test failure
         self.recorded_values["epoll_pwait_exit"] = locals()
 
-class Test2(TraceParser):
+class WorkingCasesTimeout(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
         self.expect["select_entry"]["select_timeout_in_fd0"] = 0
@@ -515,7 +515,7 @@ class Test2(TraceParser):
         self.recorded_values["epoll_wait_exit"] = locals()
 
 
-class Test3(TraceParser):
+class PselectInvalidFd(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
         self.expect["select_entry"]["select_invalid_fd_in"] = 0
@@ -544,7 +544,7 @@ class Test3(TraceParser):
         self.recorded_values["select_exit"] = locals()
 
 
-class Test4(TraceParser):
+class PpollBig(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
         self.expect["poll_entry"]["big_poll_in"] = 0
@@ -584,7 +584,7 @@ class Test4(TraceParser):
         # Save values of local variables to print in case of test failure
         self.recorded_values["poll_exit"] = locals()
 
-class Test5(TraceParser):
+class PpollFdsBufferOverflow(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
         self.expect["poll_entry"]["poll_overflow_in"] = 0
@@ -618,7 +618,7 @@ class Test5(TraceParser):
         self.recorded_values["poll_exit"] = locals()
 
 
-class Test6(TraceParser):
+class PselectInvalidPointer(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
         self.expect["select_entry"]["pselect_invalid_in"] = 0
@@ -651,7 +651,7 @@ class Test6(TraceParser):
         self.recorded_values["select_exit"] = locals()
 
 
-class Test7(TraceParser):
+class PpollFdsULongMax(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
         self.expect["poll_entry"]["poll_max_in"] = 0
@@ -682,7 +682,7 @@ class Test7(TraceParser):
         self.recorded_values["poll_exit"] = locals()
 
 
-class Test8(TraceParser):
+class EpollPwaitInvalidPointer(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
 
@@ -719,7 +719,7 @@ class Test8(TraceParser):
         self.recorded_values["epoll_wait_exit"] = locals()
 
 
-class Test9(TraceParser):
+class EpollPwaitIntMax(TraceParser):
     def __init__(self, trace, validation_args):
         super().__init__(trace, validation_args['pid'])
 
@@ -757,7 +757,7 @@ class Test9(TraceParser):
 if __name__ == "__main__":
     parser = argparse.ArgumentParser(description='Trace parser')
     parser.add_argument('path', metavar="<path/to/trace>", help='Trace path')
-    parser.add_argument('-t', '--test', type=int, help='Test to validate')
+    parser.add_argument('-t', '--test', type=str, help='Test to validate')
     parser.add_argument('-o', '--validation-file', type=str, help='Validation file path')
     args = parser.parse_args()
 
@@ -780,28 +780,28 @@ if __name__ == "__main__":
 
     t = None
 
-    if args.test == 1:
-        t = Test1(traces, test_validation_args)
-    elif args.test == 2:
-        t = Test2(traces, test_validation_args)
-    elif args.test == 3:
-        t = Test3(traces, test_validation_args)
-    elif args.test == 4:
-        t = Test4(traces, test_validation_args)
-    elif args.test == 5:
-        t = Test5(traces, test_validation_args)
-    elif args.test == 6:
-        t = Test6(traces, test_validation_args)
-    elif args.test == 7:
-        t = Test7(traces, test_validation_args)
-    elif args.test == 8:
-        t = Test8(traces, test_validation_args)
-    elif args.test == 9:
-        t = Test9(traces, test_validation_args)
-    elif args.test == 10:
+    if args.test == "working_cases":
+        t = WorkingCases(traces, test_validation_args)
+    elif args.test == "working_cases_timeout":
+        t = WorkingCasesTimeout(traces, test_validation_args)
+    elif args.test == "pselect_invalid_fd":
+        t = PselectInvalidFd(traces, test_validation_args)
+    elif args.test == "ppoll_big":
+        t = PpollBig(traces, test_validation_args)
+    elif args.test == "ppoll_fds_buffer_overflow":
+        t = PpollFdsBufferOverflow(traces, test_validation_args)
+    elif args.test == "pselect_invalid_pointer":
+        t = PselectInvalidPointer(traces, test_validation_args)
+    elif args.test == "ppoll_fds_ulong_max":
+        t = PpollFdsULongMax(traces, test_validation_args)
+    elif args.test == "epoll_pwait_invalid_pointer":
+        t = EpollPwaitInvalidPointer(traces, test_validation_args)
+    elif args.test == "epoll_pwait_int_max":
+        t = EpollPwaitIntMax(traces, test_validation_args)
+    elif args.test == "ppoll_concurrent_write":
         # stress test, nothing reliable to check
         ret = 0
-    elif args.test == 11:
+    elif args.test == "epoll_pwait_concurrent_munmap":
         # stress test, nothing reliable to check
         ret = 0
     else:
This page took 0.045711 seconds and 4 git commands to generate.