Mailing-List: contact cygwin-developers-help AT cygwin DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-developers-owner AT cygwin DOT com Delivered-To: mailing list cygwin-developers AT cygwin DOT com Date: Fri, 7 Dec 2001 14:25:05 -0500 From: Jason Tishler To: Cygwin-Developers Subject: dll_list::load_after_fork() blues Message-ID: <20011207142505.A1828@dothill.com> Mail-Followup-To: Cygwin-Developers Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="a/Al8wDWqLSIkMZN" Content-Disposition: inline User-Agent: Mutt/1.3.18i --a/Al8wDWqLSIkMZN Content-Type: text/plain; charset=us-ascii Content-Disposition: inline I am looking for some guidance on how to possibly solve the Cygwin Python fork() problem demonstrated by: http://cygwin.com/ml/cygwin/2001-12/msg00419.html After applying the attached patch to further instrument load_after_fork(), I get the attached output. From this test case, we see that load_after_fork() can currently handle the case when the DLL remaps to an address that is lower than the expected value (e.g. cygcrypto.dll). But, load_after_fork() cannot handle the case when the DLL remaps to a higher address (e.g., cygssl.dll). Does anyone have ideas on how to handle the too high case? Does anyone understand why the DLL in question seems to remap to an address that is exactly 0x10000 too high? Note that I have also tried a Python built without "-Wl,--enable-auto-image-base". I got identical results including the 0x10000 offset (albeit with different address). Thanks, Jason --a/Al8wDWqLSIkMZN Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="dll_init.cc.diff" ? save Index: dll_init.cc =================================================================== RCS file: /cvs/src/src/winsup/cygwin/dll_init.cc,v retrieving revision 1.21 diff -u -p -r1.21 dll_init.cc --- dll_init.cc 2001/10/21 03:38:41 1.21 +++ dll_init.cc 2001/12/07 18:57:29 @@ -305,13 +305,26 @@ dll_list::load_after_fork (HANDLE parent LoadLibrary (d.name); } else if (try2) + { + system_printf ("remap failed twice for %s with old handle = %p, new handle = %p", d.name, d.handle, h); + for (next = first; next; next = d.next) + { + DWORD nb; + /* Read the dll structure from the parent. */ + if (!ReadProcessMemory (parent, next, &d, sizeof (dll), &nb) || + nb != sizeof (dll)) + break; + system_printf ("name = %s handle = %p", d.name, d.handle); + } api_fatal ("unable to remap %s to same address as parent -- %p", d.name, 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. */ + system_printf ("remap failed for %s with old handle = %p, new handle = %p", d.name, d.handle, h); FreeLibrary (h); /* Block all of the memory up to the new load address. */ reserve_upto (d.name, (DWORD) d.handle); --a/Al8wDWqLSIkMZN Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="nothreads.txt" 0 [main] python 1668 dll_list::load_after_fork: remap failed for C:\cygwin\bin\cygcrypto.dll with old handle = 0x1A230000, new handle = 0x420000 69577 [main] python 1668 dll_list::load_after_fork: remap failed for C:\cygwin\bin\cygssl.dll with old handle = 0x1A2E0000, new handle = 0x1A2F0000 99003 [main] python 1668 dll_list::load_after_fork: remap failed twice for C:\cygwin\bin\cygssl.dll with old handle = 0x1A2E0000, new handle = 0x1A2F0000 115156 [main] python 1668 dll_list::load_after_fork: name = C:\home\jtishler\src\PythonCvs\nothreads\libpython2.2.dll handle = 0x69340000 129665 [main] python 1668 dll_list::load_after_fork: name = C:\cygwin\bin\cygcrypto.dll handle = 0x1A230000 186610 [main] python 1668 dll_list::load_after_fork: name = C:\cygwin\bin\cygssl.dll handle = 0x1A2E0000 215412 [main] python 1668 dll_list::load_after_fork: name = C:\home\jtishler\src\PythonCvs\nothreads\build\lib.cygwin-1.3.5-i686-2.2\_socket.dll handle = 0x69200000 C:\home\jtishler\src\PythonCvs\nothreads\python.exe: *** unable to remap C:\home\jtishler\src\PythonCvs\nothreads\build\lib.cygwin-1.3.5-i686-2.2\_socket.dll to same address as parent -- 0x1A2F0000 0 [main] python 1932 sync_with_child: child 1668(0x140) died before initialization with status code 0x1 38713 [main] python 1932 sync_with_child: *** child state child loading dlls Traceback (most recent call last): File "test2.py", line 4, in ? pid = os.fork() OSError: [Errno 11] Resource temporarily unavailable --a/Al8wDWqLSIkMZN--