Hi
I think I've found the problem with dlopen()/fork() on Win ME as
reported in
http://cygwin.com/ml/cygwin/2003-02/msg02221.html
If I'm right, it also applies to win 95/98.

in dll_init.cc: (dll_list::load_after_fork) a call is made to 
LoadLibraryEx (d.name, NULL, DONT_RESOLVE_DLL_REFERENCES);

According to the MSDN library, at
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/loadlibraryex.asp
the symbol DONT_RESOLVE_DLL_REFERENCES is not supported on win 9x/Me. It
does not say what the result of using this value on those platforms is.
I suspect that this breaks the LoadLibraryEx call, so that the
subsequent FreeLibrary call ends up deallocating memory that was never
allocated, hence the crash.

I have tried a patched version of dll_init.cc that uses plain
LoadLibrary instead of LoadLibraryEx on win 9x/Me, and with this patched
cygwin1.dll my test program runs correctly on all platforms. I have
attached the patch (cvs diff -up dll_init.cc). Could someone please
review this patch and apply it if it is acceptable?

By the way, the current CVS has a problem with unix sockets - they are
verrrry slow - like several minutes to get a simple message through in
some cases. 

Regards,
Steven

Index: dll_init.cc
===================================================================
RCS file: /cvs/src/src/winsup/cygwin/dll_init.cc,v
retrieving revision 1.33
diff -u -p -r1.33 dll_init.cc
--- dll_init.cc 14 Nov 2002 04:29:39 -0000      1.33
+++ dll_init.cc 28 Feb 2003 13:14:41 -0000
@@ -304,35 +304,45 @@ dll_list::load_after_fork (HANDLE parent
         the parent had some of those. */
       if (d.type == DLL_LOAD)
        {
-         HMODULE h = LoadLibraryEx (d.name, NULL, DONT_RESOLVE_DLL_REFERENCES);
-
-         /* See if DLL will load in proper place.  If so, free it and reload
-            it the right way.
-            It sort of stinks that we can't invert the order of the FreeLibrary
-            and LoadLibrary since Microsoft documentation seems to imply that that
-            should do what we want.  However, since the library was loaded above,
-            the second LoadLibrary does not execute it's startup code unless it
-            is first unloaded. */
-         if (h == d.handle)
+         HMODULE h;
+         if (GetVersion() < 0x80000000) /* not on 9x/Me */
            {
-             FreeLibrary (h);
-             LoadLibrary (d.name);
+             h = LoadLibraryEx (d.name, NULL, DONT_RESOLVE_DLL_REFERENCES);
+             /* See if DLL will load in proper place.  If so, free it and reload
+                it the right way.
+                It sort of stinks that we can't invert the order of the FreeLibrary
+                and LoadLibrary since Microsoft documentation seems to imply that that
+                should do what we want.  However, since the library was loaded above,
+                the second LoadLibrary does not execute it's startup code unless it
+                is first unloaded. */
+             if (h == d.handle)
+               {
+                 FreeLibrary (h);
+                 LoadLibrary (d.name);
+               }
            }
-         else if (try2)
-           api_fatal ("unable to remap %s to same address as parent(%p) != %p",
-                      d.name, d.handle, h);
-         else
+         else /* 9x/Me */
+           h = LoadLibrary (d.name);
+           
+         if (h != d.handle)
            {
-             /* It loaded in the wrong place.  Dunno why this happens but it always
-                seems to happen when there are multiple DLLs attempting to load into
-                the same address space.  In the "forked" process, the second DLL 
always
-                loads into a different location. */
-             FreeLibrary (h);
-             /* Block all of the memory up to the new load address. */
-             reserve_upto (d.name, (DWORD) d.handle);
-             try2 = 1;         /* And try */
-             continue;         /*  again. */
+             if (try2)
+               api_fatal ("unable to remap %s to same address as parent(%p) != %p",
+                          d.name, d.handle, h);
+             else
+               {
+                 /* It loaded in the wrong place.  Dunno why this happens but it 
always
+                    seems to happen when there are multiple DLLs attempting to load 
into
+                    the same address space.  In the "forked" process, the second DLL 
always
+                    loads into a different location. */
+                 FreeLibrary (h);
+                 /* Block all of the memory up to the new load address. */
+                 reserve_upto (d.name, (DWORD) d.handle);
+                 try2 = 1;             /* And try */
+                 continue;             /*  again. */
+               }
            }
+           
          /* If we reached here, and try2 is set, then there is a lot of memory to
             release. */
          if (try2)

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

Reply via email to