test/sigkill_rain.c: a testcase with lots of async deaths
diff --git a/test/sigkill_rain.c b/test/sigkill_rain.c
new file mode 100644
index 0000000..4306a8a
--- /dev/null
+++ b/test/sigkill_rain.c
@@ -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;
+}