From owner-freebsd-hackers@FreeBSD.ORG Mon Apr 18 09:20:04 2005 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1847016A4CE for ; Mon, 18 Apr 2005 09:20:04 +0000 (GMT) Received: from fw.zoral.com.ua (ll-227.216.82.212.sovam.net.ua [212.82.216.227]) by mx1.FreeBSD.org (Postfix) with ESMTP id AFC6643D55 for ; Mon, 18 Apr 2005 09:20:01 +0000 (GMT) (envelope-from konstantin.belousov@zoral.com.ua) Received: from deviant.zoral.local (root@kostik.zoral.local [10.1.1.38]) by fw.zoral.com.ua (8.13.1/8.13.1) with ESMTP id j3I9Kb1n071321 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO) for ; Mon, 18 Apr 2005 12:20:37 +0300 (EEST) (envelope-from konstantin.belousov@zoral.com.ua) Received: from deviant.zoral.local (kostik@localhost [127.0.0.1]) by deviant.zoral.local (8.13.3/8.13.3) with ESMTP id j3I9KdUT031763 for ; Mon, 18 Apr 2005 12:20:39 +0300 (EEST) (envelope-from konstantin.belousov@zoral.com.ua) Received: (from kostik@localhost) by deviant.zoral.local (8.13.3/8.13.3/Submit) id j3I9KdXj031762 for freebsd-hackers@freebsd.org; Mon, 18 Apr 2005 12:20:39 +0300 (EEST) (envelope-from konstantin.belousov@zoral.com.ua) X-Authentication-Warning: deviant.zoral.local: kostik set sender to konstantin.belousov@zoral.com.ua using -f Date: Mon, 18 Apr 2005 12:20:39 +0300 From: Kostik Belousov To: freebsd-hackers@freebsd.org Message-ID: <20050418092038.GB984@deviant.zoral.local> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="yrj/dFKFPuw6o+aM" Content-Disposition: inline User-Agent: Mutt/1.4.2.1i X-Virus-Scanned: ClamAV 0.82/837/Sun Apr 17 18:25:32 2005 on fw.zoral.com.ua X-Virus-Status: Clean Subject: sigprocmask and fork X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 18 Apr 2005 09:20:04 -0000 --yrj/dFKFPuw6o+aM Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Hi, I come across the following problem: after fork(), the 5-STABLE system sets the child process blocked signal mask to 0 (let us account single-threaded processes only). I was under impression that signal mask shall be inherited by the child process (according to SUSv3 and man fork). Inheritance _was_ the behaviour of 4-STABLE (there, p_sigmask belongs to struct proc and placed in the copied-on-fork part of the structure) and also seen on other UNIXes (e.g. Solaris). After googling, I found the comment by Dong Xuezhang in http://lists.freebsd.org/pipermail/freebsd-threads/2005-February/002899.html where he said that "Actually fork() do not copy the properties of signal mask". I confirm that fork does not copy mask, but why ? Attached is the program that illustrates this issue on pooma% uname -a ~/work/bsd/sigmask FreeBSD pooma.home 5.4-STABLE FreeBSD 5.4-STABLE #32: Fri Apr 15 22:16:43 EEST 2005 root@pooma.home:/usr/obj/usr/src/sys/POOMA i386 On unpatched 5-STABLE, the child process reports SIGUSR2 immediately after start, despite parent blocked SIGUSR2 before forking. It seems that needs of thread_schedule_upcall() to zero sigmask interfere with the needs of the fork1(). I propose the trivial patch (against 5-STABLE) to fix the problems. It handles td_sigmask in the way similar to td_sigstk, that is also zeroed on _upcall(), as was done by davidxu at kern/kern_fork.c:1.209 rev. Index: kern/kern_fork.c =================================================================== RCS file: /usr/local/arch/ncvs/src/sys/kern/kern_fork.c,v retrieving revision 1.234.2.8 diff -U5 -r1.234.2.8 kern_fork.c --- kern/kern_fork.c 27 Feb 2005 02:36:39 -0000 1.234.2.8 +++ kern/kern_fork.c 18 Apr 2005 08:58:50 -0000 @@ -470,10 +470,11 @@ __rangeof(struct thread, td_startcopy, td_endcopy)); bcopy(&td->td_ksegrp->kg_startcopy, &kg2->kg_startcopy, __rangeof(struct ksegrp, kg_startcopy, kg_endcopy)); td2->td_sigstk = td->td_sigstk; + td2->td_sigmask = td->td_sigmask; /* * Duplicate sub-structures as needed. * Increase reference counts on shared objects. */ Thanks for attention, Kostik Belousov. --yrj/dFKFPuw6o+aM Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="sigmask1.cc" #include #include #include #include #include #include extern "C" void sigusr2_handler(int signo) { static const char msg[] = "SIGUSR2\n"; write(2, msg, sizeof(msg) - 1); _exit(0); } int main(int argc, char *argv[]) { struct sigaction sa; memset(&sa, 0, sizeof(sa)); sa.sa_handler = sigusr2_handler; sigaction(SIGUSR2, &sa, NULL); sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGUSR2); sigprocmask(SIG_BLOCK, &mask, NULL); pid_t child = fork(); if (child == 0) { raise(SIGUSR2); printf("sleeping\n"); sleep(10); printf("enabling SIGUSR2\n"); sigprocmask(SIG_UNBLOCK, &mask, NULL); while (true) ; } int status; wait(&status); return 0; } --yrj/dFKFPuw6o+aM--