Date: Thu, 1 Apr 1999 23:11:00 +0100 From: dmlb@ragnet.demon.co.uk To: FreeBSD-gnats-submit@freebsd.org Cc: dmlb@ragnet.demon.co.uk Subject: bin/10912: Problems with job control in bin/sh and fix. Message-ID: <E10Spfw-0000Je-00@ragnet.demon.co.uk>
index | next in thread | raw e-mail
>Number: 10912
>Category: bin
>Synopsis: Fix to prevent infinite loops on missing children
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Thu Apr 1 15:20:01 PST 1999
>Closed-Date:
>Last-Modified:
>Originator: Duncan Barclay
>Release: FreeBSD 2.2.6-RELEASE i386
>Organization:
>Environment:
3.1 release used for testing. Full CVS repository available
locally.
>Description:
Code in jobs.c dowait() fails when a child is reaped and breakwaitcmd
is set. The shell thinks there is a job waiting to be reaped which
has already exit'd. It then loops forever calling dowait() trying to
find its lost child.
This occurs when a sub-shell is invoked by a trap - the sub shell has
breakwaitcmd set on entry to dowait() but the wait will also reap the
child. dowait() exits because of breakwaitcmd and does not update the
job status.
/bin/sh before 1998 09 07 does not exhibit this behaviour, this is when
background execution of traps was added.
Example:
In .env I have
_winch(){
foo=$(stty -a | sed ....)
....
}
trap _winch 28
Turning on DEBUG and obseving trace output (I've added a getpid to
trace() so I can follow this). Also I have changed onsig() in trap.c
to set breakwaitcmd to the signal number so I can see it happen.
PID 8679 is the backquote sub-shell.
PID 8680 is the stty process.
[8679] In parent shell: child = 8680
[8679] searchexec "sed" returns "/usr/bin/sed"
[8679] forkshell(%0, 0x80aa4dc, 0) called
[8679] In parent shell: child = 8681
[8679] waitforjob(%1) called *** 8679 waits for stty
*** to finish
[8679] dowait(1) called, breakwaitcmd = 128 *** trouble brewing
[8680] Child shell 8680
[8680] evaltree(0x80aa4a4: 1) called
[8680] evalcommand(0x80aa4a4, 1) called
[8680] evalcommand arg: stty
[8680] evalcommand arg: -a *** stty completes
[8679] wait returns 8680, status=0 *** stty is reaped
[8679] dowait returning because breakwaitcmd = 128 *** oh s**t!!!!
I've "fixed" this by checking that in_waitcmd is set in the signal
handler, but this may not be "right". I'm not entirely sure that the
breakwaitcmd code is right in dowait() as it doesn't check that the wait
returned due to a signal to this process.
Patches below to add pid to trace logging and the in_waitcmd check.
Index: sh/show.c
===================================================================
RCS file: /ide0.e/ncvs/src/bin/sh/show.c,v
retrieving revision 1.9
diff -u -r1.9 show.c
--- show.c 1998/05/18 06:44:19 1.9
+++ show.c 1999/04/01 22:25:05
@@ -316,6 +316,7 @@
fmt = va_arg(va, char *);
#endif
if (tracefile != NULL) {
+ (void) fprintf(tracefile, "[%d] ", getpid());
(void) vfprintf(tracefile, fmt, va);
if (strchr(fmt, '\n'))
(void) fflush(tracefile);
Index: sh/trap.c
===================================================================
RCS file: /ide0.e/ncvs/src/bin/sh/trap.c,v
retrieving revision 1.17
diff -u -r1.17 trap.c
--- trap.c 1998/09/10 22:09:11 1.17
+++ trap.c 1999/04/01 22:37:20
@@ -362,15 +362,15 @@
/* If we are currently in a wait builtin, prepare to break it */
if ((signo == SIGINT || signo == SIGQUIT) && in_waitcmd != 0)
- breakwaitcmd = 1;
+ breakwaitcmd = signo;
/*
* If a trap is set, not ignored and not the null command, we need
* to make sure traps are executed even when a child blocks signals.
*/
- if (trap[signo] != NULL &&
+ if (in_waitcmd != 0 && trap[signo] != NULL &&
! trap[signo][0] == '\0' &&
! (trap[signo][0] == ':' && trap[signo][1] == '\0'))
- breakwaitcmd = 1;
+ breakwaitcmd = 1000*signo+in_waitcmd;
}
Duncan
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?E10Spfw-0000Je-00>
