[MLton-user] cygwin fork?

Petersen, Leaf leaf.petersen at intel.com
Tue Sep 25 15:54:59 PDT 2007


The "use-mmap" solution seems to solve the problem - thanks!

I should have mentioned that I was using the Exn.keepHistory
functionality already, which was what led me to believe that the C
"fork" function was indeed being called.  What I've seen is consistent
with your suggestion below that the fork function is setting errno when
called from ML but not when called from C.

Thanks,
Leaf 

>-----Original Message-----
>From: Matthew Fluet [mailto:fluet at tti-c.org] 
>Sent: Tuesday, September 25, 2007 6:38 AM
>To: Petersen, Leaf
>Cc: MLton-user at mlton.org
>Subject: Re: [MLton-user] cygwin fork?
>
>
>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 
>option.
>
>(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 mailing list