delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2025/04/10/05:06:19

DMARC-Filter: OpenDMARC Filter v1.4.2 delorie.com 53A96JVu3180803
Authentication-Results: delorie.com; dmarc=pass (p=none dis=none) header.from=cygwin.com
Authentication-Results: delorie.com; spf=pass smtp.mailfrom=cygwin.com
DKIM-Filter: OpenDKIM Filter v2.11.0 delorie.com 53A96JVu3180803
Authentication-Results: delorie.com;
dkim=pass (1024-bit key, unprotected) header.d=cygwin.com header.i=@cygwin.com header.a=rsa-sha256 header.s=default header.b=EjkanyEy
X-Recipient: archive-cygwin AT delorie DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B3A013839821
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cygwin.com;
s=default; t=1744275978;
bh=HRKAAlbzbOnBtEkIV1V66mfyNayFMlCAGwNwjQ6OcjU=;
h=Date:To:Subject:References:In-Reply-To:List-Id:List-Unsubscribe:
List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc:
From;
b=EjkanyEygvSp54lXCuoFwNNeGpSyeXr30UUlsagOcKVeeezu18uqRhkshPJCyr1ER
JxOY0yw/Zj4K+UFx+sUQxq1Px+8MNJb94UQ9h+kS/mZPTwG/uYkTRvpRPscGpRBZYs
u0xbXFWVhCKNSy0PJZEb0CTPJRAd0/5FQoj2/8fM=
X-Original-To: cygwin AT cygwin DOT com
Delivered-To: cygwin AT cygwin DOT com
DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org D4B2C3839C55
Date: Thu, 10 Apr 2025 11:04:40 +0200
To: cygwin AT cygwin DOT com
Subject: Re: pthread_atfork vs dlopen/dlclose
Message-ID: <Z_eJqDJw-xbhktwC@calimero.vinschen.de>
Mail-Followup-To: cygwin AT cygwin DOT com
References: <07665688-8199-2e80-cdfe-abeaa6f56ba7 AT jdrake DOT com>
<2021152719 DOT 99592 DOT 1744265074916 AT mail DOT yahoo DOT com>
<b150c1e4-b3cd-4f90-8548-0c5f287948d4 AT jdrake DOT com>
<94af5480-167a-fcc6-5f4c-89afa5ce8637 AT jdrake DOT com>
MIME-Version: 1.0
In-Reply-To: <94af5480-167a-fcc6-5f4c-89afa5ce8637@jdrake.com>
X-BeenThere: cygwin AT cygwin DOT com
X-Mailman-Version: 2.1.30
List-Id: General Cygwin discussions and problem reports <cygwin.cygwin.com>
List-Unsubscribe: <https://cygwin.com/mailman/options/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=unsubscribe>
List-Archive: <https://cygwin.com/pipermail/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-request AT cygwin DOT com?subject=help>
List-Subscribe: <https://cygwin.com/mailman/listinfo/cygwin>,
<mailto:cygwin-request AT cygwin DOT com?subject=subscribe>
From: Corinna Vinschen via Cygwin <cygwin AT cygwin DOT com>
Reply-To: cygwin AT cygwin DOT com
Cc: Corinna Vinschen <corinna-cygwin AT cygwin DOT com>
Errors-To: cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com
Sender: "Cygwin" <cygwin-bounces~archive-cygwin=delorie DOT com AT cygwin DOT com>
X-MIME-Autoconverted: from base64 to 8bit by delorie.com id 53A96JVu3180803

On Apr  9 23:32, Jeremy Drake via Cygwin wrote:
> On Wed, 9 Apr 2025, Jeremy Drake via Cygwin wrote:
> 
> > On Thu, 10 Apr 2025, Kevin Schnitzius via Cygwin wrote:
> >
> > > On Wednesday, April 9, 2025 at 06:54:34 PM EDT, Jeremy Drake via Cygwin <cygwin AT cygwin DOT com> wrote:
> > >
> > > > The recent issue with pthread_atfork handlers reminded me of a scenario
> > > > that I know glibc handles, but it seems that Cygwin does not.  Test case:
> > >
> > > <... code that loads a shared lib, registers some functions in shared lib with pthread_atfork(), unloads the shared lib, and crashes on fork...>
> > >
> > > Calling functions in an unloaded library should result in undefined behavior.
> > >
> > > However, further investigation reveals that the Linux pthread_atfork() registered functions are not being called and POSIX does not proved a mechanism for un-registering these functions.   Note: pthread_atfork() is not bumping the ref count on the shared lib--those functions are definitely unavailable after the dlclose()
> > >
> > > In the Cygwin version, calling the functions in the unloaded library when the fork happens causes the crash.
> > >
> > > This seems to be a bug with fork(), if it is a bug at all.
> >
> > I did a quick search, and found a write-up of *my* bug report :D
> >
> > https://developers.redhat.com/articles/2022/12/14/how-we-addressed-unforeseen-use-case-pthreadatfork
> >
> > "Now, dlclose()'ing a module means that any fork handlers registered by it
> > should not be executed after the dlclose and should therefore implicitly
> > be deregistered."
> 
> It seems glibc takes care of this implicit deregistration in
> __cxa_finalize, after calling __cxa_atexit functions, it unregisters any
> at_quick_exit or pthread_atfork callbacks from the DSO being unloaded.
> 
> https://sourceware.org/git/?p=glibc.git;a=blob;f=stdlib/cxa_finalize.c;h=2bb35602edc6bf842e5d2c93ad03454d7b57ee65;hb=HEAD
> 
> It doesn't look like newlib deals with either at_quick_exit or
> pthread_atfork handlers in its __cxa_finalize implementation.

Cygwin is doing this stuff mostly in its own code, see thread.cc.
It keeps lists of the callbacks in a global structure which is
called MT_INTERFACE throughout thread.cc.

The functions pthread::atforkprepare(), pthread::atforkparent() and
pthread::atforkchild () are called from different spots during fork().

Here's what we're missing:

- Either keep track of the DLL a callback function is coming from by
  calling dlls.find (handle, true) and store the struct dll pointer.
  In dlclose(), if the DLL is of type DLL_LOAD or DLL_NATIVE, and
  the refcounter indicates that this is the last FreeLibrary, check the
  three callback lists in MT_INTERFACE and remove all functions
  with the same struct dll pointer.

- Or, instead of keeping track, tweak the aformentioned three functions
  to call GetModuleHandleEx() just as dladdr() does, and if it returns
  NULL, remove the callback from the list on the fly.


Corinna

-- 
Problem reports:      https://cygwin.com/problems.html
FAQ:                  https://cygwin.com/faq/
Documentation:        https://cygwin.com/docs.html
Unsubscribe info:     https://cygwin.com/ml/#unsubscribe-simple

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019