static void stuck_syscall_info(struct childdata *child) { struct syscallrecord *rec; unsigned int callno; char fdstr[20]; bool do32; if (shm->debug == FALSE) return; memset(fdstr, 0, sizeof(fdstr)); rec = &child->syscall; lock(&rec->lock); do32 = rec->do32bit; callno = rec->nr; /* we can only be 'stuck' if we're still doing the syscall. */ if (rec->state == BEFORE) { if (check_if_fd(child, rec) == TRUE) sprintf(fdstr, "(fd = %d)", (unsigned int) rec->a1); } unlock(&rec->lock); output(0, "child %d (pid %u) Stuck in syscall %d:%s%s%s.\n", child->num, child->pid, callno, print_syscall_name(callno, do32), do32 ? " (32bit)" : "", fdstr); }
static void stuck_syscall_info(int childno) { unsigned int callno = shm->syscall[childno].nr; char fdstr[20]; pid_t pid = shm->pids[childno]; memset(fdstr, 0, sizeof(fdstr)); if (check_if_fd(childno) == TRUE) sprintf(fdstr, "(fd = %d)", (unsigned int) shm->syscall[childno].a1); output(0, "[%d] Stuck in syscall %d:%s%s%s.\n", pid, callno, print_syscall_name(callno, shm->syscall[childno].do32bit), shm->syscall[childno].do32bit ? " (32bit)" : "", fdstr); }
void check_parent_pid(void) { pid_t pid; unsigned int i; static unsigned int parent_check_time = 10; parent_check_time--; if (parent_check_time != 0) return; parent_check_time = 10; if (getppid() == shm->mainpid) return; pid = getpid(); //FIXME: Add locking so only one child does this output. output(0, BUGTXT "CHILD (pid:%d) GOT REPARENTED! " "parent pid:%d. Watchdog pid:%d\n", pid, shm->mainpid, watchdog_pid); output(0, BUGTXT "Last syscalls:\n"); for (i = 0; i < MAX_NR_CHILDREN; i++) { // Skip over 'boring' entries. if ((shm->pids[i] == -1) && (shm->previous_syscallno[i] == 0) && (shm->child_syscall_count[i] == 0)) continue; output(0, "[%d] pid:%d call:%s callno:%d\n", i, shm->pids[i], print_syscall_name(shm->previous_syscallno[i], shm->do32bit[i]), // FIXME: need previous do32bit shm->child_syscall_count[i]); } shm->exit_reason = EXIT_REPARENT_PROBLEM; exit(EXIT_FAILURE); //TODO: Emergency logging. }