This is the mail archive of the cygwin-developers mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: LoadLibrary error 487 (was Re: Please test latest developer snapshot)


On Sat, Feb 26, 2011 at 01:14:33PM -0500, Christopher Faylor wrote:
>On Sat, Feb 26, 2011 at 07:04:27PM +0100, Corinna Vinschen wrote:
>>On Feb 26 16:32, Corinna Vinschen wrote:
>>> I'm seriously puzzled.  Any input would be much appreciated.
>>> 
>>> On Feb 26 11:35, Corinna Vinschen wrote:
>>> > On Feb 25 16:09, David Rothenberger wrote:
>>> > > I was able to reproduce this using a clone of the git repository itself:
>>> > > 
>>> > > % uname -a
>>> > > CYGWIN_NT-5.1 tela 1.7.8s(0.236/5/3) 20110221 20:36:00 i686 Cygwin
>>> > > % git clone git://github.com/git/git.git
>>> > > Cloning into git...
>>> > > remote: Counting objects: 134689, done.
>>> > > remote: Compressing objects: 100% (39672/39672), done.
>>> > > remote: Total 134689 (delta 100250), reused 126970 (delta 93150)
>>> > > Receiving objects: 100% (134689/134689), 28.44 MiB | 621 KiB/s, done.
>>> > > Resolving deltas: 100% (100250/100250), done.
>>> > > % cd git/
>>> > > % git log
>>> > >       0 [main] git 3088 C:\cygwin\bin\git.exe: *** fatal error - could not load C:\WINDOWS\system32\winmm.dll, Win32 error 487
>>> > 
>>> > Thanks for the report.  I can reproduce this under Windows XP but
>>> > not under Windows 7.  Stay tuned.
>>> [...]
>>> The only workaround which works for me is to use the GetTickCount()
>>> function instead of the timeGetTime() function in hires_ms::nsecs():
>>> [...]
>>> Does anybody have an idea what could cause this problem?  I already
>>> googled for this but all I can come up with is questions with no reply
>>> or questions which refer to loading a DLL as data or resource.  And
>>> the replies aren't very helpful either.
>>
>>A couple of minutes ago I found this:
>>
>>http://www.tech-archive.net/Archive/DotNet/microsoft.public.dotnet.framework.clr/2007-02/msg00000.html
>>
>>While this is about static loading, the MSFT guy claims that winmm calls
>>FreeLibrary in DllMain().  His workaround to use LoadLibrary works for
>>the guy which has this problem.
>>
>>This gave me a crazy idea.  The problem doesn't occur in the git called
>>from the command line, but in a forked child.  And then, if winmm calls
>>FreeLibrary in DllMain (at least on XP), maybe that's our problem here,
>>too.  Fortunately there's the LoadLibraryEx function, which accepts the
>>parameter DONT_RESOLVE_DLL_REFERENCES, which in turn allows to get a
>>module handle without calling DllMain.  So I did this:
>>
>>Index: autoload.cc
>>===================================================================
>>RCS file: /cvs/src/src/winsup/cygwin/autoload.cc,v
>>retrieving revision 1.183
>>diff -u -p -r1.183 autoload.cc
>>--- autoload.cc	15 Feb 2011 15:56:00 -0000	1.183
>>+++ autoload.cc	26 Feb 2011 17:52:06 -0000
>>@@ -241,6 +241,14 @@ std_dll_init ()
>> 	     error code is neither NOACCESS nor DLL_INIT_FAILED, break out
>> 	     of the loop. */
>> 	  err = GetLastError ();
>>+	  if (err == ERROR_INVALID_ADDRESS)
>>+	    {
>>+	      if ((dll->handle = LoadLibraryExW (dll_path, 0,
>>+						 DONT_RESOLVE_DLL_REFERENCES))
>>+		  != NULL)
>>+		break;
>>+	      err = GetLastError ();
>>+	    }
>> 	  if (err != ERROR_NOACCESS && err != ERROR_DLL_INIT_FAILED)
>> 	    break;
>> 	  if (i < RETRY_COUNT)
>>
>>In theory, that should be seriously broken.  However, it actually works.
>>This LoadLibraryEx call returns a module handle, and the subsequently
>>fetched function pointer to timeGetTime() is really valid and returns
>>the expected values on XP!
>>
>>I don't understand that.  It shouldn't work.  But it does.
>>
>>Chris, what do you think?  Is that something we should try?  Maybe we
>>should try this only if we set a flag in some not yet existing
>>LoadDLLfuncEx4?
>
>I think I'd be ok with the change if you made that:
>
>if (err == ERROR_INVALID_ADDRESS && in_forkee)
>
>It's still not foolproof but at least we wouldn't be affecting non-forked
>processes and, in theory, the data segments of loaded dlls would be properly
>filled out in a fork().
>
>In fact, hmm.  I wonder if you could just change std_dll_init so that it
>always used DONT_RESOLVE_DLL_REFERENCES when in_forkee.  That might speed
>fork up a little.
>
>This also assumes that Cygwin got in first to load the dll and that it's
>being loaded during fork startup but I think that is a given, right?
>
>(Of course Microsoft says not to use this flag so I wonder if it will be
>gone or broken in Windows 8)

The other thing we could do is add a flag to thd dll_info struct which says
"Use DONT_RESOLVE_DLL_REFERENCES" either in the forkee or always depending
on what works for winm.dll.

cgf


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]