From owner-freebsd-threads@FreeBSD.ORG Mon Feb 14 11:07:15 2011 Return-Path: Delivered-To: freebsd-threads@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0D356106570A for ; Mon, 14 Feb 2011 11:07:15 +0000 (UTC) (envelope-from owner-bugmaster@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D36168FC2D for ; Mon, 14 Feb 2011 11:07:14 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p1EB7EfR077331 for ; Mon, 14 Feb 2011 11:07:14 GMT (envelope-from owner-bugmaster@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p1EB7E4Z077328 for freebsd-threads@FreeBSD.org; Mon, 14 Feb 2011 11:07:14 GMT (envelope-from owner-bugmaster@FreeBSD.org) Date: Mon, 14 Feb 2011 11:07:14 GMT Message-Id: <201102141107.p1EB7E4Z077328@freefall.freebsd.org> X-Authentication-Warning: freefall.freebsd.org: gnats set sender to owner-bugmaster@FreeBSD.org using -f From: FreeBSD bugmaster To: freebsd-threads@FreeBSD.org Cc: Subject: Current problem reports assigned to freebsd-threads@FreeBSD.org X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Feb 2011 11:07:15 -0000 Note: to view an individual PR, use: http://www.freebsd.org/cgi/query-pr.cgi?pr=(number). The following is a listing of current problems submitted by FreeBSD users. These represent problem reports covering all versions including experimental development code and obsolete releases. S Tracker Resp. Description -------------------------------------------------------------------------------- o threa/150959 threads [libc] Stub pthread_once in libc should call _libc_onc o threa/149366 threads pthread_cleanup_pop never runs the configured routine o threa/148515 threads Memory / syslog strangeness in FreeBSD 8.x ( possible o threa/141721 threads rtprio(1): (id|rt)prio priority resets when new thread o threa/136345 threads Recursive read rwlocks in thread A cause deadlock with o threa/135673 threads databases/mysql50-server - MySQL query lock-ups on 7.2 o threa/133734 threads 32 bit libthr failing pthread_create() o threa/128922 threads threads hang with xorg running o threa/127225 threads bug in lib/libthr/thread/thr_init.c o threa/122923 threads 'nice' does not prevent background process from steali o threa/121336 threads lang/neko threading ok on UP, broken on SMP (FreeBSD 7 o threa/116668 threads can no longer use jdk15 with libthr on -stable SMP o threa/116181 threads /dev/io-related io access permissions are not propagat o threa/115211 threads pthread_atfork misbehaves in initial thread o threa/110636 threads [request] gdb(1): using gdb with multi thread applicat o threa/110306 threads apache 2.0 segmentation violation when calling gethost o threa/103975 threads Implicit loading/unloading of libpthread.so may crash o threa/101323 threads [patch] fork(2) in threaded programs broken. f threa/100815 threads FBSD 5.5 broke nanosleep in libc_r s threa/84483 threads problems with devel/nspr and -lc_r on 4.x o threa/80992 threads abort() sometimes not caught by gdb depending on threa o threa/79683 threads svctcp_create() fails if multiple threads call at the s threa/76694 threads fork cause hang in dup()/close() function in child (-l s threa/76690 threads fork hang in child for -lc_r s threa/69020 threads pthreads library leaks _gc_mutex s threa/48856 threads Setting SIGCHLD to SIG_IGN still leaves zombies under s threa/40671 threads pthread_cancel doesn't remove thread from condition qu s threa/34536 threads accept() blocks other threads s threa/30464 threads pthread mutex attributes -- pshared 29 problems total. From owner-freebsd-threads@FreeBSD.ORG Fri Feb 18 09:56:11 2011 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3E2A81065673; Fri, 18 Feb 2011 09:56:11 +0000 (UTC) (envelope-from brucec@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id 1495C8FC18; Fri, 18 Feb 2011 09:56:11 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p1I9uAUi065924; Fri, 18 Feb 2011 09:56:10 GMT (envelope-from brucec@freefall.freebsd.org) Received: (from brucec@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p1I9uAUV065920; Fri, 18 Feb 2011 09:56:10 GMT (envelope-from brucec) Date: Fri, 18 Feb 2011 09:56:10 GMT Message-Id: <201102180956.p1I9uAUV065920@freefall.freebsd.org> To: ssanders@opnet.com, brucec@FreeBSD.org, freebsd-threads@FreeBSD.org From: brucec@FreeBSD.org Cc: Subject: Re: threads/133734: 32 bit libthr failing pthread_create() X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 18 Feb 2011 09:56:11 -0000 Synopsis: 32 bit libthr failing pthread_create() State-Changed-From-To: open->closed State-Changed-By: brucec State-Changed-When: Fri Feb 18 09:54:04 UTC 2011 State-Changed-Why: Submitter reports that the problem was fixed by linking with libthr. http://www.freebsd.org/cgi/query-pr.cgi?pr=133734 From owner-freebsd-threads@FreeBSD.ORG Sat Feb 19 18:10:13 2011 Return-Path: Delivered-To: freebsd-threads@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 21E021065673 for ; Sat, 19 Feb 2011 18:10:13 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:4f8:fff6::28]) by mx1.freebsd.org (Postfix) with ESMTP id D7F088FC1C for ; Sat, 19 Feb 2011 18:10:12 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.4/8.14.4) with ESMTP id p1JIACSE075491 for ; Sat, 19 Feb 2011 18:10:12 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id p1JIACTi075490; Sat, 19 Feb 2011 18:10:12 GMT (envelope-from gnats) Resent-Date: Sat, 19 Feb 2011 18:10:12 GMT Resent-Message-Id: <201102191810.p1JIACTi075490@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-threads@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, KOSAKI Motohiro Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 195E3106566C for ; Sat, 19 Feb 2011 18:09:54 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22]) by mx1.freebsd.org (Postfix) with ESMTP id 07E2D8FC12 for ; Sat, 19 Feb 2011 18:09:54 +0000 (UTC) Received: from red.freebsd.org (localhost [127.0.0.1]) by red.freebsd.org (8.14.4/8.14.4) with ESMTP id p1JI9rDc063562 for ; Sat, 19 Feb 2011 18:09:53 GMT (envelope-from nobody@red.freebsd.org) Received: (from nobody@localhost) by red.freebsd.org (8.14.4/8.14.4/Submit) id p1JI9rZi063561; Sat, 19 Feb 2011 18:09:53 GMT (envelope-from nobody) Message-Id: <201102191809.p1JI9rZi063561@red.freebsd.org> Date: Sat, 19 Feb 2011 18:09:53 GMT From: KOSAKI Motohiro To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: threads/154893: pthread_sigmask don't work if mask and oldmask are passed the same pointer X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Feb 2011 18:10:13 -0000 >Number: 154893 >Category: threads >Synopsis: pthread_sigmask don't work if mask and oldmask are passed the same pointer >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-threads >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sat Feb 19 18:10:12 UTC 2011 >Closed-Date: >Last-Modified: >Originator: KOSAKI Motohiro >Release: 8.1 >Organization: >Environment: FreeBSD FreeBSD8 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:36:49 UTC 2010 root@mason.cse.buffalo.edu:/\ usr/obj/usr/src/sys/GENERIC amd64 >Description: Programmers expect pthread_sigmask(SIG_SETMASK, &msk, &msk) mean 1) rewritten signal mask by msk. 2) and, return old signal mask to msk. But, FreeBSD doesn't. Its pthread_sigmask behave the same as pthread_sigmask(SIG_SETMASK, NULL, &msk). It is very strange to me. Sidenote: man sigprocmask says its type is below. int sigprocmask(int how, const sigset_t * restrict set, sigset_t * restrict oset); It is not POSIX compliant nor user friendly. But the man page clealy describe set==oset is invalid. At least, pthread_sigmask's man page shold be fixed if uthread maintainers woun't fix this issue. Sidenote2: This is a source of signal breakage of ruby trunk. http://redmine.ruby-lang.org/issues/show/4173 >How-To-Repeat: run following program ------------------------------------------------------ #include #include #include void* func(void* arg) { sigset_t old; sigset_t add; int i; sigemptyset(&old); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("before: "); for (i=0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); sigemptyset(&add); sigaddset(&add, SIGUSR1); pthread_sigmask(SIG_BLOCK, &add, NULL); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("after: "); for (i=0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); return 0; } void* func2(void* arg) { sigset_t old; sigset_t add; int i; sigemptyset(&old); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("before: "); for (i=0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); sigemptyset(&add); sigaddset(&add, SIGUSR1); pthread_sigmask(SIG_BLOCK, &add, &old); printf("after: "); for (i=0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); return 0; } int main(void) { pthread_t thr; void* ret; printf("correct case: \n"); pthread_create(&thr, NULL, func, NULL); pthread_join(thr, &ret); printf("incorrect case: \n"); pthread_create(&thr, NULL, func2, NULL); pthread_join(thr, &ret); return 0; } >Fix: /usr/src/lib/libc_r/uthread/uthread_sigmask.c has following code. ----------------------------------------------------------------- int _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) { struct pthread *curthread = _get_curthread(); sigset_t sigset; int ret = 0; /* Check if the existing signal process mask is to be returned: */ if (oset != NULL) { /* Return the current mask: */ *oset = curthread->sigmask; // (1) } /* Check if a new signal set was provided by the caller: */ if (set != NULL) { (snip) } ---------------------------------------------------- Then, if set == oset, set argument was override before use it at (1). To introduce temporary variable fix this issue easily. >Release-Note: >Audit-Trail: >Unformatted: From owner-freebsd-threads@FreeBSD.ORG Sat Feb 19 18:43:53 2011 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id B6084106564A for ; Sat, 19 Feb 2011 18:43:53 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 20B1F8FC19 for ; Sat, 19 Feb 2011 18:43:52 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id p1JIhnHD064595 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 19 Feb 2011 20:43:49 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id p1JIhnDe028810; Sat, 19 Feb 2011 20:43:49 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id p1JIhmun028809; Sat, 19 Feb 2011 20:43:48 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Sat, 19 Feb 2011 20:43:48 +0200 From: Kostik Belousov To: KOSAKI Motohiro Message-ID: <20110219184348.GK78089@deviant.kiev.zoral.com.ua> References: <201102191809.p1JI9rZi063561@red.freebsd.org> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="6dVRKsw9Fpbr3VPY" Content-Disposition: inline In-Reply-To: <201102191809.p1JI9rZi063561@red.freebsd.org> User-Agent: Mutt/1.4.2.3i X-Spam-Status: No, score=-3.4 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: threads/154893: pthread_sigmask don't work if mask and oldmask are passed the same pointer X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Feb 2011 18:43:53 -0000 --6dVRKsw9Fpbr3VPY Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sat, Feb 19, 2011 at 06:09:53PM +0000, KOSAKI Motohiro wrote: >=20 > >Number: 154893 > >Category: threads > >Synopsis: pthread_sigmask don't work if mask and oldmask are passe= d the same pointer > >Confidential: no > >Severity: non-critical > >Priority: low > >Responsible: freebsd-threads > >State: open > >Quarter: =20 > >Keywords: =20 > >Date-Required: > >Class: sw-bug > >Submitter-Id: current-users > >Arrival-Date: Sat Feb 19 18:10:12 UTC 2011 > >Closed-Date: > >Last-Modified: > >Originator: KOSAKI Motohiro > >Release: 8.1 > >Organization: > >Environment: > FreeBSD FreeBSD8 8.1-RELEASE FreeBSD 8.1-RELEASE #0: Mon Jul 19 02:36:49 = UTC 2010 root@mason.cse.buffalo.edu:/\ > usr/obj/usr/src/sys/GENERIC amd64 > >Description: > Programmers expect pthread_sigmask(SIG_SETMASK, &msk, &msk) mean > 1) rewritten signal mask by msk. > 2) and, return old signal mask to msk. >=20 > But, FreeBSD doesn't. Its pthread_sigmask behave the same as=20 > pthread_sigmask(SIG_SETMASK, NULL, &msk). It is very strange to me. >=20 > Sidenote: > man sigprocmask says its type is below. >=20 > int > sigprocmask(int how, const sigset_t * restrict set, > sigset_t * restrict oset); >=20 > It is not POSIX compliant nor user friendly. But the man page > clealy describe set=3D=3Doset is invalid. > At least, pthread_sigmask's man page shold be fixed if uthread maintainers > woun't fix this issue. Note that POSIX requires the following prototypes for the sigprocmask and pthread_sigmask: int pthread_sigmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); int sigprocmask(int how, const sigset_t *restrict set, sigset_t *restrict oset); The restrict keyword explicitely disallows the case of set =3D=3D oset, so I think the behaviour is undefined by POSIX, and our implementation is correct. On the other hand, pthread_sigmask(3) manpage needs update to add restrict, and include/signal.h also ought to be changed. >=20 >=20 > Sidenote2: > This is a source of signal breakage of ruby trunk. > http://redmine.ruby-lang.org/issues/show/4173 I would say that ruby has a bug then. > >How-To-Repeat: > run following program >=20 > ------------------------------------------------------ > #include > #include > #include >=20 > void* func(void* arg) > { > sigset_t old; > sigset_t add; > int i; >=20 > sigemptyset(&old); > pthread_sigmask(SIG_BLOCK, NULL, &old); >=20 > printf("before: "); > for (i=3D0; i<4; i++) > printf(" %08x", old.__bits[i]); > printf("\n"); >=20 > sigemptyset(&add); > sigaddset(&add, SIGUSR1); > pthread_sigmask(SIG_BLOCK, &add, NULL); > pthread_sigmask(SIG_BLOCK, NULL, &old); >=20 > printf("after: "); > for (i=3D0; i<4; i++) > printf(" %08x", old.__bits[i]); > printf("\n"); >=20 > return 0; > } >=20 > void* func2(void* arg) > { > sigset_t old; > sigset_t add; > int i; >=20 > sigemptyset(&old); > pthread_sigmask(SIG_BLOCK, NULL, &old); >=20 > printf("before: "); > for (i=3D0; i<4; i++) > printf(" %08x", old.__bits[i]); > printf("\n"); >=20 > sigemptyset(&add); > sigaddset(&add, SIGUSR1); > pthread_sigmask(SIG_BLOCK, &add, &old); >=20 > printf("after: "); > for (i=3D0; i<4; i++) > printf(" %08x", old.__bits[i]); > printf("\n"); >=20 > return 0; > } >=20 > int main(void) > { > pthread_t thr; > void* ret; >=20 > printf("correct case: \n"); > pthread_create(&thr, NULL, func, NULL); > pthread_join(thr, &ret); >=20 > printf("incorrect case: \n"); > pthread_create(&thr, NULL, func2, NULL); > pthread_join(thr, &ret); >=20 >=20 > return 0; > } >=20 >=20 > >Fix: > /usr/src/lib/libc_r/uthread/uthread_sigmask.c has following code. > ----------------------------------------------------------------- > int > _pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) > { > struct pthread *curthread =3D _get_curthread(); > sigset_t sigset; > int ret =3D 0; >=20 > /* Check if the existing signal process mask is to be returned: */ > if (oset !=3D NULL) { > /* Return the current mask: */ > *oset =3D curthread->sigmask; // (1) > } > /* Check if a new signal set was provided by the caller: */ > if (set !=3D NULL) { >=20 > (snip) >=20 > } > ---------------------------------------------------- >=20 > Then, if set =3D=3D oset, set argument was override before use it at (1). > To introduce temporary variable fix this issue easily. libc_r is unused. Real implementation is in lib/libthr, that already has a twist that would not allow the override for case of action !=3D SIG_UNBLOCK. Moreover, the kernel side of sigprocmask(2) implementation first copies new set into kernel VA, and only then copies old mask out. Your example does not supply oset =3D=3D set to the pthread_sigmask, meantime. I really do not see anything wrong with the output of the program that supposed to illustrate the issue. The func() adds SIGUSR1 to the mask with second call to pthread_sigmask(SIG_BLOCK, &add, NULL);. Then, third call correctly returns SIGUSR1 in the mask. On the other hand, func2() sets SIGUSR1 as blocked and retrieves the previous mask in single atomic action. Since SIGUSR1 was not blocked before the call, old sigset correctly indicates it as "not blocked". The only change that I see as needed now is the following cosmetics: commit 49287c24fc46f342b46db1fae3fe9982bfbf7ed9 Author: Konstantin Belousov Date: Sat Feb 19 20:41:46 2011 +0200 Add restrict keyword to pthread_sigmask prototype and manpage diff --git a/include/signal.h b/include/signal.h index 4a4cd17..52a611c 100644 --- a/include/signal.h +++ b/include/signal.h @@ -69,7 +69,8 @@ int raise(int); #if __POSIX_VISIBLE || __XSI_VISIBLE int kill(__pid_t, int); int pthread_kill(__pthread_t, int); -int pthread_sigmask(int, const __sigset_t *, __sigset_t *); +int pthread_sigmask(int, const __sigset_t *__restrict, + __sigset_t * __restrict); int sigaction(int, const struct sigaction * __restrict, struct sigaction * __restrict); int sigaddset(sigset_t *, int); diff --git a/share/man/man3/pthread_sigmask.3 b/share/man/man3/pthread_sigm= ask.3 index c412543..013ba7c 100644 --- a/share/man/man3/pthread_sigmask.3 +++ b/share/man/man3/pthread_sigmask.3 @@ -26,7 +26,7 @@ .\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" .\" $FreeBSD$ -.Dd April 27, 2000 +.Dd February 19, 2011 .Dt PTHREAD_SIGMASK 3 .Os .Sh NAME @@ -38,7 +38,8 @@ .In pthread.h .In signal.h .Ft int -.Fn pthread_sigmask "int how" "const sigset_t *set" "sigset_t *oset" +.Fn pthread_sigmask "int how" "const sigset_t * restrict set" \ + "sigset_t * restrict oset" .Sh DESCRIPTION The .Fn pthread_sigmask --6dVRKsw9Fpbr3VPY Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (FreeBSD) iEYEARECAAYFAk1gD2QACgkQC3+MBN1Mb4hA4ACfT9c/CjA8sySNsniK0KBnDKSN ne8AnjgDnRM4SC0mskWyh3+CdlnNw7zJ =h3U2 -----END PGP SIGNATURE----- --6dVRKsw9Fpbr3VPY-- From owner-freebsd-threads@FreeBSD.ORG Sat Feb 19 19:42:47 2011 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D8997106566B for ; Sat, 19 Feb 2011 19:42:47 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from mail.zoral.com.ua (mx0.zoral.com.ua [91.193.166.200]) by mx1.freebsd.org (Postfix) with ESMTP id 746BA8FC0A for ; Sat, 19 Feb 2011 19:42:46 +0000 (UTC) Received: from deviant.kiev.zoral.com.ua (root@deviant.kiev.zoral.com.ua [10.1.1.148]) by mail.zoral.com.ua (8.14.2/8.14.2) with ESMTP id p1JJghiC068034 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Sat, 19 Feb 2011 21:42:43 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: from deviant.kiev.zoral.com.ua (kostik@localhost [127.0.0.1]) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4) with ESMTP id p1JJgh7T029095; Sat, 19 Feb 2011 21:42:43 +0200 (EET) (envelope-from kostikbel@gmail.com) Received: (from kostik@localhost) by deviant.kiev.zoral.com.ua (8.14.4/8.14.4/Submit) id p1JJghi4029094; Sat, 19 Feb 2011 21:42:43 +0200 (EET) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: deviant.kiev.zoral.com.ua: kostik set sender to kostikbel@gmail.com using -f Date: Sat, 19 Feb 2011 21:42:43 +0200 From: Kostik Belousov To: KOSAKI Motohiro Message-ID: <20110219194243.GL78089@deviant.kiev.zoral.com.ua> References: <201102191809.p1JI9rZi063561@red.freebsd.org> <20110219184348.GK78089@deviant.kiev.zoral.com.ua> Mime-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary="fBKP4Km0jCX9yvBB" Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.4.2.3i X-Spam-Status: No, score=-3.4 required=5.0 tests=ALL_TRUSTED,AWL,BAYES_00, DNS_FROM_OPENWHOIS autolearn=no version=3.2.5 X-Spam-Checker-Version: SpamAssassin 3.2.5 (2008-06-10) on skuns.kiev.zoral.com.ua Cc: freebsd-threads@freebsd.org Subject: Re: threads/154893: pthread_sigmask don't work if mask and oldmask are passed the same pointer X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Feb 2011 19:42:47 -0000 --fBKP4Km0jCX9yvBB Content-Type: text/plain; charset=us-ascii Content-Disposition: inline Content-Transfer-Encoding: quoted-printable On Sun, Feb 20, 2011 at 04:22:46AM +0900, KOSAKI Motohiro wrote: > > Your example does not supply oset =3D=3D set to the pthread_sigmask, > > meantime. I really do not see anything wrong with the output of > > the program that supposed to illustrate the issue. >=20 > Oh, I'm sorry. It's cut-n-paste mistake. I did paste old version > unintensionally. >=20 > void* func2(void* arg) > { > sigset_t old; > sigset_t add; > int i; >=20 > sigemptyset(&old); > pthread_sigmask(SIG_BLOCK, NULL, &old); >=20 > printf("before: "); > for (i=3D0; i<4; i++) > printf(" %08x", old.__bits[i]); > printf("\n"); >=20 > sigemptyset(&add); > sigaddset(&add, SIGUSR1); > pthread_sigmask(SIG_BLOCK, &add, &add); > pthread_sigmask(SIG_BLOCK, NULL, &old); >=20 > printf("after: "); > for (i=3D0; i<4; i++) > printf(" %08x", old.__bits[i]); > printf("\n"); >=20 > return 0; > } >=20 > The result is, >=20 > correct case: > before: 00000000 00000000 00000000 00000000 > after: 20000000 00000000 00000000 00000000 > incorrect case: > before: 00000000 00000000 00000000 00000000 > after: 00000000 00000000 00000000 00000000 >=20 > difference between func and func2 are >=20 > - pthread_sigmask(SIG_BLOCK, &add, NULL); > + pthread_sigmask(SIG_BLOCK, &add, &add); >=20 > That said, To add oset changed sigprocmask() behavior significantly. Still something is not right :). I copied/pasted the updated func2() from the mail above, and get correct case:=20 before: 00000000 00000000 00000000 00000000 after: 20000000 00000000 00000000 00000000 incorrect case:=20 before: 00000000 00000000 00000000 00000000 after: 20000000 00000000 00000000 00000000 on amd64 machine, while code is compiled for 32 bit. I would say that the output is as expected by me. The old mask is copied out by kernel after new mask is copied in. Below is the exact source of the test I used. Could you, please, confirm that the test is right ? If not, please send me the exact source code that demonstrates your issue. Thanks. #include #include #include void* func(void* arg) { sigset_t old; sigset_t add; int i; sigemptyset(&old); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("before: "); for (i=3D0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); sigemptyset(&add); sigaddset(&add, SIGUSR1); pthread_sigmask(SIG_BLOCK, &add, NULL); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("after: "); for (i=3D0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); return 0; } void* func2(void* arg) { sigset_t old; sigset_t add; int i; sigemptyset(&old); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("before: "); for (i=3D0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); sigemptyset(&add); sigaddset(&add, SIGUSR1); pthread_sigmask(SIG_BLOCK, &add, &add); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("after: "); for (i=3D0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); return 0; } int main(void) { pthread_t thr; void* ret; printf("correct case: \n"); pthread_create(&thr, NULL, func, NULL); pthread_join(thr, &ret); printf("incorrect case: \n"); pthread_create(&thr, NULL, func2, NULL); pthread_join(thr, &ret); return 0; } --fBKP4Km0jCX9yvBB Content-Type: application/pgp-signature Content-Disposition: inline -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (FreeBSD) iEYEARECAAYFAk1gHTIACgkQC3+MBN1Mb4iEbQCg3whUHY7l0Wd98PuzJWT/Ud2H cFYAn1qOqx8XJRwo4cemsYlUGvAhPkxs =F2XK -----END PGP SIGNATURE----- --fBKP4Km0jCX9yvBB-- From owner-freebsd-threads@FreeBSD.ORG Sat Feb 19 19:54:40 2011 Return-Path: Delivered-To: freebsd-threads@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 344AE106564A for ; Sat, 19 Feb 2011 19:54:40 +0000 (UTC) (envelope-from kosaki.motohiro@gmail.com) Received: from mail-wy0-f182.google.com (mail-wy0-f182.google.com [74.125.82.182]) by mx1.freebsd.org (Postfix) with ESMTP id BBEBD8FC1B for ; Sat, 19 Feb 2011 19:54:39 +0000 (UTC) Received: by wyb32 with SMTP id 32so631401wyb.13 for ; Sat, 19 Feb 2011 11:54:38 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=domainkey-signature:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc:content-type:content-transfer-encoding; bh=GeCYMSIxb6raP8ZELfvwATHoBllQm+bKeyXv3XcSL+4=; b=q+vtgHHoRiC8mAIekqfFs1kc2mSZny11d7JVyHB+2GWJ+AdFCrcBsxP99fsUvGeqZ9 I/vYBYuV9SRqREPoDq/UR13m0uQaPJ8vKJfyenUhHF41nW7dQyRhY+7Cd6zSuAShTxr3 wCyFKzEcHWIddXnPz5akLCZRzff12XbHaHNYA= DomainKey-Signature: a=rsa-sha1; c=nofws; d=gmail.com; s=gamma; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; b=nldSVDLRucJupeEVw2rRzRzR7SzEo1uHm0P+MlU4m2aLjzSvyqJHAPOAJGF1VYlQjL t093b3P8KCEMJKcROuV+BJhIeAS2XJ+euLrIYskU1pV9Vrgr3xvxWDhO8RsvlLR3vjsU wiExvO87LiJKblKqYDDf101LcLmxK03L9+7P0= Received: by 10.216.7.8 with SMTP id 8mr740570weo.30.1298143386866; Sat, 19 Feb 2011 11:23:06 -0800 (PST) MIME-Version: 1.0 Received: by 10.216.182.74 with HTTP; Sat, 19 Feb 2011 11:22:46 -0800 (PST) In-Reply-To: <20110219184348.GK78089@deviant.kiev.zoral.com.ua> References: <201102191809.p1JI9rZi063561@red.freebsd.org> <20110219184348.GK78089@deviant.kiev.zoral.com.ua> From: KOSAKI Motohiro Date: Sun, 20 Feb 2011 04:22:46 +0900 Message-ID: To: Kostik Belousov Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable Cc: freebsd-threads@freebsd.org Subject: Re: threads/154893: pthread_sigmask don't work if mask and oldmask are passed the same pointer X-BeenThere: freebsd-threads@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Threading on FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 19 Feb 2011 19:54:40 -0000 Hi > Note that POSIX requires the following prototypes for > the sigprocmask and pthread_sigmask: > > int pthread_sigmask(int how, const sigset_t *restrict set, > =A0 =A0 =A0 sigset_t *restrict oset); > int sigprocmask(int how, const sigset_t *restrict set, > =A0 =A0 =A0sigset_t *restrict oset); Ouch. right you are. > The restrict keyword explicitely disallows the case of set =3D=3D oset, > so I think the behaviour is undefined by POSIX, and our implementation > is correct. I agree. > On the other hand, pthread_sigmask(3) manpage needs update to add > restrict, and include/signal.h also ought to be changed. OK, thanks. >> Then, if set =3D=3D oset, set argument was override before use it at (1)= . >> To introduce temporary variable fix this issue easily. > libc_r is unused. Real implementation is in lib/libthr, that already > has a twist that would not allow the override for case of action !=3D > SIG_UNBLOCK. Moreover, the kernel side of sigprocmask(2) implementation > first copies new set into kernel VA, and only then copies old mask out. Hmhm. > Your example does not supply oset =3D=3D set to the pthread_sigmask, > meantime. I really do not see anything wrong with the output of > the program that supposed to illustrate the issue. Oh, I'm sorry. It's cut-n-paste mistake. I did paste old version unintensionally. void* func2(void* arg) { sigset_t old; sigset_t add; int i; sigemptyset(&old); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("before: "); for (i=3D0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); sigemptyset(&add); sigaddset(&add, SIGUSR1); pthread_sigmask(SIG_BLOCK, &add, &add); pthread_sigmask(SIG_BLOCK, NULL, &old); printf("after: "); for (i=3D0; i<4; i++) printf(" %08x", old.__bits[i]); printf("\n"); return 0; } The result is, correct case: before: 00000000 00000000 00000000 00000000 after: 20000000 00000000 00000000 00000000 incorrect case: before: 00000000 00000000 00000000 00000000 after: 00000000 00000000 00000000 00000000 difference between func and func2 are - pthread_sigmask(SIG_BLOCK, &add, NULL); + pthread_sigmask(SIG_BLOCK, &add, &add); That said, To add oset changed sigprocmask() behavior significantly. > The func() adds SIGUSR1 to the mask with second call to > pthread_sigmask(SIG_BLOCK, &add, NULL);. Then, third call > correctly returns SIGUSR1 in the mask. > > On the other hand, func2() sets SIGUSR1 as blocked and retrieves > the previous mask in single atomic action. Since SIGUSR1 was not > blocked before the call, old sigset correctly indicates it as > "not blocked". (snip) > The only change that I see as needed now is the following cosmetics: > > commit 49287c24fc46f342b46db1fae3fe9982bfbf7ed9 > Author: Konstantin Belousov > Date: =A0 Sat Feb 19 20:41:46 2011 +0200 > > =A0 =A0Add restrict keyword to pthread_sigmask prototype and manpage > > diff --git a/include/signal.h b/include/signal.h > index 4a4cd17..52a611c 100644 > --- a/include/signal.h > +++ b/include/signal.h > @@ -69,7 +69,8 @@ int =A0 raise(int); > =A0#if __POSIX_VISIBLE || __XSI_VISIBLE > =A0int =A0 =A0kill(__pid_t, int); > =A0int =A0 =A0pthread_kill(__pthread_t, int); > -int =A0 =A0pthread_sigmask(int, const __sigset_t *, __sigset_t *); > +int =A0 =A0pthread_sigmask(int, const __sigset_t *__restrict, > + =A0 =A0 =A0 =A0 =A0 __sigset_t * __restrict); > =A0int =A0 =A0sigaction(int, const struct sigaction * __restrict, > =A0 =A0 =A0 =A0 =A0 =A0struct sigaction * __restrict); > =A0int =A0 =A0sigaddset(sigset_t *, int); > diff --git a/share/man/man3/pthread_sigmask.3 b/share/man/man3/pthread_si= gmask.3 > index c412543..013ba7c 100644 > --- a/share/man/man3/pthread_sigmask.3 > +++ b/share/man/man3/pthread_sigmask.3 > @@ -26,7 +26,7 @@ > =A0.\" EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. > =A0.\" > =A0.\" $FreeBSD$ > -.Dd April 27, 2000 > +.Dd February 19, 2011 > =A0.Dt PTHREAD_SIGMASK 3 > =A0.Os > =A0.Sh NAME > @@ -38,7 +38,8 @@ > =A0.In pthread.h > =A0.In signal.h > =A0.Ft int > -.Fn pthread_sigmask "int how" "const sigset_t *set" "sigset_t *oset" > +.Fn pthread_sigmask "int how" "const sigset_t * restrict set" \ > + =A0 =A0"sigset_t * restrict oset" > =A0.Sh DESCRIPTION > =A0The > =A0.Fn pthread_sigmask Looks good.