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

Reply via email to