Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: "dead lock detected" in Firefox



On Sun, Mar 27, 2011 at 05:15:45AM -0400, Gary Duzan wrote:
>    With current/amd64 I get the message "dead lock detected" when
> trying to start Firefox. It looks like I'm hitting problems with
> the locking added in rtld.c 1.141 (I have 1.142). I have made the
> LD_DEBUG output available at:
> 
>       http://www.duzan.org/gary/ffdl.log

Can you try with the attached patch please?

Joerg
Index: rtld.c
===================================================================
RCS file: /home/joerg/repo/netbsd/src/libexec/ld.elf_so/rtld.c,v
retrieving revision 1.142
diff -u -p -r1.142 rtld.c
--- rtld.c      26 Mar 2011 21:40:37 -0000      1.142
+++ rtld.c      27 Mar 2011 21:46:12 -0000
@@ -89,6 +89,7 @@ Obj_Entry      *_rtld_objmain;        /* The ma
 Obj_Entry       _rtld_objself; /* The dynamic linker shared object */
 u_int          _rtld_objcount; /* Number of objects in _rtld_objlist */
 u_int          _rtld_objloads; /* Number of objects loaded in _rtld_objlist */
+u_int          _rtld_objgen;   /* Generation count for _rtld_objlist */
 const char     _rtld_path[] = _PATH_RTLD;
 
 /* Initialize a fake symbol for resolving undefined weak references. */
@@ -139,9 +140,13 @@ _rtld_call_fini_functions(int force)
        Objlist_Entry *elm;
        Objlist finilist;
        Obj_Entry *obj;
+       void (*fini)(void);
+       u_int cur_objgen;
 
        dbg(("_rtld_call_fini_functions(%d)", force));
 
+restart:
+       cur_objgen = ++_rtld_objgen;
        SIMPLEQ_INIT(&finilist);
        _rtld_initlist_tsort(&finilist, 1);
 
@@ -157,10 +162,15 @@ _rtld_call_fini_functions(int force)
                dbg (("calling fini function %s at %p",  obj->path,
                    (void *)obj->fini));
                obj->fini_called = 1;
-               /* XXXlocking: exit point */
-               _rtld_mutex_may_recurse = true;
-               (*obj->fini)();
-               _rtld_mutex_may_recurse = false;
+               fini = obj->fini;
+               _rtld_exclusive_exit();
+               (*fini)();
+               _rtld_exclusive_enter();
+               if (_rtld_objgen != cur_objgen) {
+                       dbg(("restarting fini iteration"));
+                       _rtld_objlist_clear(&finilist);
+                       goto restart;
+               }
        }
 
        /* Second pass: objects marked with DF_1_INITFIRST. */
@@ -175,10 +185,15 @@ _rtld_call_fini_functions(int force)
                dbg (("calling fini function %s at %p (DF_1_INITFIRST)",
                    obj->path, (void *)obj->fini));
                obj->fini_called = 1;
-               /* XXXlocking: exit point */
-               _rtld_mutex_may_recurse = true;
-               (*obj->fini)();
-               _rtld_mutex_may_recurse = false;
+               fini = obj->fini;
+               _rtld_exclusive_exit();
+               (*fini)();
+               _rtld_exclusive_enter();
+               if (_rtld_objgen != cur_objgen) {
+                       dbg(("restarting fini iteration"));
+                       _rtld_objlist_clear(&finilist);
+                       goto restart;
+               }
        }
 
         _rtld_objlist_clear(&finilist);
@@ -190,8 +205,13 @@ _rtld_call_init_functions()
        Objlist_Entry *elm;
        Objlist initlist;
        Obj_Entry *obj;
+       void (*init)(void);
+       u_int cur_objgen;
 
        dbg(("_rtld_call_init_functions()"));
+
+restart:
+       cur_objgen = ++_rtld_objgen;
        SIMPLEQ_INIT(&initlist);
        _rtld_initlist_tsort(&initlist, 0);
 
@@ -204,10 +224,15 @@ _rtld_call_init_functions()
                dbg (("calling init function %s at %p (DF_1_INITFIRST)",
                    obj->path, (void *)obj->init));
                obj->init_called = 1;
-               /* XXXlocking: exit point */
-               _rtld_mutex_may_recurse = true;
-               (*obj->init)();
-               _rtld_mutex_may_recurse = false;
+               init = obj->init;
+               _rtld_exclusive_exit();
+               (*init)();
+               _rtld_exclusive_enter();
+               if (_rtld_objgen != cur_objgen) {
+                       dbg(("restarting init iteration"));
+                       _rtld_objlist_clear(&initlist);
+                       goto restart;
+               }
        }
 
        /* Second pass: all other objects. */
@@ -219,10 +244,15 @@ _rtld_call_init_functions()
                dbg (("calling init function %s at %p",  obj->path,
                    (void *)obj->init));
                obj->init_called = 1;
-               /* XXXlocking: exit point */
-               _rtld_mutex_may_recurse = true;
-               (*obj->init)();
-               _rtld_mutex_may_recurse = false;
+               init = obj->init;
+               _rtld_exclusive_exit();
+               (*init)();
+               _rtld_exclusive_enter();
+               if (_rtld_objgen != cur_objgen) {
+                       dbg(("restarting init iteration"));
+                       _rtld_objlist_clear(&initlist);
+                       goto restart;
+               }
        }
 
         _rtld_objlist_clear(&initlist);


Home | Main Index | Thread Index | Old Index