]> granicus.if.org Git - strace/commitdiff
tests: update futex test to accommodate the recent kernel change
authorEugene Syromyatnikov <evgsyr@gmail.com>
Fri, 3 Nov 2017 02:45:00 +0000 (03:45 +0100)
committerDmitry V. Levin <ldv@altlinux.org>
Fri, 3 Nov 2017 20:46:47 +0000 (20:46 +0000)
Kernel commit v4.14-rc1~162^2~8 refactored futex implementation and
introduced checks for invalid shift sizes.  Accommodate this change
by allowing EINVAL in the corresponding futex checks.

* tests/futex.c (CHECK_FUTEX_GENERIC): Reset errno before the syscall.
(main) <wake_ops>: Add err2 field, describe err/err2 fields.
Add EINVAL as a possible errno to the checks that contain invalid
shift values.
Update return value check so it checks that values are strictly
as expected.

Closes: https://github.com/strace/strace/pull/16
tests/futex.c

index 3a10f87e2679db1c85de0383813e113fcd44092f..e1dbcb749a85815d2fc21aa0dac76ad450380fba 100644 (file)
@@ -66,6 +66,7 @@ void futex_error(int *uaddr, int op, unsigned long val, unsigned long timeout,
 # define CHECK_FUTEX_GENERIC(uaddr, op, val, timeout, uaddr2, val3, check, \
        enosys) \
        do { \
+               errno = 0; \
                rc = syscall(__NR_futex, (uaddr), (op), (val), (timeout), \
                        (uaddr2), (val3)); \
                /* It is here due to EPERM on WAKE_OP on AArch64 */ \
@@ -496,7 +497,16 @@ main(int argc, char *argv[])
        static const struct {
                uint32_t val;
                const char *str;
+
+               /*
+                * Peculiar semantics:
+                *  * err == 0 and err2 != 0 => expect both either the absence
+                *    of error or presence of err2
+                *  * err != 0 and err2 == 0 => expect err only, no success
+                *    expected.
+                */
                int err;
+               int err2;
        } wake_ops[] = {
                { 0x00000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_EQ<<24|0" },
                { 0x00fff000, "FUTEX_OP_SET<<28|0xfff<<12|FUTEX_OP_CMP_EQ<<24|"
@@ -516,7 +526,7 @@ main(int argc, char *argv[])
                { 0x80000000, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_SET<<28|0<<12|"
                        "FUTEX_OP_CMP_EQ<<24|0" },
                { 0xa0caffee, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_OR<<28|"
-                       "0xcaf<<12|FUTEX_OP_CMP_EQ<<24|0xfee" },
+                       "0xcaf<<12|FUTEX_OP_CMP_EQ<<24|0xfee", 0, EINVAL },
                { 0x01000000, "FUTEX_OP_SET<<28|0<<12|FUTEX_OP_CMP_NE<<24|0" },
                { 0x01234567, "FUTEX_OP_SET<<28|0x234<<12|FUTEX_OP_CMP_NE<<24|"
                        "0x567" },
@@ -534,18 +544,29 @@ main(int argc, char *argv[])
                        "0xf<<24 /* FUTEX_OP_CMP_??? */|0", ENOSYS },
                { 0xbadfaced, "FUTEX_OP_OPARG_SHIFT<<28|FUTEX_OP_ANDN<<28|"
                        "0xdfa<<12|0xa<<24 /* FUTEX_OP_CMP_??? */|0xced",
-                       ENOSYS },
+                       ENOSYS, EINVAL },
                { 0xffffffff, "FUTEX_OP_OPARG_SHIFT<<28|"
                        "0x7<<28 /* FUTEX_OP_??? */|0xfff<<12|"
                        "0xf<<24 /* FUTEX_OP_CMP_??? */|0xfff",
-                       ENOSYS },
+                       ENOSYS, EINVAL },
        };
 
        for (i = 0; i < ARRAY_SIZE(wake_ops); i++) {
                for (j = 0; j < 2; j++) {
                        CHECK_FUTEX_ENOSYS(uaddr,
                                j ? FUTEX_WAKE_OP_PRIVATE : FUTEX_WAKE_OP,
-                               VAL, i, uaddr2, wake_ops[i].val, (rc == 0));
+                               VAL, i, uaddr2, wake_ops[i].val,
+                               /*
+                                * Either one of errs is 0 or rc == 0 is not
+                                * allowed.
+                                */
+                               ((!wake_ops[i].err || !wake_ops[i].err2 ||
+                                       (rc != 0)) &&
+                               ((!wake_ops[i].err && (rc == 0)) ||
+                               (wake_ops[i].err  && (rc == -1) &&
+                                       (errno == wake_ops[i].err)) ||
+                               (wake_ops[i].err2 && (rc == -1) &&
+                                       (errno == wake_ops[i].err2)))));
                        printf("futex(%p, FUTEX_WAKE_OP%s, %u, %u, %p, %s)"
                               " = %s\n", uaddr, j ? "_PRIVATE" : "", VAL_PR,
                               i, uaddr2, wake_ops[i].str, sprintrc(rc));