]> granicus.if.org Git - strace/commitdiff
test/sigkill_rain.c: a testcase with lots of async deaths
authorDenys Vlasenko <dvlasenk@redhat.com>
Fri, 13 Feb 2009 10:26:31 +0000 (10:26 +0000)
committerDenys Vlasenko <dvlasenk@redhat.com>
Fri, 13 Feb 2009 10:26:31 +0000 (10:26 +0000)
test/sigkill_rain.c [new file with mode: 0644]

diff --git a/test/sigkill_rain.c b/test/sigkill_rain.c
new file mode 100644 (file)
index 0000000..4306a8a
--- /dev/null
@@ -0,0 +1,62 @@
+/* This test is not yet added to Makefile */
+
+#include <stddef.h>
+#include <unistd.h>
+#include <signal.h>
+
+#include <sys/types.h>
+#include <sys/socket.h>
+static const struct sockaddr sa;
+
+int main(int argc, char **argv)
+{
+       int loops;
+       int pid;
+       sigset_t set;
+
+       sigemptyset(&set);
+       sigaddset(&set, SIGCHLD);
+       sigprocmask(SIG_BLOCK, &set, NULL);
+
+       loops = 999;
+       if (argv[1])
+               loops = atoi(argv[1]);
+
+       while (--loops >= 0) {
+               pid = fork();
+               if (pid < 0) _exit(1);
+               if (!pid) {
+                       /* child */
+                       int child = getpid();
+
+                       loops = 99;
+                       while (--loops) {
+                               pid = fork();
+                               if (pid < 0) _exit(1);
+                               if (!pid) {
+                                       /* grandchild: kill child */
+                                       kill(child, SIGKILL);
+                                       _exit(0);
+                               }
+                               /* Add various syscalls you want to test here.
+                                * strace will decode them and suddenly find
+                                * process disappearing.
+                                * But leave at least one case "empty", so that
+                                * "kill grandchild" happens quicker.
+                                * This produces cases when strace can't even
+                                * decode syscall number before process dies.
+                                */
+                               switch (loops & 1) {
+                               case 0: /* empty */ break;
+                               case 1: sendto(-1, "Hello cruel world", 17, 0, &sa, sizeof(sa)); break;
+                               }
+                               /* kill grandchild */
+                               kill(pid, SIGKILL);
+                       }
+                       _exit(0);
+               }
+               /* parent */
+               wait(NULL);
+       }
+       return 0;
+}