Just to be sure that we are following up on the right path, I added the hack 
listed below making the JIT memory allocation shared. Then the os.fork() call 
works just fine for a simple test program (also included below). Obviously 
that's not an actual solution as the parent and the child will need separate 
JIT memory allocations, but it pinpoints the issue. I will issue a report to 
the Cygwin folks, however a fix may or may not be slow in the coming. How hard 
would it be for Pypy to use malloc() instead of mmap() for Cygwin?. -- Uwe

*** pypy/pypy/rlib/rmmap.py     Wed May 30 08:11:31 2012
--- pypy/pypy/rlib/rmmap.py     Sat Jun  9 16:23:45 2012
***************
*** 14,19 ****
--- 14,20 ----
  _MS_WINDOWS = os.name == "nt"
  _LINUX = "linux" in sys.platform
  _64BIT = "64bit" in platform.architecture()[0]
+ _CYGWIN = "cygwin" == sys.platform
  
  class RValueError(Exception):
      def __init__(self, message):
***************
*** 692,698 ****
          so the memory has the executable bit set and gets allocated
          internally in case of a sandboxed process.
          """
!         flags = MAP_PRIVATE | MAP_ANONYMOUS
          prot = PROT_EXEC | PROT_READ | PROT_WRITE
          hintp = rffi.cast(PTR, hint.pos)
          res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
--- 693,703 ----
          so the memory has the executable bit set and gets allocated
          internally in case of a sandboxed process.
          """
!         if _CYGWIN:
!             # XXX Hack: JIT memory should be private but Cygwin's fork() fails
!             flags = MAP_SHARED | MAP_ANONYMOUS
!         else:
!             flags = MAP_PRIVATE | MAP_ANONYMOUS
          prot = PROT_EXEC | PROT_READ | PROT_WRITE
          hintp = rffi.cast(PTR, hint.pos)
          res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)

PS Here's a little test program.

import sys, os
from test import pystone
# run some code that uses the JIT
print "top-level process:", pystone.main()
print "top-level process:", pystone.main()

pid = os.fork()
if pid == 0:
    print "I'm the child, my PID is", os.getpid()
    print "child process:", pystone.main()
    print "child process:", pystone.main()
    sys.exit()
else:
    print "I'm the parent, my PID is", os.getpid(), " the child PID is", pid
    print "parent process:", pystone.main()
    print "parent process:", pystone.main()
    sys.exit()




________________________________
 From: Armin Rigo <ar...@tunes.org>
To: Uwe F. Mayer <uwe_f_ma...@yahoo.com> 
Cc: Amaury Forgeot d'Arc <amaur...@gmail.com>; Matti Picus 
<matti.pi...@gmail.com>; "pypy-dev@python.org" <pypy-dev@python.org> 
Sent: Thursday, June 7, 2012 10:27 PM
Subject: Re: [pypy-dev] Patches for Pypy under cygwin
 
Hi Uwe,

On Thu, Jun 7, 2012 at 9:21 PM, Uwe F. Mayer <uwe_f_ma...@yahoo.com> wrote:
>       3 [main] pypy-c 11788 fixup_mmaps_after_fork: ReadProcessMemory failed
> for MAP_PRIVATE address 0xB0010000, Win32 error 998

Yes, that's one of the mmap addresses used by the JIT, if available.

More to the point, googling for "fork cygwin mmap" shows that there
are open bugs with cygwin's fork() in the presence of MAP_PRIVATE
mmaps.  That's obviously why it fails.

I don't really know what we can reasonably do about that, short of
asking people to use some specific versions of cygwin where it seems
to work.  I can imagine what we could unreasonably do as work-around,
but that requires a lot of work and gross hacks that don't seem
appropriate to put in the pypy source just to support cygwin...  I
would recommend that you try to see it fixed on the cygwin side.


A bientôt,

Armin.
_______________________________________________
pypy-dev mailing list
pypy-dev@python.org
http://mail.python.org/mailman/listinfo/pypy-dev

Reply via email to