On Wed, 11 Apr 2012 15:53:38 +0300
Konstantin Belousov <kostik...@gmail.com> wrote:

> On Wed, Apr 11, 2012 at 01:34:01PM +0200, Stefan Farfeleder wrote:
> > On Tue, Apr 10, 2012 at 08:31:53AM +0200, Stefan Farfeleder wrote:
> > > On Tue, Apr 10, 2012 at 01:44:02AM -0400, AN wrote:
> > > > FreeBSD FBSD10 10.0-CURRENT FreeBSD 10.0-CURRENT #7 r234042: Sun Apr  8 
> > > > 17:36:38 EDT 2012     root@FBSD10:/usr/obj/usr/src/sys/MYKERNEL  amd64
> > > > 
> > > > After a recent update on Sunday to r234042 I am having a problem with 2 
> > > > ports:
> > > > 
> > > > gedit
> > > > evince
> > > > (using Gnome2 - ports tree up to date)
> > > > 
> > > > My last update (before this past Sun build/install world) was 2 weeks 
> > > > ago, 
> > > > so it was definitely a change made in the last 2 weeks.
> > > > 
> > > > Gedit will not start from the command line, or the applications menu. 
> > > > There is no error message on the command line.  Evince will start, 
> > > > however 
> > > > when you try to open a document the program freezes.
> > > > 
> > > > I have tried to:
> > > > make deinstall
> > > > make clean
> > > > make install clean
> > > > 
> > > > for both ports but they are still broken.  I would appreciate any help.
> > > 
> > > I'm experiencing that too (r234038), xine also no longer starts (hangs
> > > at splash screen).
> > 
> > FWIW backing out r233749 fixes evince and xine for me.
> Please recompile at least rtld/libc/libthr with debugging symbols and get
> a backtrace from the hung process.

My wild guess tells me that the rtld_bind_lock gets held recursively
when resolving filtered symbol.
The attached band-aid patch supports the guess.

I have the world/kernel as of r234038 and have difficulty to launch XFce's
xfdesktop-settings (w/ im-scim.so which loads libstdc++), where every threads
of xfdesktop-settings stuck into either "urdlck" or "uwrlck" states.

I have to admit that the attached patch is something like 3-minute-hacking
quality, but it at least avoids the stall.


-- 
-|-__   YAMAMOTO, Taku
 | __ <     <t...@tackymt.homeip.net>

      - A chicken is an egg's way of producing more eggs. -
--- lib/libthr/thread/thr_rtld.c.orig   2011-01-23 09:17:50.657791000 +0900
+++ lib/libthr/thread/thr_rtld.c        2012-04-12 02:48:05.091322596 +0900
@@ -52,6 +52,10 @@ static void  _thr_rtld_wlock_acquire(void
 
 struct rtld_lock {
        struct  urwlock lock;
+       struct  pthread * volatile owner;
+       int     nested;
+       int     count_rw; /* total rlock-within-wlock incidents */
+       int     count_ww; /* total wlock-within-wlock incidents */
        char            _pad[CACHE_LINE_SIZE - sizeof(struct urwlock)];
 };
 
@@ -106,6 +110,15 @@ _thr_rtld_lock_destroy(void *lock)
                errno = errsave;                \
 }
 
+#define HANDLE_NESTED_ACQ(statfield) {                                 \
+               if ((l->lock.rw_state & URWLOCK_WRITE_OWNER) != 0 &&    \
+                   l->owner == curthread) {                            \
+                       l->nested++;                                    \
+                       l->statfield++;                                 \
+                       return;                                         \
+               }                                                       \
+       }
+
 static void
 _thr_rtld_rlock_acquire(void *lock)
 {
@@ -117,6 +130,7 @@ _thr_rtld_rlock_acquire(void *lock)
        SAVE_ERRNO();
        l = (struct rtld_lock *)lock;
 
+       HANDLE_NESTED_ACQ(count_rw);
        THR_CRITICAL_ENTER(curthread);
        while (_thr_rwlock_rdlock(&l->lock, 0, NULL) != 0)
                ;
@@ -135,9 +149,11 @@ _thr_rtld_wlock_acquire(void *lock)
        SAVE_ERRNO();
        l = (struct rtld_lock *)lock;
 
+       HANDLE_NESTED_ACQ(count_ww);
        THR_CRITICAL_ENTER(curthread);
        while (_thr_rwlock_wrlock(&l->lock, NULL) != 0)
                ;
+       l->owner = curthread;
        RESTORE_ERRNO();
 }
 
@@ -154,6 +170,14 @@ _thr_rtld_lock_release(void *lock)
        l = (struct rtld_lock *)lock;
        
        state = l->lock.rw_state;
+       if ((state & URWLOCK_WRITE_OWNER) != 0) {
+               if (l->nested == 0)
+                       l->owner = NULL;
+               else {
+                       l->nested--;
+                       return;
+               }
+       }
        if (_thr_rwlock_unlock(&l->lock) == 0) {
                if ((state & URWLOCK_WRITE_OWNER) == 0)
                        curthread->rdlock_count--;
_______________________________________________
freebsd-current@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-current
To unsubscribe, send any mail to "freebsd-current-unsubscr...@freebsd.org"

Reply via email to