gnutls on mingw64

classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

gnutls on mingw64

Stephen Leake-3
I'm trying to get list-packages to use https, which requires gnutls. I'm
running Emacs master on mingw64.

gnutls-available-p returns nil. Running emacs under the debugger, I can
trace this to LoadLibraryW failing; the file name is
L"libgnutls-30.dll", which is in PATH as
D:\msys64\mingw64\bin\libgnutls-30.dll, installed via pacman.

Currently neither w32_delayed_load nor init_gnutls_functions calls
GetLastError; would it help to add that?

Since the file should be found, it seems DllMain is returning False?
What might be the reason for that?

--
-- Stephe

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Richard Copley-2
On Tue, 26 Nov 2019 at 12:35, Stephen Leake <[hidden email]> wrote:

> I'm trying to get list-packages to use https, which requires gnutls. I'm
> running Emacs master on mingw64.
>
> gnutls-available-p returns nil. Running emacs under the debugger, I can
> trace this to LoadLibraryW failing; the file name is
> L"libgnutls-30.dll", which is in PATH as
> D:\msys64\mingw64\bin\libgnutls-30.dll, installed via pacman.
>
> Currently neither w32_delayed_load nor init_gnutls_functions calls
> GetLastError; would it help to add that?
>
> Since the file should be found, it seems DllMain is returning False?
> What might be the reason for that?

Not a lot to go on here. Works just fine for me.

Are you missing a dependency? You can investigate DLL loading with <https://github.com/lucasg/Dependencies> (use it on libgnutls-30.dll, not on emacs.exe). Non-system dependencies here:

C:\msys64\mingw64\bin\libwinpthread-1.dll
C:\msys64\mingw64\bin\libgcc_s_seh-1.dll
C:\msys64\mingw64\bin\libgmp-10.dll
C:\msys64\mingw64\bin\libhogweed-5.dll
C:\msys64\mingw64\bin\libidn2-0.dll
C:\msys64\mingw64\bin\libintl-8.dll
C:\msys64\mingw64\bin\libnettle-7.dll
C:\msys64\mingw64\bin\libp11-kit-0.dll
C:\msys64\mingw64\bin\libtasn1-6.dll
C:\msys64\mingw64\bin\libunistring-2.dll

It's unlikely, but is LoadLibrary finding a mismatched (32-bit) libgnutls-30.dll? It needn't be on PATH. <https://docs.microsoft.com/en-gb/windows/win32/dlls/dynamic-link-library-search-order#standard-search-order-for-desktop-applications>.

GnuTLS's DllMain (defined by the CRT) always returns true, but there is a library constructor which calls gnutls_global_init. You could look there for further clues. <https://gitlab.com/gnutls/gnutls/blob/master/lib/global.c>

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Eli Zaretskii
In reply to this post by Stephen Leake-3
> From: Stephen Leake <[hidden email]>
> Date: Tue, 26 Nov 2019 04:34:10 -0800
>
> gnutls-available-p returns nil. Running emacs under the debugger, I can
> trace this to LoadLibraryW failing; the file name is
> L"libgnutls-30.dll", which is in PATH as
> D:\msys64\mingw64\bin\libgnutls-30.dll, installed via pacman.
>
> Currently neither w32_delayed_load nor init_gnutls_functions calls
> GetLastError; would it help to add that?

Does its value tell something useful in this case?

> Since the file should be found, it seems DllMain is returning False?
> What might be the reason for that?

Are you sure all of the dependencies of the DLL are also available and
appear first on PATH?  Maybe you have a DLL by the right name but
wrong architecture on PATH before that?

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Stephen Leake-3
In reply to this post by Richard Copley-2
Richard Copley <[hidden email]> writes:

> Are you missing a dependency?

Yes, sigh (see below).

> You can investigate DLL loading with <
> https://github.com/lucasg/Dependencies>

Thanks; that has a command line interface, so I can be sure it's using
the same PATH as Emacs

> (use it on libgnutls-30.dll, not on emacs.exe). Non-system
> dependencies here:
>
> C:\msys64\mingw64\bin\libhogweed-5.dll

Missing this

> C:\msys64\mingw64\bin\libnettle-7.dll

and this


So the dependency list in mingw pacman is incorrect for libgnutls. I've
reported this via the mingw64 github issues page:
https://github.com/msys2/MINGW-packages/issues/5997

Hmm. pacman has a package msys/libhogweed 3.5.1, which installs
d:/msys64/mingw64/bin/libhogweed-4.dll; wrong version. Sigh.

Similarly, package libnettle 3.5 installs libnettle-6.dll.

And I did pacman -Sy.

How did you get the required versions?

--
-- Stephe

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Richard Copley-2
On Wed, 27 Nov 2019 at 01:13, Stephen Leake <[hidden email]> wrote:
Richard Copley <[hidden email]> writes:

So the dependency list in mingw pacman is incorrect for libgnutls. I've
reported this via the mingw64 github issues page:
https://github.com/msys2/MINGW-packages/issues/5997

Hmm. pacman has a package msys/libhogweed 3.5.1, which installs
d:/msys64/mingw64/bin/libhogweed-4.dll; wrong version. Sigh.

That is the package dependent on the msys DLL, not the native package; and that path doesn't seem right. Here, the files belonging to the msys/libhogweed package are:

$ pacman -Ql libhogweed
libhogweed /usr/
libhogweed /usr/bin/
libhogweed /usr/bin/msys-hogweed-5.dll

This command shows which package owns the native libhogweed DLL on my system:

$ pacman -Qo /mingw64/bin/libhogweed-5.dll
/mingw64/bin/libhogweed-5.dll is owned by mingw-w64-x86_64-nettle 3.5.1-1
 
Similarly, package libnettle 3.5 installs libnettle-6.dll.

$ pacman -Ssq nettle
mingw-w64-i686-nettle
mingw-w64-x86_64-nettle
libnettle
libnettle-devel
nettle
 
It's the native package, mingw-w64-x86_64-nettle, that you want.

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Stephen Leake-3
Richard Copley <[hidden email]> writes:

> On Wed, 27 Nov 2019 at 01:13, Stephen Leake <[hidden email]>
> wrote:
>
>> Richard Copley <[hidden email]> writes:
>>
>> So the dependency list in mingw pacman is incorrect for libgnutls. I've
>> reported this via the mingw64 github issues page:
>> https://github.com/msys2/MINGW-packages/issues/5997
>>
>> Hmm. pacman has a package msys/libhogweed 3.5.1, which installs
>> d:/msys64/mingw64/bin/libhogweed-4.dll; wrong version. Sigh.
>>
> $ pacman -Ssq nettle
> mingw-w64-i686-nettle
> mingw-w64-x86_64-nettle
> libnettle
> libnettle-devel
> nettle
>
> It's the native package, mingw-w64-x86_64-nettle, that you want.

Sigh; I only searched for "libnettle", not "nettle".

Now gnutls-available-p is returning non-nil; thanks for your help.

--
-- Stephe

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Stephen Leake-3
In reply to this post by Eli Zaretskii
Eli Zaretskii <[hidden email]> writes:

>> From: Stephen Leake <[hidden email]>
>> Date: Tue, 26 Nov 2019 04:34:10 -0800
>>
>> gnutls-available-p returns nil. Running emacs under the debugger, I can
>> trace this to LoadLibraryW failing; the file name is
>> L"libgnutls-30.dll", which is in PATH as
>> D:\msys64\mingw64\bin\libgnutls-30.dll, installed via pacman.
>>
>> Currently neither w32_delayed_load nor init_gnutls_functions calls
>> GetLastError; would it help to add that?
>
> Does its value tell something useful in this case?

I did not modify the code to find out, but I'm guessing it's the
standard unhelpful "could not find the file" without the file name.

--
-- Stephe

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Eli Zaretskii
> From: Stephen Leake <[hidden email]>
> Date: Wed, 27 Nov 2019 02:00:09 -0800
>
> >> Currently neither w32_delayed_load nor init_gnutls_functions calls
> >> GetLastError; would it help to add that?
> >
> > Does its value tell something useful in this case?
>
> I did not modify the code to find out, but I'm guessing it's the
> standard unhelpful "could not find the file" without the file name.

But it did find the file, it just couldn't load it because some of its
dependencies were of incorrect architecture/ABI.

IMO, it only makes sense to call GetLastError and display the results
to the user if the message will allow the user figure out what went
wrong and how to fix it.

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Stephen Leake-3
Eli Zaretskii <[hidden email]> writes:

>> From: Stephen Leake <[hidden email]>
>> Date: Wed, 27 Nov 2019 02:00:09 -0800
>>
>> >> Currently neither w32_delayed_load nor init_gnutls_functions calls
>> >> GetLastError; would it help to add that?
>> >
>> > Does its value tell something useful in this case?
>>
>> I did not modify the code to find out, but I'm guessing it's the
>> standard unhelpful "could not find the file" without the file name.
>
> But it did find the file, it just couldn't load it because some of its
> dependencies were of incorrect architecture/ABI.

It found libgnutls-30.dll, which was the top level file it was
looking for. But that depends on libhogweed-5.dll and libnettle-7.dll,
which were not found.

> IMO, it only makes sense to call GetLastError and display the results
> to the user if the message will allow the user figure out what went
> wrong and how to fix it.

Yes.

<rant> I keep hoping Microsoft will do better, but I'm always
disappointed. The most common error I get is "file not found" because
PATH is wrong or the file is not installed, when it's perfectly clear
that the system knows the name of the file it's looking for, but _I_
don't, and it's not telling me! _very_ frustrating; Gnu/Linux is much
better here. So I assume that's the error message GetLastError will
return here. </rant>

I'm also assuming that whoever wrote w32_delayed_load tested calling
GetLastError, got an unhelpful message, and deleted it. It would be nice
if there was a comment saying that. If I get motivated, I might try that
experiment, but given the above, it's not high on my list.

--
-- Stephe

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Richard Copley-2
On Thu, 28 Nov 2019 at 21:08, Stephen Leake <[hidden email]> wrote:
<rant> I keep hoping Microsoft will do better, but I'm always
disappointed. The most common error I get is "file not found" because
PATH is wrong or the file is not installed, when it's perfectly clear
that the system knows the name of the file it's looking for, but _I_
don't, and it's not telling me! _very_ frustrating; Gnu/Linux is much
better here. So I assume that's the error message GetLastError will
return here. </rant>

I'm also assuming that whoever wrote w32_delayed_load tested calling
GetLastError, got an unhelpful message, and deleted it. It would be nice
if there was a comment saying that. If I get motivated, I might try that
experiment, but given the above, it's not high on my list.

I see where you're coming from but I'm not sure you're being even-handed. I'm not their advocate, but you can work reasonably seriously with Microsoft Windows operating systems if you have to, despite the obvious disadvantages.

GetLastError() is just an integer, like errno. You must have to do a little more work to get descriptive errors from other systems? There's probably an equivalent. The Application error log in Event Viewer springs to mind.

The doc for LoadLibrary (<https://docs.microsoft.com/en-gb/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibrarya>) says: "To enable or disable error messages displayed by the loader during DLL loads, use theSetErrorMode function". I think the errors are displayed in a message box, but it might be helpful for debugging, at least if it's an application you can recompile.

("Dependencies" gets detailed information somehow. But for all I know (I haven't looked) it emulates the loader to see what happens.)

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Juanma Barranquero
In reply to this post by Stephen Leake-3


On Thu, Nov 28, 2019 at 10:08 PM Stephen Leake <[hidden email]> wrote:

> I'm also assuming that whoever wrote w32_delayed_load tested calling
> GetLastError, got an unhelpful message, and deleted it. It would be nice
> if there was a comment saying that.

"Whoever wrote w32_delayed_load" didn't do that, because the already existing code
that loaded the image libraries didn't do it either. The whoever-dude just added a
mechanism to allow the user to add new image libraries on their own, which was
previously impossible because they were hard-coded (if such-and-such-v2 loads, then
good, else if such-and-such-v1 loads, then good too, else oh no!).

I'm not saying that the whoever-dude shouldn't have done what you suggest, just
that he was fixing other issue and didn't even think of calling GetLastError.

Bad, bad whoever-dude! ;-)

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Eli Zaretskii
In reply to this post by Richard Copley-2
> From: Richard Copley <[hidden email]>
> Date: Thu, 28 Nov 2019 22:22:16 +0000
> Cc: emacs-devel <[hidden email]>
>
> GetLastError() is just an integer, like errno. You must have to do a little more work to get descriptive errors
> from other systems? There's probably an equivalent. The Application error log in Event Viewer springs to
> mind.

I usually do from the shell prompt:

   net helpmsg NNN

where NNN is the code returned by GetLastError.  (Programmatically,
there's the FormatMessage function to return the error string.)
Example:

  D:\usr\eli>net helpmsg 2

  The system cannot find the file specified.

> ("Dependencies" gets detailed information somehow. But for all I know (I haven't looked) it emulates the
> loader to see what happens.)

You can do the same with objdump, btw.

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Richard Copley-2
> On Thu, 28 Nov 2019 at 21:08, Stephen Leake <[hidden email]> wrote:
> > The most common error I get is "file not found" because
> > PATH is wrong or the file is not installed, when it's perfectly clear
> > that the system knows the name of the file it's looking for, but _I_
> > don't, and it's not telling me! _very_ frustrating; Gnu/Linux is much
> > better here. So I assume that's the error message GetLastError will
> > return here.

> On Fri, 29 Nov 2019 at 07:17, Eli Zaretskii <[hidden email]> wrote:
> > From: Richard Copley <[hidden email]>
>
> > GetLastError() is just an integer, like errno. You must have to do a little more work to get descriptive errors
> > from other systems? There's probably an equivalent. The Application error log in Event Viewer springs to
> > mind.
>
> I usually do from the shell prompt:
>
>    net helpmsg NNN
>
> where NNN is the code returned by GetLastError.  (Programmatically,
> there's the FormatMessage function to return the error string.)
> Example:
>
>   D:\usr\eli>net helpmsg 2
>
>   The system cannot find the file specified.
>

On GNU/Linux, the strerror family of functions can be used to format an error message. I'd demonstrate, but it would be patronising and beside the point.
You've brought us back to the error message Stephe complained about in the first place. I quoted him in the email you replied to. He complained that the message doesn't include the name of the file that was not found. He remarked "Gnu/Linux is much better here". I wondered how.

> > ("Dependencies" gets detailed information somehow. But for all I know (I haven't looked) it emulates the
> > loader to see what happens.)
>
> You can do the same with objdump, btw.

I'll leave the conversation here. It's not going anywhere.

Reply | Threaded
Open this post in threaded view
|

Re: gnutls on mingw64

Eli Zaretskii
> From: Richard Copley <[hidden email]>
> Date: Fri, 29 Nov 2019 08:32:01 +0000
> Cc: Stephen Leake <[hidden email]>, Emacs Development <[hidden email]>
>
> I'll leave the conversation here. It's not going anywhere.

I hoped I was helping by providing additional information about
figuring out DLL dependencies and interpreting system error numbers.
Apologies if it wasn't helpful.