|
Message-ID: <20160115045952.GE238@brightrain.aerifal.cx> Date: Thu, 14 Jan 2016 23:59:52 -0500 From: Rich Felker <dalias@...c.org> To: musl@...ts.openwall.com Subject: Re: dlopen deadlock On Thu, Jan 14, 2016 at 09:47:59PM -0500, Rich Felker wrote: > > > > one solution i can think of is to have an init_fini_lock > > > > for each dso, then the deadlock only happens if a ctor > > > > tries to dlopen its own lib (directly or indirectly) > > > > which is nonsense (the library depends on itself being > > > > loaded) > > > > > > The lock has to protect the fini chain linked list (used to control > > > order of dtors) so I don't think having it be per-dso is a > > > possibility. > > > > > > > i guess using lockfree atomics could solve the deadlock then > > I don't think atomics help. We could achieve the same thing as atomics > by just taking and releasing the lock on each iteration when modifying > the lock-protected state, but not holding the lock while calling the > actual ctors. > > >From what I can see/remember, the reason I didn't write the code that > way is that we don't want dlopen to return before all ctors have run > -- or at least started running, in the case of a recursive call to > dlopen. If the lock were taken/released on each iteration, two threads > simultaneously calling dlopen on the same library libA that depends on > libB could each run A's ctors and B's ctors and either of them could > return from dlopen before the other finished, resulting in library > code running without its ctors having finished. > > The problem is that excluding multiple threads from running > possibly-unrelated ctors simultaneously is wrong, and marking a > library constructed as soon as its ctors start is also wrong (at least > once this big-hammer lock is fixed). Instead we should be doing some > sort of proper dependency-graph tracking and ensuring that a dlopen > cannot return until all dependencies have completed their ctors, > except in the special case of recursion, in which case it's acceptable > for libX's ctors to load a libY that depends on libX, where libX > should be treated as "already constructed" (it's a bug in libX if it > has not already completed any initialization that libY might depend > on). However I don't see any reasonable way to track this kind of > relationship when it happens 'indirectly-recursively' via a new > thread. It may just be that such a case should deadlock. However, > dlopen of separate libs which are unrelated in any dependency sense to > the caller should _not_ deadlock just because it happens from a thread > created by a ctor... Some relevant history: commit f4f77c068f1058d202a976678fce2617d59c0ff6 fix/improve shared library ctor/dtor handling, allow recursive dlopen commit 509b50eda8ea7d4a28f738e4cf8ea98d25959f00 fix missing synchronization in calls from dynamic linker to global ctors Rich
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.