[newlib-cygwin] Cygwin: dll_init: Always call __cxa_finalize() for DLL_LOAD

Takashi Yano tyan0@sourceware.org
Wed Nov 19 11:26:59 GMT 2025


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=0d2f981940a496a41b0b650a4ba286d9137302f7

commit 0d2f981940a496a41b0b650a4ba286d9137302f7
Author: Takashi Yano <takashi.yano@nifty.ne.jp>
Date:   Tue Oct 28 09:30:41 2025 +0900

    Cygwin: dll_init: Always call __cxa_finalize() for DLL_LOAD
    
    For dlopen()'ed DLL, __cxa_finalize() should always be called at dll
    detach time. The reason is as follows. In the case that dlopen()'ed
    DLL A is dlclose()'ed in the destructor of DLL B, and the destructor
    of DLL B is called in exit_state, DLL A will be unloaded by dlclose().
    If __cxa_finalize() for DLL A is not called here, the destructor of
    DLL A will be called in exit() even though DLL A is already unloaded.
    This causes crash at exit(). In this case, __cxa_finalize() should be
    called before unloading DLL A even in exit_state.
    
    Addresses: https://cygwin.com/pipermail/cygwin/2025-October/258877.html
    Fixes: c019a66c32f8 ("* dll_init.cc (dll_list::detach) ... Don't call __cxa_finalize in exiting case.")
    Reported-by: Thomas Huth <th.huth@posteo.eu>
    Reviewed-by: Mark Geisert <mark@maxrnd.com>, Jon Turney <jon.turney@dronecode.org.uk>, Corinna Vinschen <corinna-cygwin@cygwin.com>
    Signed-off-by: Takashi Yano <takashi.yano@nifty.ne.jp>

Diff:
---
 winsup/cygwin/dll_init.cc | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc
index 1369165c9..d2ed74bed 100644
--- a/winsup/cygwin/dll_init.cc
+++ b/winsup/cygwin/dll_init.cc
@@ -584,7 +584,16 @@ dll_list::detach (void *retaddr)
 	  /* Ensure our exception handler is enabled for destructors */
 	  exception protect;
 	  /* Call finalize function if we are not already exiting */
-	  if (!exit_state)
+	  /* For dlopen()'ed DLL, __cxa_finalize() should always be called
+	     at dll detach time. The reason is as follows. In the case that
+	     dlopen()'ed DLL A is dlclose()'ed in the destructor of DLL B,
+	     and the destructor of DLL B is called in exit_state, DLL A will
+	     be unloaded by dlclose(). If __cxa_finalize() for DLL A is not
+	     called here, the destructor of DLL A will be called in exit()
+	     even though DLL A is already unloaded. This causes crash at
+	     exit(). In this case, __cxa_finalize() should be called before
+	     unloading DLL A even in exit_state. */
+	  if (!exit_state || d->type == DLL_LOAD)
 	    __cxa_finalize (d->handle);
 	  d->run_dtors ();
 	}


More information about the Cygwin-cvs mailing list