Cygwin: dll_init: Always call __cxa_finalize() for DLL_LOAD
authorTakashi Yano <takashi.yano@nifty.ne.jp>
Tue, 28 Oct 2025 00:30:41 +0000 (09:30 +0900)
committerTakashi Yano <takashi.yano@nifty.ne.jp>
Wed, 19 Nov 2025 11:23:01 +0000 (20:23 +0900)
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>
winsup/cygwin/dll_init.cc

index 1369165c9f8aee7e29830c941f53ccb65eaad0fd..d2ed74bed883281a90c3e75f8c6f40ec733570a0 100644 (file)
@@ -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 ();
        }
This page took 0.06968 seconds and 5 git commands to generate.