From 48cb6336d8ae93c78b82ad567585660a2371ccf7 Mon Sep 17 00:00:00 2001 From: Eugene Syromyatnikov Date: Fri, 3 Nov 2017 03:45:00 +0100 Subject: [PATCH] tests: update futex test to accommodate the recent kernel change 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) : 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 | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/tests/futex.c b/tests/futex.c index 3a10f87e..e1dbcb74 100644 --- a/tests/futex.c +++ b/tests/futex.c @@ -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)); -- 2.40.0