misc/150959: Stub pthread_once in libc should call _libc_once

Kenton Varda temporal at gmail.com
Sun Sep 26 07:10:06 UTC 2010


>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 at 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:


More information about the freebsd-bugs mailing list