Mail Archives: cygwin/2003/02/28/08:31:50
--Multipart_Fri__28_Feb_2003_13:34:04_+0000_101a2960
Content-Type: text/plain; charset=US-ASCII
Content-Transfer-Encoding: 7bit
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
--Multipart_Fri__28_Feb_2003_13:34:04_+0000_101a2960
Content-Type: text/plain;
name="dlldiff.txt"
Content-Disposition: attachment;
filename="dlldiff.txt"
Content-Transfer-Encoding: 7bit
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)
--Multipart_Fri__28_Feb_2003_13:34:04_+0000_101a2960
Content-Type: text/plain; charset=us-ascii
--
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/
--Multipart_Fri__28_Feb_2003_13:34:04_+0000_101a2960--
- Raw text -