If dlclose() for the first DLL is called in the destructor of another linked DLL, __cxa_finalize() should be called even in exit_state. This is because if the second destructor is called in exit_state, the first DLL will be unloaded by dlclose(). Therefore, if __cxa_finalize() is not called here, the destructor of the first DLL will be called in exit() even though the first DLL is already unloaded. This causes crash at exit(). In the case above, __cxa_finalize() should be called before unloading the first DLL 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 <[email protected]> Reviewed-by: Signed-off-by: Takashi Yano <[email protected]> --- winsup/cygwin/dll_init.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 1369165c9..b6ab4ed11 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -584,7 +584,8 @@ 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) + /* Loaded DLLs need finalize function even in the exiting state */ + if (!exit_state || d->type == DLL_LOAD) __cxa_finalize (d->handle); d->run_dtors (); } -- 2.51.0
