https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=70026ace15f0ad65f9fe7af01285c921c5f3e91f
commit 70026ace15f0ad65f9fe7af01285c921c5f3e91f Author: Corinna Vinschen <cori...@vinschen.de> AuthorDate: Sun Mar 30 20:09:02 2025 +0200 Commit: Corinna Vinschen <cori...@vinschen.de> CommitDate: Sun Mar 30 20:57:00 2025 +0200 Cygwin: dlfcn: avoid ENOENT on dlcose after dlopen(cygwin1.dll) When dlopen'ing the Cygwin DLL, refcounting the number of dlopen calls fails because dll_list::find returns NULL if the address resolves to the Cygwin DLL. Fix this by adding a bool parameter to dll_list::find which allows find to return the dll entry for the Cygwin DLL for the sake of dlopen/dlclose/fork. Fixes: 33297d810d90 ("Cygwin: dlfcn: Fix reference counting") Signed-off-by: Corinna Vinschen <cori...@vinschen.de> (cherry picked from commit 82b31085f6ad23c3aaf5a928bd56fe06cbe63df5) Diff: --- winsup/cygwin/dlfcn.cc | 4 ++-- winsup/cygwin/dll_init.cc | 4 ++-- winsup/cygwin/local_includes/dll_init.h | 2 +- winsup/cygwin/release/3.6.1 | 3 +++ 4 files changed, 8 insertions(+), 5 deletions(-) diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc index fb705247352e..f98c7db475f7 100644 --- a/winsup/cygwin/dlfcn.cc +++ b/winsup/cygwin/dlfcn.cc @@ -276,7 +276,7 @@ dlopen (const char *name, int flags) /* reference counting */ if (ret) { - dll *d = dlls.find (ret); + dll *d = dlls.find (ret, true); if (d) ++d->count; } @@ -349,7 +349,7 @@ dlclose (void *handle) if (handle != GetModuleHandle (NULL)) { /* reference counting */ - dll *d = dlls.find (handle); + dll *d = dlls.find (handle, true); if (!d || d->count <= 0) { errno = ENOENT; diff --git a/winsup/cygwin/dll_init.cc b/winsup/cygwin/dll_init.cc index 1a047511f8cc..c6fb94a43379 100644 --- a/winsup/cygwin/dll_init.cc +++ b/winsup/cygwin/dll_init.cc @@ -542,7 +542,7 @@ dll_list::topsort_visit (dll* d, bool seek_tail) dll * -dll_list::find (void *retaddr) +dll_list::find (void *retaddr, bool find_self) { MEMORY_BASIC_INFORMATION m; if (!VirtualQuery (retaddr, &m, sizeof m)) @@ -551,7 +551,7 @@ dll_list::find (void *retaddr) dll *d = &start; while ((d = d->next)) - if (d->type != DLL_SELF && d->handle == h) + if ((d->type != DLL_SELF || find_self) && d->handle == h) break; return d; } diff --git a/winsup/cygwin/local_includes/dll_init.h b/winsup/cygwin/local_includes/dll_init.h index 65f4213dbb7a..f79b1573ee09 100644 --- a/winsup/cygwin/local_includes/dll_init.h +++ b/winsup/cygwin/local_includes/dll_init.h @@ -131,7 +131,7 @@ public: int reload_on_fork; dll *operator [] (PCWCHAR ntname); dll *alloc (HINSTANCE, per_process *, dll_type); - dll *find (void *); + dll *find (void *, bool = false); void detach (void *); void init (); void load_after_fork (HANDLE); diff --git a/winsup/cygwin/release/3.6.1 b/winsup/cygwin/release/3.6.1 index 95c2c054e9ea..85c3f6c0554b 100644 --- a/winsup/cygwin/release/3.6.1 +++ b/winsup/cygwin/release/3.6.1 @@ -15,3 +15,6 @@ Fixes: in the SA_ONSTACK case, because locally-copied context on the normal stack area is not accessible from the signal handler. Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257714.html + +- Fix reference counting when dlopen/dlclose is called on the Cygwin DLL. + Addresses: https://cygwin.com/pipermail/cygwin/2025-March/257783.html