2 * Each process that gets forked runs this code.
13 #include <sys/resource.h>
14 #include <sys/prctl.h>
21 #include "params.h" // for 'debug'
28 #include "trinity.h" // ARRAY_SIZE
29 #include "utils.h" // zmalloc
31 static struct rlimit oldrlimit
;
33 static void disable_coredumps(void)
38 (void)signal(SIGABRT
, SIG_DFL
);
39 (void)signal(SIGSEGV
, SIG_DFL
);
43 getrlimit(RLIMIT_CORE
, &oldrlimit
);
46 limit
.rlim_max
= oldrlimit
.rlim_max
;
47 if (setrlimit(RLIMIT_CORE
, &limit
) != 0)
48 perror( "setrlimit(RLIMIT_CORE)" );
51 static void reenable_coredumps(void)
56 prctl(PR_SET_DUMPABLE
, TRUE
);
58 if (setrlimit(RLIMIT_CORE
, &oldrlimit
) != 0) {
59 outputerr("[%d] Error restoring rlimits to cur:%d max:%d (%s)\n",
61 (unsigned int) oldrlimit
.rlim_cur
,
62 (unsigned int) oldrlimit
.rlim_max
,
66 static void set_make_it_fail(void)
69 const char *buf
= "1";
71 /* If we failed last time, don't bother trying in future. */
72 if (shm
->do_make_it_fail
== TRUE
)
75 fd
= open("/proc/self/make-it-fail", O_WRONLY
);
79 if (write(fd
, buf
, 1) == -1) {
81 outputerr("writing to /proc/self/make-it-fail failed! (%s)\n", strerror(errno
));
83 shm
->do_make_it_fail
= TRUE
;
89 * We call this occasionally to set some FPU state, in the hopes that we
90 * might tickle some weird FPU/scheduler related bugs
92 static void use_fpu(void)
95 asm volatile("":"+m" (x
));
97 asm volatile("":"+m" (x
));
102 static void setup_page_maps(void)
107 page
= (void *) page_maps
;
109 for (i
= 0; i
< page_size
/ sizeof(unsigned long); i
++) {
113 page
[i
] = (unsigned long) map
->ptr
;
117 void init_child(int childno
)
120 pid_t pid
= getpid();
122 this_child
= childno
;
126 shm
->kill_count
[childno
] = 0;
132 if (sched_getaffinity(pid
, sizeof(set
), &set
) == 0) {
134 CPU_SET(childno
, &set
);
135 sched_setaffinity(pid
, sizeof(set
), &set
);
138 shm
->child_syscall_count
[childno
] = 0;
142 if (rand() % 100 < 50)
145 shm
->num_mappings
[childno
] = 0;
146 shm
->mappings
[childno
] = zmalloc(sizeof(struct map
));
147 INIT_LIST_HEAD(&shm
->mappings
[childno
]->list
);
150 void check_parent_pid(void)
154 static unsigned int parent_check_time
= 10;
157 if (parent_check_time
!= 0)
160 parent_check_time
= 10;
162 if (getppid() == shm
->mainpid
)
167 //FIXME: Add locking so only one child does this output.
168 output(0, BUGTXT
"CHILD (pid:%d) GOT REPARENTED! "
169 "parent pid:%d. Watchdog pid:%d\n",
170 pid
, shm
->mainpid
, watchdog_pid
);
171 output(0, BUGTXT
"Last syscalls:\n");
173 for (i
= 0; i
< shm
->running_childs
; i
++) {
174 // Skip over 'boring' entries.
175 if ((shm
->pids
[i
] == EMPTY_PIDSLOT
) &&
176 (shm
->previous_syscallno
[i
] == 0) &&
177 (shm
->child_syscall_count
[i
] == 0))
180 output(0, "[%d] pid:%d call:%s callno:%d\n",
182 print_syscall_name(shm
->previous_syscallno
[i
], shm
->do32bit
[i
]), // FIXME: need previous do32bit
183 shm
->child_syscall_count
[i
]);
185 shm
->exit_reason
= EXIT_REPARENT_PROBLEM
;
187 //TODO: Emergency logging.
193 int (*func
)(int childno
);
196 static const struct child_funcs child_functions
[] = {
197 { .type
= CHILD_RANDOM_SYSCALLS
, .name
= "rand_syscalls", .func
= child_random_syscalls
},
199 { .type
= CHILD_OPEN_ALL_FILES
, .name
= "read_all_files", .func
= child_read_all_files
},
203 int child_process(int childno
)
208 i
= rand() % ARRAY_SIZE(child_functions
);
211 output(0, "Chose %s.\n", child_functions
[i
].name
);
214 shm
->child_type
[childno
] = child_functions
[i
].type
;
215 ret
= child_functions
[i
].func(childno
);
217 reenable_coredumps();