[PATCH] Cygwin: dlfcn: fix ENOENT in dlclose

Corinna Vinschen corinna-cygwin@cygwin.com
Sun Mar 30 21:43:52 GMT 2025


Hi Yuri,

On Mar 30 23:00, Yuyi Wang wrote:
> dlclose tries to decrease the ref count of the dll* entry, but a new dll
> opened by dlopen doesn't create a new dll* entry.
> ---
>  winsup/cygwin/dlfcn.cc | 5 +++--
>  1 file changed, 3 insertions(+), 2 deletions(-)
> 
> diff --git a/winsup/cygwin/dlfcn.cc b/winsup/cygwin/dlfcn.cc
> index fb7052473..3093ec1be 100644
> --- a/winsup/cygwin/dlfcn.cc
> +++ b/winsup/cygwin/dlfcn.cc
> @@ -350,14 +350,15 @@ dlclose (void *handle)
>      {
>        /* reference counting */
>        dll *d = dlls.find (handle);
> -      if (!d || d->count <= 0)
> +      if (d && d->count <= 0)
>  	{
>  	  errno = ENOENT;
>  	  ret = -1;
>  	}
>        else
>  	{
> -	  --d->count;
> +	  if (d)
> +	    --d->count;
>  	  if (!FreeLibrary ((HMODULE) handle))
>  	    {
>  	      __seterrno ();
> -- 
> 2.48.1.windows.1-2

Thanks for the patch, but that's not the right way to fix this issue,
afaics.  I tested this scenario, and this problem only occurs with
dlopening cygwin1.dll.

The reason is that the dll_list::find method returns NULL if the found
DLL is cygwin1.dll.  This makes sense for other places where the method
is used, but it doesn't make sense for dlopen/dlclose.  
So dll_list::find needs a way to return the dll pointer so we can
refcount cygwin1.dll like any other DLL so dlclose succeeds.

While looking into it, I found another refcount problem in terms of
RTLD_NODELETE.  I fixed that too.

Please give the next test release cygwin-3.7.0-0.24.g98112b9f6f90
a try.


Thanks,
Corinna


More information about the Cygwin-patches mailing list