From dan@dan.emsphone.com  Tue Oct 28 11:35:38 2003
Return-Path: <dan@dan.emsphone.com>
Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125])
	by hub.freebsd.org (Postfix) with ESMTP id 48AC216A4CE
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 28 Oct 2003 11:35:38 -0800 (PST)
Received: from dan.emsphone.com (dan.emsphone.com [199.67.51.101])
	by mx1.FreeBSD.org (Postfix) with ESMTP id 9CAE143FAF
	for <FreeBSD-gnats-submit@freebsd.org>; Tue, 28 Oct 2003 11:35:37 -0800 (PST)
	(envelope-from dan@dan.emsphone.com)
Received: (from dan@localhost)
	by dan.emsphone.com (8.12.9/8.12.9) id h9SJZbbu041495;
	Tue, 28 Oct 2003 13:35:37 -0600 (CST)
	(envelope-from dan)
Message-Id: <200310281935.h9SJZbbu041495@dan.emsphone.com>
Date: Tue, 28 Oct 2003 13:35:37 -0600 (CST)
From: Dan Nelson <dnelson@allantgroup.com>
Reply-To: Dan Nelson <dnelson@allantgroup.com>
To: FreeBSD-gnats-submit@freebsd.org
Cc:
Subject: itimers aren't cleared on fork()
X-Send-Pr-Version: 3.113
X-GNATS-Notify:

>Number:         58647
>Category:       kern
>Synopsis:       itimers aren't cleared on fork()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    jhb
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 28 11:40:18 PST 2003
>Closed-Date:    Thu Dec 11 11:31:29 PST 2003
>Last-Modified:  Thu Dec 11 11:31:29 PST 2003
>Originator:     Dan Nelson
>Release:        FreeBSD 5.1-CURRENT i386 / FreeBSD 4.8-RELEASE i386
>Organization:
The Allant Group, Inc.
>Environment:
System: FreeBSD dan.emsphone.com 5.1-CURRENT FreeBSD 5.1-CURRENT #295: Mon Oct 27 16:19:10 CST 2003 dan@dan.emsphone.com:/usr/src/sys/i386/compile/DANSMP i386


	
>Description:

POSIX says that all timers are cleared in the child after a fork()
(twice in fact):
http://www.opengroup.org/onlinepubs/007904975/functions/fork.html

[XSI] Interval timers shall be reset in the child process.

[TMR] Per-process timers created by the parent shall not be inherited by the child process.


FreeBSD 4.x and 5.x, however, only clear ITIMER_REAL.  ITIMER_VIRTUAL
and ITIMER_PROF both continue to fire in the child process.

This could cause problems for any program that uses those timers and
also forks (note that userland pthreads uses ITIMER_PROF for its
scheduling timer).  It definitely causes programs for threaded
debuggers, since the profile timer is firing the whole time between the
child calling ptrace(PT_TRACE_ME) and exec()'ing the debug target.

	
>How-To-Repeat:
	

Compile the following program and run it.  For each received signal, a
c or p (child/parent) will be printed, along with a R, V, or P (signal). 
"p:P", for example means the parent got a SIGPROF.  Any "c:" output
indicates a bug.

#include <unistd.h>
#include <sys/time.h>
#include <signal.h>

char pc = 'p';			/* parent or child */

static void sig_handler(int sig)
{
	/* print what signal we got, and whether we're child or parent, in
	   one atomic write */
	char array[4];
	array[0] = pc;
	array[1] = ':';
	array[2] = (sig == SIGPROF ? 'P' : sig == SIGVTALRM ? 'V' : sig == SIGALRM ? 'A' : '!');
	array[3] = ' ';
	write(1, &array, 4);
}

int main(int argc, char *argv[])
{
	struct itimerval itimer;
	struct sigaction act;

	sigemptyset(&act.sa_mask);
	act.sa_handler = sig_handler;
	act.sa_flags = SA_RESTART;
	sigaction(SIGPROF, &act, NULL);
	sigaction(SIGALRM, &act, NULL);
	sigaction(SIGVTALRM, &act, NULL);

	itimer.it_interval.tv_sec = 1;
	itimer.it_interval.tv_usec = 0;
	itimer.it_value = itimer.it_interval;
	setitimer(ITIMER_PROF, &itimer, NULL);
	setitimer(ITIMER_VIRTUAL, &itimer, NULL);
	setitimer(ITIMER_REAL, &itimer, NULL);
	if (fork() == 0)
		pc = 'c';
	for (;;)
		;
}


>Fix:

Unknown.  It looks like the real timer is stored in a different place
from the virtual and profiling timers, which might explain why only the
real timer is cleared during fork.

>Release-Note:
>Audit-Trail:

From: John Baldwin <jhb@FreeBSD.org>
To: freebsd-gnats-submit@FreeBSD.org
Cc:  
Subject: Re: kern/58647: itimers aren't cleared on fork()
Date: Tue, 28 Oct 2003 14:55:18 -0500 (EST)

 It seems that fork() doesn't explicitly clear the realtimer, rather
 p_realtimer is in the zero'd section of struct proc whereas the
 p_itimer array with the old real timer and the other two interval
 timers is in the copy section of p_stat.  The patch below moves
 p_itimer to the zero section of p_stat instead:
 
 Index: resourcevar.h
 ===================================================================
 RCS file: /usr/cvs/src/sys/sys/resourcevar.h,v
 retrieving revision 1.35
 diff -u -r1.35 resourcevar.h
 --- resourcevar.h       20 Apr 2003 13:54:04 -0000      1.35
 +++ resourcevar.h       28 Oct 2003 19:51:10 -0000
 @@ -52,11 +52,10 @@
  #define        pstat_startzero p_ru
         struct  rusage p_ru;            /* stats for this proc */
         struct  rusage p_cru;           /* sum of stats for reaped children */
 -#define        pstat_endzero   pstat_startcopy
 -
 -#define        pstat_startcopy p_timer
         struct  itimerval p_timer[3];   /* virtual-time timers */
 +#define        pstat_endzero   pstat_startcopy
  
 +#define        pstat_startcopy p_prof
         struct uprof {                  /* profile arguments */
                 caddr_t pr_base;        /* buffer base */
                 u_long  pr_size;        /* buffer size */
 
 -- 
 
 John Baldwin <jhb@FreeBSD.org>  <><  http://www.FreeBSD.org/~jhb/
 "Power Users Use the Power to Serve!"  -  http://www.FreeBSD.org/
State-Changed-From-To: open->patched 
State-Changed-By: jhb 
State-Changed-When: Tue Oct 28 12:46:31 PST 2003 
State-Changed-Why:  
Committed to current, pending MFC. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=58647 
Responsible-Changed-From-To: freebsd-bugs->jhb 
Responsible-Changed-By: jhb 
Responsible-Changed-When: Tue Oct 28 13:00:16 PST 2003 
Responsible-Changed-Why:  
I'll take this one. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=58647 
State-Changed-From-To: patched->closed 
State-Changed-By: jhb 
State-Changed-When: Thu Dec 11 11:31:14 PST 2003 
State-Changed-Why:  
Merged to 4.x.  Thanks! 

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