[MLton] Re: cygwoes

Mike Thomas miketh@paradigmgeo.com
Thu, 13 Oct 2005 10:51:57 +1000


Hi Matthew.

I compiled a slightly modified standalone version of that program
(below) under MinGW32 gcc and Cygwin gcc and got totally different
results for MinGW32 gcc which lead me to wonder whether there is
something like a C typecast mismatch problem in calculating the starting
point and/or passing the result back to VirtualFree or outputting the
results.

0x60000,0000 is 1.6 billion which is pretty high up in the Windows
memory map so I think you're looking in the wrong place for substantial
amounts of memory anyway.  Note that the MinGW32 version starts at
0x98,0000, much lower down.

May I also suggest that you check out the VM Validator tools avalable
free of the web.

I also seem to recall that Cygwin rebases certain DLL's in order to make
fork() work so the memory map may be different for Cygwin and it may
even be stuffing up the semantics of VirtualAlloc and friends in some
subtle way.  VM Validator will help to track that down.

In any event, I think the different start points needs to be explained.
Try following execution with gdb to see what is happening.

I am terribly sorry for not spending more time on this and appreciate
your helping out us Windows users but my Cygin installation is currently
in a mess which precludes using gdb and I am stuck with major time
constraints too great to chase that problem as well.

Cheers

Mike Thomas


========= MINGW32 =============

$ gcc vm.c -o vm

$ ./vm
start = 0x00980000  size = 8192
start = 0x00980000  size = 16384
start = 0x00980000  size = 32768
start = 0x00980000  size = 65536
start = 0x00980000  size = 131072
start = 0x00980000  size = 262144
start = 0x00980000  size = 524288
start = 0x00980000  size = 1048576
start = 0x00980000  size = 2097152
start = 0x00980000  size = 4194304
start = 0x00980000  size = 8388608
start = 0x00980000  size = 16777216
start = 0x00980000  size = 33554432
start = 0x00980000  size = 67108864
start = 0x00980000  size = 134217728
start = 0x00980000  size = 268435456

========= CYGWIN =============

$ gcc -g /c/ptdevw-nomks/vm.c -o vm.exe

miketh@water ~
$ ./vm
start = 0x60000000  size = 8192
Error: VirtualFree failed with error 87: The parameter is incorrect.
start = 0x60000000  size = 16384
Error: VirtualFree failed with error 87: The parameter is incorrect.
start = 0x18000000  size = 32768
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 65536
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 131072
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 262144
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 524288
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 1048576
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 2097152
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x18000000  size = 4194304
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x10000000  size = 8388608
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x10000000  size = 16777216
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x10000000  size = 33554432
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x10000000  size = 67108864
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x10000000  size = 134217728
Error: VirtualFree failed with error 487: Attempt to access invalid
address.
start = 0x08000000  size = 268435456
Error: VirtualFree failed with error 487: Attempt to access invalid
address.

=================================

/*#include <stdbool.h>*/
#include <stdio.h>
#include <windows.h>

typedef unsigned int uint;
typedef uint bool;

#define true TRUE 
#define false FALSE

#define inline


#define DEBUG 0

static void Windows_printError (LPTSTR lpszFunction) {
    TCHAR szBuf[80]; 
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError(); 

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

    wsprintfA(szBuf, 
        "%s failed with error %d: %s", 
        lpszFunction, dw, lpMsgBuf); 
 
    // MessageBox(NULL, szBuf, "Error", MB_OK); 
    fprintf(stderr, "Error: %s", szBuf);

    LocalFree(lpMsgBuf);
}

static inline void *Windows_mmapAnon (void *start, size_t length) {
  void *res;
  
  if (DEBUG)
    fprintf(stderr, "Windows_mmapAnon(0x%08x, %u) = ", (uint)start,
length);
  res = VirtualAlloc ((LPVOID)start, length, MEM_COMMIT,
PAGE_READWRITE);
  // res = VirtualAlloc (NULL, length, MEM_COMMIT, PAGE_READWRITE);
  if (DEBUG)
    fprintf(stderr, "0x%08x\n", (uint)res);
  return res;
}

static inline void Windows_release (void *base, size_t length) {
  if (DEBUG)
    fprintf(stderr, "Windows_release(0x%08x, %u)\n", (uint)base,
length);
  if (0 == VirtualFree (base, 0, MEM_RELEASE)) {
    Windows_printError("VirtualFree");
  }
}

static bool create (void **start, size_t size) {
  int direction = 1;
  unsigned int i;

  for (i = 0; i < 32; i++) {
    unsigned long address;
    
    address = i * 0x08000000ul;
    if (direction)
      address = 0xf8000000ul - address;
    *start = Windows_mmapAnon ((void*)address, size);
    if ((void*)NULL != *start) {
      direction = (0 == direction);
      return true;
    }
  }
  return false;
}

#define N 16
int main (int argc, char* argv[]) {
  void *start = NULL;
  size_t size = 4096;
  int i;
  
  for ( i = 0; i < N; i++ ) {
    size = 2 * size;
    if (create (&start, size)) {
      fprintf(stderr, "start = 0x%08x  size = %u\n",
              (unsigned int)start, (unsigned int)size);
      Windows_release(start, size);
    }
  }

  return 1;
}