Bug 13344

Summary: Marking all functions which don't have callbacks with the leaf attribute breaks pthread applications.
Product: glibc Reporter: Octoploid <cryptooctoploid>
Component: nptlAssignee: Ulrich Drepper <drepper.fsp>
Status: RESOLVED FIXED    
Severity: normal CC: hubicka, jakub, jim
Priority: P2 Flags: fweimer: security-
Version: 2.14   
Target Milestone: ---   
Host: Target:
Build: Last reconfirmed:

Description Octoploid 2011-10-25 18:19:51 UTC
Commit aa78043a4aafe5 marks all functions, which don't have callbacks, with
the leaf attribute. This may break pthreaded apps (for example "git grep"),
because pthread_mutex_{lock,unlock,trylock,timedlock} and  pthread_cond_{wait,timedwait} , etc. are also marked and therefore gcc
happily optimizes them. 

See: https://bugzilla.redhat.com/show_bug.cgi?id=747377
or: http://thread.gmane.org/gmane.comp.version-control.git/184184

There are two possibilties to solve this issue; either don't mark the pthread
related functions in glibc or teach gcc to unmark those functions.
Comment 1 Jakub Jelinek 2011-10-25 20:38:30 UTC
I think the leaf attribute in gcc is currently primarily used by ipa-reference
to find out what variables are supposed not to be read resp. written during the call to that function (with leaf attribute all static vars in the current translation unit are in that set if the leaf function is defined in some other compilation unit) and for checking whether labels can be reached by non-local goto.  While the synchronization primitives don't call any callbacks, from this POV it is undesirable to treat them that way, they need to be considered as full barriers.  I think the GCC documentation of leaf attribute should be improved and the pthread.h/sem.h functions that are supposed to work as memory synchronization points should use __THROWNL or similar macro which would be the old __THROW, without leaf attribute in it.
Comment 2 Jakub Jelinek 2011-10-25 20:51:21 UTC
There are other functions that shouldn't be marked leaf BTW, although they are __THROW - e.g. sprintf/snprintf/vsprintf/vsnprintf and their checking equivalents - it is possible to register a printf hook and the hook certainly can be defined in the current function.  And the wide counterparts too.  I'd say sscanf/vsscanf should be treated similarly just in case there will be scanf hooks implemented in the future.
Comment 3 jim@meyering.net 2011-10-26 06:55:18 UTC
at least per POSIX,
http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_11, here's the full list:

The following functions synchronize memory with respect to other threads:

    fork
    pthread_barrier_wait
    pthread_cond_broadcast
    pthread_cond_signal
    pthread_cond_timedwait
    pthread_cond_wait
    pthread_create
    pthread_join
    pthread_mutex_lock
    pthread_mutex_timedlock
    pthread_mutex_trylock
    pthread_mutex_unlock
    pthread_spin_lock
    pthread_spin_trylock
    pthread_spin_unlock
    pthread_rwlock_rdlock
    pthread_rwlock_timedrdlock
    pthread_rwlock_timedwrlock
    pthread_rwlock_tryrdlock
    pthread_rwlock_trywrlock
    pthread_rwlock_unlock
    pthread_rwlock_wrlock
    sem_post
    sem_timedwait
    sem_trywait
    sem_wait
    semctl
    semop
    wait
    waitpid
Comment 4 Octoploid 2011-10-27 16:40:32 UTC
Fixed. Thanks.