From: Denys Vlasenko Date: Wed, 8 Jun 2011 12:08:59 +0000 (+0200) Subject: Update test/* directory, it seem to be a bit bit-rotted X-Git-Tag: v4.7~387 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=8158e7716c330d21f116ea6c6479f3d559c63f38;p=strace Update test/* directory, it seem to be a bit bit-rotted Added README; modified sigkill_rain.c to be more understandable, made clone.c compile; added wait_must_be_interruptible.c test; updated Makefile and .gitignore. Signed-off-by: Denys Vlasenko --- diff --git a/test/.gitignore b/test/.gitignore index 58caafe7..5c689bd6 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -1,7 +1,9 @@ +vfork fork sig skodic -vfork clone leaderkill childthread +sigkill_rain +wait_must_be_interruptible diff --git a/test/Makefile b/test/Makefile index 3e7236b9..64bc811f 100644 --- a/test/Makefile +++ b/test/Makefile @@ -2,11 +2,15 @@ # $Id$ # -all: vfork fork sig skodic clone leaderkill childthread +all: \ + vfork fork sig skodic clone leaderkill childthread \ + sigkill_rain wait_must_be_interruptible leaderkill: LDFLAGS += -pthread childthread: LDFLAGS += -pthread clean distclean: - rm -f clone vfork fork sig leaderkill *.o core + rm -f *.o core \ + vfork fork sig skodic clone leaderkill childthread \ + sigkill_rain wait_must_be_interruptible diff --git a/test/README b/test/README new file mode 100644 index 00000000..7fae09b6 --- /dev/null +++ b/test/README @@ -0,0 +1,17 @@ +To run a test: +* Run make +* Run resulting executable(s) under strace +* Check strace output and/or program's output and exitcode + +To add a new test: +* Add its .c source to this dir +* Add it to "all" and "clean" targets in Makefile +* Add it to .gitignore file + +Please spend some time making your testcase understandable. +For example, it may print an explanation how it should be used +(which strace options to use, and what to look for in strace output). + +If possible, make it so that your testcase detects error/bug +it is intended to test for, and prints error message and exits with 1 +if the bug is detected, instead of relying on user to peruse strace output. diff --git a/test/clone.c b/test/clone.c index 335086fc..5de302f8 100644 --- a/test/clone.c +++ b/test/clone.c @@ -1,3 +1,6 @@ +/* for CLONE_foo: */ +#define _GNU_SOURCE 1 + #include #include #include diff --git a/test/sigkill_rain.c b/test/sigkill_rain.c index dd83a692..01b8986e 100644 --- a/test/sigkill_rain.c +++ b/test/sigkill_rain.c @@ -1,12 +1,10 @@ -/* This test is not yet added to Makefile */ - #include #include #include #include - #include #include +#include static const struct sockaddr sa; @@ -16,6 +14,12 @@ int main(int argc, char *argv[]) int pid; sigset_t set; + printf( +"Please run me under 'strace -f -oLOG', and examine LOG file for incorrect\n" +"decoding of interrupted syscalls: grep for 'sendto', '??" /* anti-trigraph gap */ "?', 'unavailable'.\n" +"Pass number of iterations in argv[1] (default: 999).\n" + ); + sigemptyset(&set); sigaddset(&set, SIGCHLD); sigprocmask(SIG_BLOCK, &set, NULL); @@ -57,7 +61,7 @@ int main(int argc, char *argv[]) */ switch (loops & 1) { case 0: - break; /* intentional empty */ + break; /* intentionally empty */ case 1: sendto(-1, "Hello cruel world", 17, 0, &sa, sizeof(sa)); break; diff --git a/test/wait_must_be_interruptible.c b/test/wait_must_be_interruptible.c new file mode 100644 index 00000000..931ec4ce --- /dev/null +++ b/test/wait_must_be_interruptible.c @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +/* Expected order is: + * Child signals parent + * Parent got signal + * Child will exit now + * + * The bug we test for: under strace -f, last two lines are swapped + * because wait syscall is suspended by strace and thus can't be interrupted. + */ + +static const char msg1[] = "Child signals parent\n"; +static const char msg2[] = "Parent got signal\n"; +static const char msg3[] = "Child will exit now\n"; + +static void handler(int s) +{ + write(1, msg2, sizeof(msg2)-1); +} + +static void test() +{ + /* Note: in Linux, signal() installs handler with SA_RESTART flag, + * therefore wait will be restarted. + */ + signal(SIGALRM, handler); + + if (fork() == 0) { + /* child */ + sleep(1); + write(1, msg1, sizeof(msg1)-1); + kill(getppid(), SIGALRM); + sleep(1); + write(1, msg3, sizeof(msg3)-1); + _exit(0); + } + + /* parent */ + wait(NULL); + _exit(0); +} + +int main() +{ + char buf1[80]; + char buf2[80]; + char buf3[80]; + int pipefd[2]; + + printf("Please run me under 'strace -f'\n"); + + pipe(pipefd); + + if (fork() == 0) { + if (pipefd[1] != 1) { + dup2(pipefd[1], 1); + close(pipefd[1]); + } + test(); + } + + if (pipefd[0] != 0) { + dup2(pipefd[0], 0); + close(pipefd[0]); + } + fgets(buf1, 80, stdin); printf("%s", buf1); + fgets(buf2, 80, stdin); printf("%s", buf2); + fgets(buf3, 80, stdin); printf("%s", buf3); + + if (strcmp(buf1, msg1) != 0 + || strcmp(buf2, msg2) != 0 + || strcmp(buf3, msg3) != 0 + ) { + printf("ERROR! Expected order:\n%s%s%s", msg1, msg2, msg3); + return 1; + } + printf("Good: wait seems to be correctly interrupted by signals\n"); + return 0; +}