[Crash-utility] crash CPU bound waiting for user response
Dave Anderson
anderson at redhat.com
Tue Jul 10 20:37:36 UTC 2007
D. Hugh Redelmeier wrote:
> | From: Dave Anderson <anderson at redhat.com>
>
> | Yeah, but I'm still paranoid about re-introducing the hang I used
> | to see.
> |
> | I think I'll just put a "stall(1000);" call after each waitpid().
> | Works for me...
>
> I take that as a challenge. I think that I've eliminated this
> busy-wait and simplified the code. I admit that wait_for_children is
> slightly more complicated.
>
> In light testing this worked fine. I'd really like to find out how
> this is going to hang. I promise to attempt to debug any hang that I
> can duplicate.
>
I didn't mean it as a challenge. I appreciate the effort, but
at this point I'm really not particularly interested in re-working
this area, especially since it can be so simply avoided with a stall.
Thanks,
Dave
> ===================================================================
> RCS file: RCS/cmdline.c,v
> retrieving revision 1.1
> diff -u -r1.1 cmdline.c
> --- cmdline.c 2007/07/10 19:30:01 1.1
> +++ cmdline.c 2007/07/10 20:16:57
> @@ -31,6 +31,7 @@
> static void set_my_tty(void);
> static char *signame(int);
> static int setup_stdpipe(void);
> +static void wait_for_child(pid_t *);
> static void wait_for_children(ulong);
> #define ZOMBIES_ONLY (1)
> #define ALL_CHILDREN (2)
> @@ -878,25 +879,15 @@
> if (pc->stdpipe) {
> close(fileno(pc->stdpipe));
> pc->stdpipe = NULL;
> - if (pc->stdpipe_pid && PID_ALIVE(pc->stdpipe_pid)) {
> - while (!waitpid(pc->stdpipe_pid, &waitstatus, WNOHANG))
> - ;
> - }
> - pc->stdpipe_pid = 0;
> + wait_for_child(&pc->stdpipe_pid);
> }
> if (pc->pipe) {
> close(fileno(pc->pipe));
> pc->pipe = NULL;
> console("wait for redirect %d->%d to finish...\n",
> pc->pipe_shell_pid, pc->pipe_pid);
> - if (pc->pipe_pid)
> - while (PID_ALIVE(pc->pipe_pid))
> - waitpid(pc->pipe_pid, &waitstatus, WNOHANG);
> - if (pc->pipe_shell_pid)
> - while (PID_ALIVE(pc->pipe_shell_pid))
> - waitpid(pc->pipe_shell_pid,
> - &waitstatus, WNOHANG);
> - pc->pipe_pid = 0;
> + wait_for_child(&pc->pipe_pid);
> + wait_for_child(&pc->pipe_shell_pid);
> }
> if (pc->ifile_pipe) {
> fflush(pc->ifile_pipe);
> @@ -907,12 +898,8 @@
> (FROM_INPUT_FILE|REDIRECT_TO_PIPE|REDIRECT_PID_KNOWN))) {
> console("wait for redirect %d->%d to finish...\n",
> pc->pipe_shell_pid, pc->pipe_pid);
> - while (PID_ALIVE(pc->pipe_pid))
> - waitpid(pc->pipe_pid, &waitstatus, WNOHANG);
> - if (pc->pipe_shell_pid)
> - while (PID_ALIVE(pc->pipe_shell_pid))
> - waitpid(pc->pipe_shell_pid,
> - &waitstatus, WNOHANG);
> + wait_for_child(&pc->pipe_pid);
> + wait_for_child(&pc->pipe_shell_pid);
> if (pc->redirect & (REDIRECT_MULTI_PIPE))
> wait_for_children(ALL_CHILDREN);
> }
> @@ -1967,7 +1954,7 @@
>
> if (CRASHDEBUG(2))
> console("pipe: %lx\n", pc->stdpipe);
> - return TRUE;;
> + return TRUE;
>
> } else {
> close(pc->pipefd[1]); /* child closes write end */
> @@ -1998,13 +1985,26 @@
> }
> }
>
> +static void
> +wait_for_child(pid_t *chp)
> +{
> + if (*chp != 0)
> + {
> + int waitstatus;
> +
> + do ; while (waitpid(*chp, &waitstatus, 0) == -1 && errno == EINTR);
> + *chp = 0;
> + }
> +}
> +
> static void
> wait_for_children(ulong waitflag)
> {
> - int status, pid;
> -
> while (TRUE) {
> - switch (pid = waitpid(-1, &status, WNOHANG))
> + int status;
> + pid_t pid = waitpid(-1, &status, waitflag==ZOMBIES_ONLY? WNOHANG : 0);
> +
> + switch (pid)
> {
> case 0:
> if (CRASHDEBUG(2))
> @@ -2014,6 +2014,8 @@
> break;
>
> case -1:
> + if (errno == EINTR)
> + continue;
> if (CRASHDEBUG(2))
> console("wait_for_children: no children alive\n");
> return;
> ================ end ================
>
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
More information about the Crash-utility
mailing list