]> granicus.if.org Git - strace/blob - test/sigkill_rain.c
By Hans-Christian Egtvedt (hans-christian.egtvedt AT atmel.com):
[strace] / test / sigkill_rain.c
1 /* This test is not yet added to Makefile */
2
3 #include <stdlib.h>
4 #include <stddef.h>
5 #include <unistd.h>
6 #include <signal.h>
7
8 #include <sys/types.h>
9 #include <sys/socket.h>
10
11 static const struct sockaddr sa;
12
13 int main(int argc, char *argv[])
14 {
15         int loops;
16         int pid;
17         sigset_t set;
18
19         sigemptyset(&set);
20         sigaddset(&set, SIGCHLD);
21         sigprocmask(SIG_BLOCK, &set, NULL);
22
23         loops = 999;
24         if (argv[1])
25                 loops = atoi(argv[1]);
26
27         while (--loops >= 0) {
28                 pid = fork();
29
30                 if (pid < 0)
31                         exit(1);
32
33                 if (!pid) {
34                         /* child */
35                         int child = getpid();
36
37                         loops = 99;
38                         while (--loops) {
39                                 pid = fork();
40
41                                 if (pid < 0)
42                                         exit(1);
43
44                                 if (!pid) {
45                                         /* grandchild: kill child */
46                                         kill(child, SIGKILL);
47                                         exit(0);
48                                 }
49
50                                 /* Add various syscalls you want to test here.
51                                  * strace will decode them and suddenly find
52                                  * process disappearing.
53                                  * But leave at least one case "empty", so that
54                                  * "kill grandchild" happens quicker.
55                                  * This produces cases when strace can't even
56                                  * decode syscall number before process dies.
57                                  */
58                                 switch (loops & 1) {
59                                 case 0:
60                                         break; /* intentional empty */
61                                 case 1:
62                                         sendto(-1, "Hello cruel world", 17, 0, &sa, sizeof(sa));
63                                         break;
64                                 }
65
66                                 /* kill grandchild */
67                                 kill(pid, SIGKILL);
68                         }
69
70                         exit(0);
71                 }
72
73                 /* parent */
74                 wait(NULL);
75         }
76
77         return 0;
78 }