[MLton-user] cygwin fork?
fluet at tti-c.org
Tue Sep 25 06:37:31 PDT 2007
On Fri, 21 Sep 2007, Petersen, Leaf wrote:
> I just upgraded to the latest release of MLton, and simultaneously
> updated my cygwin to the latest version. Some combination of the two
> seems to have resulted in fork no longer working. In particular the
> following SML code
> val _ =
> case Posix.Process.fork ()
> of NONE =>
> print "Child"
> | SOME pid =>
> print "Parent"
> produces the following output when compiled and run with mlton:
> unhandled exception: SysErr: Function not implemented [nosys]
I see this behavior as well on my Cygwin/Windows platform.
However, if I invoke the program with the 'use-mmap' runtime option
(./z @MLton use-mmap --), then the program behaves as expected.
Does using the 'use-mmap' runtime option work on your larger
example/application? If so, you can "bake-in" the runtime option by
compiling your example/application with the '-runtime use-mmap' compiler
(One minor thing I noticed is that on Linux, the program always prints
"Child" before "Parent", while on Cygwin/Windows, the order is pretty
random. I believe that both behaviors are within the spec for fork.)
> 1) There are several hints in the source and on the web that there are
> issues with fork. However, in poking through the source, I couldn't
> figure out where this error was happening. As far as I could tell, the
> C "fork" function is being eventually called, and presumably is
> returning ENOSYS. And yet a similar C test program seems to work. What
> am I missing?
You could try compiling with
-const 'Exn.keepHistory true' -profile-include '\$\(SML_LIB\)'
to see a back-trace of where the exception is being raised.
I suspect that the ENOSYS is arising from the runtime system defaulting to
the Windows API VirtualAlloc/VirtualFree for memory management, rather
than the POSIX API mmap/free (provided by Cygwin). I believe that Cygwin
uses VirtualAlloc/VirtualFree to implement mmap/free, but it does so
maintaining particular invariants. Our use of VirtualAlloc/VirtualFree
messes up those invariants, which I presume Cygwin is relying upon in
order to properly copy the parent's memory to the child.
In the end, I suspect that we are being bitten by not using Cygwin as
intended. Cygwin gives a Unix-looking environment on Windows; it is
working on the assumption that one is compiling Unix programs (which
wouldn't normally call Windows API functions) on Windows. Hence, it isn't
surpising that calling Windows API functions (and,
VirtualAlloc/VirtualFree is a particularly low-level function) can break
the invariants that the Cygwin API is trying to maintain.
> 2) There are suggestions that using spawn is a good workaround. This
> seems to work correctly for me. However, I haven't figured out how to
> suppress stdin and stdout when using spawn as opposed to fork/exec.
> Anyone have experience with this?
More information about the MLton-user