Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT cygwin DOT com Mail-Followup-To: cygwin AT cygwin DOT com Delivered-To: mailing list cygwin AT cygwin DOT com Date: Fri, 28 Feb 2003 13:34:04 +0000 From: "Steven O'Brien" To: cygwin AT cygwin DOT com Subject: Re: bug report - DLL failure on win ME with gcc-3 Message-Id: <20030228133404.420ee242.steven.obrien2@ntlworld.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="Multipart_Fri__28_Feb_2003_13:34:04_+0000_101a2960" --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--