Skip to content

Commit 1b1f0d8

Browse files
committed
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: c019a66 ("* 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> (cherry picked from commit 0d2f981)
1 parent eae30ac commit 1b1f0d8

1 file changed

Lines changed: 10 additions & 1 deletion

File tree

winsup/cygwin/dll_init.cc

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -584,7 +584,16 @@ dll_list::detach (void *retaddr)
584584
/* Ensure our exception handler is enabled for destructors */
585585
exception protect;
586586
/* Call finalize function if we are not already exiting */
587-
if (!exit_state)
587+
/* For dlopen()'ed DLL, __cxa_finalize() should always be called
588+
at dll detach time. The reason is as follows. In the case that
589+
dlopen()'ed DLL A is dlclose()'ed in the destructor of DLL B,
590+
and the destructor of DLL B is called in exit_state, DLL A will
591+
be unloaded by dlclose(). If __cxa_finalize() for DLL A is not
592+
called here, the destructor of DLL A will be called in exit()
593+
even though DLL A is already unloaded. This causes crash at
594+
exit(). In this case, __cxa_finalize() should be called before
595+
unloading DLL A even in exit_state. */
596+
if (!exit_state || d->type == DLL_LOAD)
588597
__cxa_finalize (d->handle);
589598
d->run_dtors ();
590599
}

0 commit comments

Comments
 (0)