Date: Mon, 01 Sep 2008 16:10:17 +0800 From: David Xu <davidxu@freebsd.org> To: Kostik Belousov <kostikbel@gmail.com> Cc: Daniel Eischen <deischen@freebsd.org>, Andriy Gapon <avg@icyb.net.ua>, freebsd-threads@freebsd.org Subject: Re: mysterious hang in pthread_create Message-ID: <48BBA369.9010108@freebsd.org> In-Reply-To: <20080830184512.GH2038@deviant.kiev.zoral.com.ua> References: <48B7101E.7060203@icyb.net.ua> <48B71BA6.5040504@icyb.net.ua> <20080829141043.GX2038@deviant.kiev.zoral.com.ua> <48B8052A.6070908@icyb.net.ua> <20080829143645.GY2038@deviant.kiev.zoral.com.ua> <Pine.GSO.4.64.0808291223240.5086@sea.ntplx.net> <20080829190506.GA2038@deviant.kiev.zoral.com.ua> <Pine.GSO.4.64.0808301128410.9898@sea.ntplx.net> <20080830155622.GF2038@deviant.kiev.zoral.com.ua> <Pine.GSO.4.64.0808301200460.9898@sea.ntplx.net> <20080830184512.GH2038@deviant.kiev.zoral.com.ua>
next in thread | previous in thread | raw e-mail | index | archive | help
Kostik Belousov wrote: > Ok, let me to tell the whole story. I am sure that in fact you know > it better then me. > > Assuming libthr is the only threading library, there are two locking > implementations for the rtld: 'default' and the one supplied by libthr. > On the first call to pthread_create(), libthr calls _rtld_thread_init() > to substitute the default by the implementation from libthr. > > In fact, default implementation is broken from my point of view. For > instance, thread_flag update is not atomic. Moreover, it does not > correctly handles sequential acquision of several locks, due > to thread_flag. > > The dl_iterate_phdr() function, called by gcc exception handling support > code, does exactly this. It acquires rtld_phdr_lock, then rtld_bind_lock. > [I shall admit it does this after my change]. In particular, this would > leave the bit for the bind lock set in the thread_flag. > > Andriy' example throw the exception and calls dl_iterate_phdr() before > first thread is created. On thread creation, _rtld_thread_init() is > called, that tries to move the locks according to thread_flag. This is > the cause for the reported wlock acquisition. > > I do not want to change anything in the default rtld locking. It is > disfunctional from the time libc_r is gone, and I think it would be > better to make it nop. My change makes the image that is linked with > libthr, to consistently use libthr locks. The ancient bug is in rtld, rlock_acquire() and wlock_acquire() test thread_flag as a boolean value, because pt_iterate_phdr() tries to lock two locks at same time, this test will always fail once it acquired first lock. The following silly patch fixes the problem Andriy encountered: Index: rtld_lock.c =================================================================== --- rtld_lock.c (版本 182594) +++ rtld_lock.c (工作副本) @@ -184,7 +184,7 @@ int rlock_acquire(rtld_lock_t lock) { - if (thread_mask_set(lock->mask)) { + if (thread_mask_set(lock->mask) & lock->mask) { dbg("rlock_acquire: recursed"); return (0); } @@ -195,7 +195,7 @@ int wlock_acquire(rtld_lock_t lock) { - if (thread_mask_set(lock->mask)) { + if (thread_mask_set(lock->mask) & lock->mask) { dbg("wlock_acquire: recursed"); return (0); } Regards, David Xu
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?48BBA369.9010108>