From owner-freebsd-bugs@FreeBSD.ORG Tue Dec 13 19:00:19 2005 Return-Path: X-Original-To: freebsd-bugs@hub.freebsd.org Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0233A16A41F for ; Tue, 13 Dec 2005 19:00:18 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5AE0843D5F for ; Tue, 13 Dec 2005 19:00:18 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.4/8.13.4) with ESMTP id jBDJ0IDc097639 for ; Tue, 13 Dec 2005 19:00:18 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.4/8.13.4/Submit) id jBDJ0HCF097638; Tue, 13 Dec 2005 19:00:17 GMT (envelope-from gnats) Date: Tue, 13 Dec 2005 19:00:17 GMT Message-Id: <200512131900.jBDJ0HCF097638@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org From: Maxim Konovalov Cc: Subject: Re: bin/90334: /bin/sh trap problem X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Maxim Konovalov List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 13 Dec 2005 19:00:19 -0000 The following reply was made to PR bin/90334; it has been noted by GNATS. From: Maxim Konovalov To: Dmitriy Kirhlarov Cc: bug-followup@freebsd.org, kst@oilspace.com Subject: Re: bin/90334: /bin/sh trap problem Date: Tue, 13 Dec 2005 21:51:01 +0300 (MSK) [...] > >Description: > on FreeBSD 5.* and FreeBSD 6.* sh scripts hanging with high > CPU load, when SIGCHLD used. > problem not present on 4-STABLE > >How-To-Repeat: > run simple script > --- > #!/bin/sh > trap "" 20 > var=`echo anytext | sed 's/text/any/'` > --- Yep, SIG_IGN as action for SIGCHLD works differ on RELENG_4 and post-RELENG_4. On post-RELENG_4 we can safely SIG_IGN SIGCHLD and the kernel will G/C zombies for us. From signal(3): % If a process explicitly specifies SIG_IGN as the action for the % signal SIGCHLD, the system will not create zombie processes when % children of the calling process exit. As a consequence, the system % will discard the exit status from the child processes. If the % calling process subsequently issues a call to wait(2) or equivalent, % it will block until all of the calling process's children terminate, % and then return a value of -1 with errno set to ECHILD. 'trap "" 20' sets SIG_IGN signal handler for SIGCHLD and we are getting ECHILD in jobs.c::waitproc() again and again and fall to the following endless loop in jobs.c::waitforjob(): %%% 865 while (jp->state == 0) 866 if (dowait(1, jp) == -1) 867 dotrap(); %%% There are two patches for the problem: 1/ Mine, if user sets an empty trap for SIGCHLD, use the default signal handler: Index: trap.c =================================================================== RCS file: /home/ncvs/src/bin/sh/trap.c,v retrieving revision 1.31 diff -u -r1.31 trap.c --- trap.c 8 Dec 2005 20:08:36 -0000 1.31 +++ trap.c 13 Dec 2005 18:18:07 -0000 @@ -238,6 +238,8 @@ action = S_CATCH; else action = S_IGN; + if (action == S_IGN && signo == SIGCHLD) + action = S_DFL; if (action == S_DFL) { switch (signo) { case SIGINT: %%% 2/ By your co-worker, Konstantin Stepanenkov, break an endless loop if we get ECHILD: Index: jobs.c =================================================================== RCS file: /home/ncvs/src/bin/sh/jobs.c,v retrieving revision 1.69 diff -u -r1.69 jobs.c --- jobs.c 5 Sep 2005 17:57:19 -0000 1.69 +++ jobs.c 13 Dec 2005 18:38:26 -0000 @@ -929,6 +929,8 @@ if (pid <= 0) return -1; } + if (errno == ECHILD) + job->state = 1; if (pid <= 0) return pid; INTOFF; %%% Not sure they are correct, need to think about the issue a bit more :-) -- Maxim Konovalov