Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Oct 2003 13:35:37 -0600 (CST)
From:      Dan Nelson <dnelson@allantgroup.com>
To:        FreeBSD-gnats-submit@FreeBSD.org
Subject:   kern/58647: itimers aren't cleared on fork()
Message-ID:  <200310281935.h9SJZbbu041495@dan.emsphone.com>
Resent-Message-ID: <200310281940.h9SJeJ2t034734@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         58647
>Category:       kern
>Synopsis:       itimers aren't cleared on fork()
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Tue Oct 28 11:40:18 PST 2003
>Closed-Date:
>Last-Modified:
>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:
>Unformatted:



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200310281935.h9SJZbbu041495>