[MLton] Re: cygwoes

Stephen Weeks MLton@mlton.org
Wed, 12 Oct 2005 01:56:01 -0700


Since Matthew has had some luck passing NULL to VirtualAlloc, I tried
cross-compiling the regressions for Cygwin with the following change
to the MLton runtime.

--- runtime/platform/windows.c  (revision 4101)
+++ runtime/platform/windows.c  (working copy)
@@ -110,7 +110,7 @@
 static inline void *Windows_mmapAnon (void *start, size_t length) {
         void *res;

-        res = VirtualAlloc ((LPVOID)start, length, MEM_COMMIT, PAGE_READWRITE);+        res = VirtualAlloc ((LPVOID)NULL/*start*/, length, MEM_COMMIT, PAGE_READWRITE);
         if (NULL == res)
                 res = (void*)-1;
         return res;

This has the same effect on Cygwin as the change Matthew made earlier
to line 1319 of gc.c.  For this test, I also switched
MLton_Platform_CygwinUseMmap back to FALSE.

All of the regressions cross compiled and ran (on Cygwin) without
problems.  So, I then cross built MLton with the the "VirtualAlloc
(NULL" in place.  The cross build worked fine, and the resulting MLton
was able to successfully type check all the libraries.  However, when
using that MLton to compile mllex, I got the following error

  mlton -target self mllex.mlb
  make[1]: Leaving directory `/tmp/package-mlton-cygwin/mllex'
  call to system failed with No child processes:
  gcc -std=gnu99 -c -I/tmp/package-mlton-cygwin/build/lib/include -O1 -fno-strict-aliasing -fomit-frame-pointer -w -fno-strength-reduce -fschedule-insns -fschedule-insns2 -malign-functions=5 -malign-jumps=2 -malign-loops=2 -o /tmp/filexU5SsF.o /tmp/file4bdZIW.3.c
  make[1]: *** [mllex] Error 1
  make: *** [tools] Error 2
      166 [main] ? 160 fork_copy: cygheap pass 0 failed, 0x611548E0..0x6115A7C8, done 0, windows pid 316, Win32 error 5

This is exactly the same error that Matthew saw last week when he
tried bootstrapping with his line 1319 hack.  I think Wesley was
correct when he said

  I think I recall that cygwin uses VirtualFree and Alloc internally
  to do mmap, and tracks the mappings it has created. When it 'fork's,
  it carefully copies all the mappings it knows of into a new
  process. When exec happens, it carefully overwrites the address
  space.

  If you are using VirtualFree/Alloc yourself, it seems reasonable to
  suppose that newer versions of cygwin be confused by the layout of
  the address space and setup gcc with broken/unclean memory.

I looked at our library code again and confirmed that to call gcc,
MLton is calling MLton.Process.spawnp, which calls the C
MLton_Process_spawn, which in turn calls the underlying Windows
spawnvp function.  I also cross compiled and ran the world1 regression
to confirm that fork raises "SysErr: Function not implemented [nosys]"
with useMmap = FALSE.  So there really is some bad interaction with
Cygwin, VirtualAlloc(NULL...), and spawnvp.