From: Dmitry V. Levin Date: Wed, 30 Dec 2015 23:00:43 +0000 (+0000) Subject: tests: add fork-f.test and vfork-f.test X-Git-Tag: v4.12~782 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78db0f2dcf1186a6f28387508536d587fb8fd2ba;p=strace tests: add fork-f.test and vfork-f.test Check how strace -f follows fork and vfork syscalls. * tests/fork-f.c: New file. * tests/fork-f.test: New test. * tests/vfork-f.c: New file. * tests/vfork-f.test: New test. * tests/Makefile.am (check_PROGRAMS): Add fork-f and vfork-f. (TESTS): Add fork-f.test and vfork-f.test. * tests/.gitignore: Add fork-f and vfork-f. --- diff --git a/tests/.gitignore b/tests/.gitignore index b4d1df9a..1891eeec 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -21,6 +21,7 @@ fcntl fcntl64 file_handle filter-unavailable +fork-f fstat fstat64 fstatat64 @@ -102,6 +103,7 @@ unix-pair-send-recv userfaultfd utime utimensat +vfork-f wait xattr xet_robust_list diff --git a/tests/Makefile.am b/tests/Makefile.am index c54fdf34..6c8f07c9 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -56,6 +56,7 @@ check_PROGRAMS = \ fcntl64 \ file_handle \ filter-unavailable \ + fork-f \ fstat \ fstat64 \ fstatat64 \ @@ -136,6 +137,7 @@ check_PROGRAMS = \ userfaultfd \ utime \ utimensat \ + vfork-f \ wait \ xattr \ xet_robust_list \ @@ -184,6 +186,7 @@ TESTS = \ fcntl64.test \ file_handle.test \ filter-unavailable.test \ + fork-f.test \ fstat.test \ fstat64.test \ fstatat64.test \ @@ -260,6 +263,7 @@ TESTS = \ userfaultfd.test \ utime.test \ utimensat.test \ + vfork-f.test \ wait.test \ xattr.test \ xet_robust_list.test \ diff --git a/tests/fork-f.c b/tests/fork-f.c new file mode 100644 index 00000000..a1a45b9e --- /dev/null +++ b/tests/fork-f.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2015 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include + +static int +logit(const char *const str) +{ + return pwrite(-1, str, strlen(str), 0) >= 0; +} + +int main(int ac, char **av, char **ep) +{ + if (ac < 1) + return 1; + if (ac > 1) + return logit(av[1]); + + logit("start"); + + int fds[2]; + (void) close(0); + if (pipe(fds)) { + perror("pipe"); + return 77; + } + + pid_t pid = fork(); + + if (pid < 0) { + perror("fork"); + return 77; + } + + if (!pid) { + close(fds[1]); + + if (read(0, fds, sizeof(int))) + _exit(2); + + char *const args[] = { av[0], (char *) "exec", NULL }; + if (logit("child") || execve(args[0], args, args + 1)) + _exit(2); + } + + close(0); + + logit("parent"); + close(fds[1]); + + int status; + if (wait(&status) != pid) { + perror("wait"); + return 77; + } + if (status) { + fprintf(stderr, "status = %d\n", status); + return 77; + } + + logit("finish"); + + pid_t ppid = getpid(); + close(-1); + printf("%-5d pwrite64(-1, \"start\", 5, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"parent\", 6, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"child\", 5, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"exec\", 4, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"finish\", 6, 0) = -1 EBADF (%m)\n", + ppid, ppid, pid, pid, ppid); + return 0; +} diff --git a/tests/fork-f.test b/tests/fork-f.test new file mode 100755 index 00000000..8fdf062e --- /dev/null +++ b/tests/fork-f.test @@ -0,0 +1,13 @@ +#!/bin/sh + +# Check how strace -f follows fork syscall. + +. "${srcdir=.}/init.sh" + +run_prog > /dev/null +OUT="$LOG.out" +run_strace -a32 -qq -f -epwrite64 -esignal=none $args > "$OUT" +match_diff "$LOG" "$OUT" +rm -f "$OUT" + +exit 0 diff --git a/tests/vfork-f.c b/tests/vfork-f.c new file mode 100644 index 00000000..6a7cce49 --- /dev/null +++ b/tests/vfork-f.c @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2015 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. + */ + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include +#include +#include +#include +#include + +static inline int +logit(const char *const str) +{ + return pwrite(-1, str, strlen(str), 0) >= 0; +} + +int main(int ac, char **av, char **ep) +{ + if (ac < 1) + return 1; + if (ac > 1) { + if (read(0, &ac, sizeof(int))) + return 2; + return logit(av[1]); + } + + logit("start"); + + int fds[2]; + (void) close(0); + if (pipe(fds)) { + perror("pipe"); + return 77; + } + if (fcntl(fds[1], F_SETFD, FD_CLOEXEC)) { + perror("fcntl"); + return 77; + } + + char *const args[] = { av[0], (char *) "exec", NULL }; + pid_t pid = vfork(); + + if (pid < 0) { + perror("vfork"); + return 77; + } + + if (!pid) { + if (logit("child") || execve(args[0], args, args + 1)) + _exit(2); + } + + close(0); + + logit("parent"); + close(fds[1]); + + int status; + if (wait(&status) != pid) { + perror("wait"); + return 77; + } + if (status) { + fprintf(stderr, "status = %d\n", status); + return 77; + } + + logit("finish"); + + pid_t ppid = getpid(); + close(-1); + printf("%-5d pwrite64(-1, \"start\", 5, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"child\", 5, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"parent\", 6, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"exec\", 4, 0) = -1 EBADF (%m)\n" + "%-5d pwrite64(-1, \"finish\", 6, 0) = -1 EBADF (%m)\n", + ppid, pid, ppid, pid, ppid); + return 0; +} diff --git a/tests/vfork-f.test b/tests/vfork-f.test new file mode 100755 index 00000000..ff4422b2 --- /dev/null +++ b/tests/vfork-f.test @@ -0,0 +1,5 @@ +#!/bin/sh + +# Check how strace -f follows vfork syscall. + +. "${srcdir=.}/fork-f.test"