From dkirhlarov@oilspace.com  Tue Dec 13 14:35:26 2005
Return-Path: <dkirhlarov@oilspace.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 4E25016A41F
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 13 Dec 2005 14:35:26 +0000 (GMT)
	(envelope-from dkirhlarov@oilspace.com)
Received: from office.oilspace.com (office.oilspace.com [194.129.65.230])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 7E3D543D67
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 13 Dec 2005 14:35:25 +0000 (GMT)
	(envelope-from dkirhlarov@oilspace.com)
Received: from dimma.mow.oilspace.com (proxy-mow.oilspace.com [81.19.78.190])
	(using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits))
	(No client certificate requested)
	by office.oilspace.com (Postfix) with ESMTP id 32EDD136E39
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 13 Dec 2005 14:35:23 +0000 (GMT)
Received: from dimma.mow.oilspace.com (localhost [127.0.0.1])
	by dimma.mow.oilspace.com (8.13.4/8.13.3) with ESMTP id jBDEZMMg004379
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 13 Dec 2005 17:35:22 +0300 (MSK)
	(envelope-from dkirhlarov@dimma.mow.oilspace.com)
Received: (from dkirhlarov@localhost)
	by dimma.mow.oilspace.com (8.13.4/8.13.3/Submit) id jBDEZMg1004378;
	Tue, 13 Dec 2005 17:35:22 +0300 (MSK)
	(envelope-from dkirhlarov)
Message-Id: <200512131435.jBDEZMg1004378@dimma.mow.oilspace.com>
Date: Tue, 13 Dec 2005 17:35:22 +0300 (MSK)
From: Dmitriy Kirhlarov <dkirhlarov@oilspace.com>
Reply-To: Dmitriy Kirhlarov <dkirhlarov@oilspace.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: /bin/sh trap problem
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         90334
>Category:       bin
>Synopsis:       [patch] sh(1) loops forever if SIGCHLD is caught (regression)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    maxim
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Dec 13 14:40:02 GMT 2005
>Closed-Date:    Thu Jan 12 05:25:43 GMT 2006
>Last-Modified:  Thu Jan 12 05:25:43 GMT 2006
>Originator:     Dmitriy Kirhlarov
>Release:        FreeBSD 5.4-STABLE i386
>Organization:
dimma
>Environment:
System: FreeBSD dimma.mow.oilspace.com 5.4-STABLE FreeBSD 5.4-STABLE #0: Sun Sep 25 23:26:13 MSD 2005 root@dimma.mow.oilspace.com:/usr/obj/usr/src/sys/dimma i386

FreeBSD fbsd.mow.oilspace.com 6.0-STABLE FreeBSD 6.0-STABLE #6: Thu Nov 24 15:26:53 GMT 2005     root@fbsd.mow.oilspace.com:/usr/obj/usr/src/sys/oilspace  i386

>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/'`
---

>Fix:

	don't know


>Release-Note:
>Audit-Trail:

From: Maxim Konovalov <maxim@macomnet.ru>
To: Dmitriy Kirhlarov <dkirhlarov@oilspace.com>
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

From: Maxim Konovalov <maxim@macomnet.ru>
To: Dmitriy Kirhlarov <dkirhlarov@oilspace.com>
Cc: bug-followup@freebsd.org, kst@oilspace.com
Subject: Re: bin/90334: /bin/sh trap problem
Date: Wed, 14 Dec 2005 12:36:50 +0300 (MSK)

 [...]
 > 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;
 > %%%
 
 BDE has more elegant version of this patch:
 
 Index: sh/jobs.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/sh/jobs.c,v
 retrieving revision 1.69
 diff -u -r1.69 jobs.c
 --- sh/jobs.c	5 Sep 2005 17:57:19 -0000	1.69
 +++ sh/jobs.c	14 Dec 2005 09:35:03 -0000
 @@ -924,6 +924,8 @@
  	} while ((pid == -1 && errno == EINTR && breakwaitcmd == 0) ||
  		 (pid > 0 && WIFSTOPPED(status) && !iflag));
  	in_dowait--;
 +	if (pid == -1 && errno == ECHILD && job != NULL)
 +		job->state = JOBDONE;
  	if (breakwaitcmd != 0) {
  		breakwaitcmd = 0;
  		if (pid <= 0)
 %%%
 
 I am going to commit it after some tests.
 
 -- 
 Maxim Konovalov
State-Changed-From-To: open->patched 
State-Changed-By: maxim 
State-Changed-When: Wed Dec 14 17:26:48 UTC 2005 
State-Changed-Why:  
Fixed in HEAD.  I'll MFC the fix in 4 weeks.  Thanks for the report! 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90334 
Responsible-Changed-From-To: freebsd-bugs->maxim 
Responsible-Changed-By: maxim 
Responsible-Changed-When: Wed Dec 14 17:27:45 UTC 2005 
Responsible-Changed-Why:  
MFC reminder. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90334 
State-Changed-From-To: patched->closed 
State-Changed-By: maxim 
State-Changed-When: Thu Jan 12 05:25:27 UTC 2006 
State-Changed-Why:  
MFC'ed to RELENG_6. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=90334 
>Unformatted:
