[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;
}