Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250528190704.GT1827@brightrain.aerifal.cx>
Date: Wed, 28 May 2025 15:07:04 -0400
From: Rich Felker <dalias@...c.org>
To: Markus Wichmann <nullplan@....net>
Cc: musl@...ts.openwall.com
Subject: Re: Deadlock in dynamic linker?

On Wed, May 28, 2025 at 04:50:44PM +0200, Markus Wichmann wrote:
> Am Tue, May 27, 2025 at 02:26:15PM -0400 schrieb Rich Felker:
> > However I'm beginning to doubt this solution really works. The problem
> > is that, if A depends on B, A's ctor can be waiting to run pending B's
> > ctor finishing. But if a concurrent exit calls B's dtor, then A's ctor
> > is no longer free to run, because it depends on B being constructed.
> > We really do need to block execution of any ctor whose deps may
> > already have been destructed.
> 
> I am wondering if we are approaching this from the wrong end: Is it
> possible to make __libc_exit_fini() wait to call *any* destructors
> until all other threads have stopped calling initializers? That way, the
> other constructors can continue to run until they reach some valid
> state, rather than this in-betweeny one.

That sounds reasonable but I don't think it solves your problem. If
exit has been called from a ctor in thread A, it's possible that
thread B is in the middle of running ctors and can never make forward
progress, because it's waiting for the ctor thread A is running to
finish in order to honor the dependency order. This seems equivalent
to the deadlock you have now.

Aside from that, it seems like you could have __libc_exit_fini() wait
on a condvar for outstanding dlopens to finish (after already having
blocked new ones) before running any dtors.

> I don't really see a nice way to do that, that also allows detecting
> multi-threaded fork() and exit() out of a constructor.

I haven't thought this through, but as a related note: the dynamic
linker will already lock out certain behaviors after multithreaded
fork. See the error call in queue_ctors for MT-fork-inconsistent case.

Anyway, I'm strongly suspecting the original problem just has no
solution, and that the answer is just "don't do that".

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.