From: Dmitry V. Levin Date: Fri, 10 Jun 2016 09:15:59 +0000 (+0000) Subject: tests: extend test coverage of wait4 syscall X-Git-Tag: v4.13~155 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1f68abfed3b0f4187a303f36d6cc32068a7e11c8;p=strace tests: extend test coverage of wait4 syscall * tests/wait4.c: New file. * tests/wait4-v.c: Likewise. * tests/wait4.test: New test. * tests/wait4-v.test: Likewise. * tests/.gitignore: Add wait4 and wait4-v. * tests/Makefile.am (check_PROGRAMS): Likewise. (DECODER_TESTS): Add wait4.test and wait4-v.test. --- diff --git a/tests/.gitignore b/tests/.gitignore index 7e5b73cd..3ee848d2 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -276,6 +276,8 @@ vfork-f vhangup vmsplice wait +wait4 +wait4-v waitpid xattr xet_robust_list diff --git a/tests/Makefile.am b/tests/Makefile.am index 3c5fe7ab..2efe44c5 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -329,6 +329,8 @@ check_PROGRAMS = \ vhangup \ vmsplice \ wait \ + wait4 \ + wait4-v \ waitpid \ xattr \ xet_robust_list \ @@ -626,6 +628,8 @@ DECODER_TESTS = \ vhangup.test \ vmsplice.test \ wait.test \ + wait4.test \ + wait4-v.test \ waitpid.test \ xattr.test \ xet_robust_list.test \ diff --git a/tests/wait4-v.c b/tests/wait4-v.c new file mode 100644 index 00000000..95a3c8b6 --- /dev/null +++ b/tests/wait4-v.c @@ -0,0 +1,3 @@ +/* This file is part of wait4-v strace test. */ +#define VERBOSE_RUSAGE +#include "wait4.c" diff --git a/tests/wait4-v.test b/tests/wait4-v.test new file mode 100755 index 00000000..58e55f25 --- /dev/null +++ b/tests/wait4-v.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check verbose decoding of wait4 syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -v -e signal=none -e trace=wait4 diff --git a/tests/wait4.c b/tests/wait4.c new file mode 100644 index 00000000..981818c7 --- /dev/null +++ b/tests/wait4.c @@ -0,0 +1,199 @@ +/* + * Check decoding of wait4 syscall. + * + * Copyright (c) 2015-2016 Dmitry V. Levin + * 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 +#include +#include +#include +#include +#include + +static const char * +sprint_rusage(const struct rusage *const ru) +{ + static char buf[1024]; + snprintf(buf, sizeof(buf), + "{ru_utime={%lu, %lu}" + ", ru_stime={%lu, %lu}" +#ifdef VERBOSE_RUSAGE + ", ru_maxrss=%lu" + ", ru_ixrss=%lu" + ", ru_idrss=%lu" + ", ru_isrss=%lu" + ", ru_minflt=%lu" + ", ru_majflt=%lu" + ", ru_nswap=%lu" + ", ru_inblock=%lu" + ", ru_oublock=%lu" + ", ru_msgsnd=%lu" + ", ru_msgrcv=%lu" + ", ru_nsignals=%lu" + ", ru_nvcsw=%lu" + ", ru_nivcsw=%lu}" +#else + ", ...}" +#endif + , (long) ru->ru_utime.tv_sec + , (long) ru->ru_utime.tv_usec + , (long) ru->ru_stime.tv_sec + , (long) ru->ru_stime.tv_usec +#ifdef VERBOSE_RUSAGE + , (long) ru->ru_maxrss + , (long) ru->ru_ixrss + , (long) ru->ru_idrss + , (long) ru->ru_isrss + , (long) ru->ru_minflt + , (long) ru->ru_majflt + , (long) ru->ru_nswap + , (long) ru->ru_inblock + , (long) ru->ru_oublock + , (long) ru->ru_msgsnd + , (long) ru->ru_msgrcv + , (long) ru->ru_nsignals + , (long) ru->ru_nvcsw + , (long) ru->ru_nivcsw +#endif + ); + return buf; +} + +static pid_t +do_wait4(pid_t pid, int *wstatus, int options, struct rusage *ru) +{ + sigset_t mask = {}; + sigaddset(&mask, SIGCHLD); + + assert(sigprocmask(SIG_BLOCK, &mask, NULL) == 0); + pid_t rc = wait4(pid, wstatus, options, ru); + assert(sigprocmask(SIG_UNBLOCK, &mask, NULL) == 0); + return rc; +} + +int +main(void) +{ + tprintf("%s", ""); + + int fds[2]; + if (pipe(fds)) + perror_msg_and_fail("pipe"); + + pid_t pid; + pid = fork(); + if (pid < 0) + perror_msg_and_fail("fork"); + + if (!pid) { + char c; + (void) close(1); + assert(read(0, &c, sizeof(c)) == 1); + return 42; + } + + (void) close(0); + + int *const s = tail_alloc(sizeof(*s)); + if (wait4(pid, s, WNOHANG|__WALL, NULL)) + perror_msg_and_fail("wait4 #1"); + tprintf("wait4(%d, %p, WNOHANG|__WALL, NULL) = 0\n", pid, s); + + struct rusage *const rusage = tail_alloc(sizeof(*rusage)); + if (wait4(pid, s, WNOHANG|__WALL, rusage)) + perror_msg_and_fail("wait4 #2"); + tprintf("wait4(%d, %p, WNOHANG|__WALL, %p) = 0\n", pid, s, rusage); + + assert(write(1, "", 1) == 1); + (void) close(1); + + assert(do_wait4(pid, s, 0, rusage) == pid); + assert(WIFEXITED(*s) && WEXITSTATUS(*s) == 42); + tprintf("wait4(%d, [{WIFEXITED(s) && WEXITSTATUS(s) == 42}], 0, %s)" + " = %d\n", pid, sprint_rusage(rusage), pid); + + pid = fork(); + if (pid < 0) + perror_msg_and_fail("fork"); + + if (!pid) { + (void) raise(SIGUSR1); + return 1; + } + + assert(do_wait4(pid, s, __WALL, rusage) == pid); + assert(WIFSIGNALED(*s) && WTERMSIG(*s) == SIGUSR1); + tprintf("wait4(%d, [{WIFSIGNALED(s) && WTERMSIG(s) == SIGUSR1}]" + ", __WALL, %s) = %d\n", pid, sprint_rusage(rusage), pid); + + if (pipe(fds)) + perror_msg_and_fail("pipe"); + pid = fork(); + if (pid < 0) + perror_msg_and_fail("fork"); + + if (!pid) { + (void) close(1); + raise(SIGSTOP); + char c; + assert(read(0, &c, sizeof(c)) == 1); + return 0; + } + + (void) close(0); + + assert(do_wait4(pid, s, WSTOPPED, rusage) == pid); + assert(WIFSTOPPED(*s) && WSTOPSIG(*s) == SIGSTOP); + tprintf("wait4(%d, [{WIFSTOPPED(s) && WSTOPSIG(s) == SIGSTOP}]" + ", WSTOPPED, %s) = %d\n", pid, sprint_rusage(rusage), pid); + + if (kill(pid, SIGCONT)) + perror_msg_and_fail("kill(SIGCONT)"); + +#if defined WCONTINUED && defined WIFCONTINUED + assert(do_wait4(pid, s, WCONTINUED, rusage) == pid); + assert(WIFCONTINUED(*s)); + tprintf("wait4(%d, [{WIFCONTINUED(s)}], WCONTINUED" + ", %s) = %d\n", pid, sprint_rusage(rusage), pid); +#endif /* WCONTINUED && WIFCONTINUED */ + + assert(write(1, "", 1) == 1); + (void) close(1); + + assert(do_wait4(pid, s, 0, rusage) == pid); + assert(WIFEXITED(*s) && WEXITSTATUS(*s) == 0); + tprintf("wait4(%d, [{WIFEXITED(s) && WEXITSTATUS(s) == 0}], 0" + ", %s) = %d\n", pid, sprint_rusage(rusage), pid); + + assert(wait4(-1, s, WNOHANG|WSTOPPED|__WALL, rusage) == -1); + tprintf("wait4(-1, %p, WNOHANG|WSTOPPED|__WALL, %p) = -1 %s (%m)\n", + s, rusage, errno2name()); + + tprintf("%s\n", "+++ exited with 0 +++"); + return 0; +} diff --git a/tests/wait4.test b/tests/wait4.test new file mode 100755 index 00000000..6338d1f6 --- /dev/null +++ b/tests/wait4.test @@ -0,0 +1,6 @@ +#!/bin/sh + +# Check decoding of wait4 syscall. + +. "${srcdir=.}/init.sh" +run_strace_match_diff -esignal=none