From owner-freebsd-bugs@FreeBSD.ORG Sun Sep 26 07:10:06 2010 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 5EA131065672 for ; Sun, 26 Sep 2010 07:10:06 +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 1CF558FC17 for ; Sun, 26 Sep 2010 07:10:06 +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 o8Q7A50k053306 for ; Sun, 26 Sep 2010 07:10:05 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.4/8.14.4/Submit) id o8Q7A5nC053305; Sun, 26 Sep 2010 07:10:05 GMT (envelope-from gnats) Resent-Date: Sun, 26 Sep 2010 07:10:05 GMT Resent-Message-Id: <201009260710.o8Q7A5nC053305@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Kenton Varda Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id D31E61065670 for ; Sun, 26 Sep 2010 07:05:08 +0000 (UTC) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21]) by mx1.freebsd.org (Postfix) with ESMTP id A77488FC16 for ; Sun, 26 Sep 2010 07:05:08 +0000 (UTC) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o8Q758xU039579 for ; Sun, 26 Sep 2010 07:05:08 GMT (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.14.3/8.14.3/Submit) id o8Q7586g039578; Sun, 26 Sep 2010 07:05:08 GMT (envelope-from nobody) Message-Id: <201009260705.o8Q7586g039578@www.freebsd.org> Date: Sun, 26 Sep 2010 07:05:08 GMT From: Kenton Varda To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-3.1 Cc: Subject: misc/150959: Stub pthread_once in libc should call _libc_once X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 26 Sep 2010 07:10:06 -0000 >Number: 150959 >Category: misc >Synopsis: Stub pthread_once in libc should call _libc_once >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Sep 26 07:10:05 UTC 2010 >Closed-Date: >Last-Modified: >Originator: Kenton Varda >Release: 8-STABLE >Organization: >Environment: FreeBSD umaro.evlan.org 8.1-STABLE FreeBSD 8.1-STABLE #0: Thu Aug 5 03:29:49 PDT 2010 kenton@umaro.evlan.org:/usr/obj/usr/src/sys/GENERIC amd64 >Description: libc.so defines a "stub" version of pthread_once(). Unfortunately, the stub version simply returns zero (success) without ever calling the init function, which does not satisfy the contract of pthread_once. The effect of this is that if code which uses pthread_once is accidentally linked without libpthread, the code's attempts to initialize data structures using pthread_once will silently fail, probably leading to unexpected and hard-to-debug crashes or other problems. When debugging this code, the developer may figure out easily enough that pthread_once() is not functioning, but is unlikely to realize that this is because he has not linked against libpthread -- most developers would expect to have seen a linker error if this were the problem. This also makes it difficult for developers to write libraries which are thread-safe without requiring a threading implementation. Many libraries have no need to spawn threads of their own, but do need to be safe to use in a multi-threaded program. These libraries may thus need to use pthread_once to initialize internal data structures. Unfortunately, this currently means that any program using such a library must link against libpthread whether or not the program actually uses threads. It would be convenient if such code could simply rely on the libc pthread stubs instead. >How-To-Repeat: 1. Write a small program that uses pthread_once(). 2. Compile and link without libpthread. 3. Observe that linking succeeds, but at runtime the init function is never called. >Fix: The basic fix is trivial: Have the pthread_once stub (defined in lib/libc/gen/_pthread_stubs.c) call _libc_once (defined in lib/libc/gen/_once_stub.c) instead of just returning zero. It appears that this was tried before, but reverted: http://svn.freebsd.org/viewvc/base?view=revision&revision=199614 >From the revision description, it seems that libstdc++ has unfortunately decided to rely on the pthread_once stub's incorrect behavior as a way to detect whether libpthread has been linked. This seems like a very poor choice on libstdc++'s part; it should be fixed to avoid depending on this behavior. Another possibility would be to return a non-zero error code. This would at least let the caller know that pthread_once() did not correctly perform its documented behavior. >Release-Note: >Audit-Trail: >Unformatted: