Mail Archives: cygwin-developers/2001/12/07/14:37:11
--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--
- Raw text -