[plt-scheme] 372: 3m does not check for VirtualAlloc failure

From: Eric Kidd (eric.kidd at iml.dartmouth.edu)
Date: Wed May 7 13:46:05 EDT 2008

Good afternoon!

When compiling a large amount of code with Halyard (roughly 20K lines)
with errortrace enabled, our memory usage frequently exceeds 400MB.[1]
This will generally cause mzscheme 372 3m to crash.

After a bit of poking around, it appears that the crash is caused by
VirtualAlloc returning NULL:

  static void *malloc_pages(size_t len, size_t alignment)
  {
    // ...
    return (void *)VirtualAlloc(NULL, len,
      MEM_COMMIT | MEM_RESERVE,
      PAGE_READWRITE);
  }
  #define malloc_dirty_pages(size,align) malloc_pages(size,align)

When this happens, the following code in GC_mark attempts to write
through a NULL pointer:

  /* Allocate and prep the page */
  work = (struct mpage *)malloc_dirty_pages(APAGE_SIZE, APAGE_SIZE);
  memset(work, 0, sizeof(struct mpage));

I'm not sure why VirtualAlloc is failing at only 400MB (the system has
barely even touched swap yet). But the GC should probably be prepared
for VirtualAlloc to return NULL, and do something sensible.

As always, thank you to the PLT Scheme for your code and advice!

Cheers,
Eric

[1] I'm not sure why the compiler allocates and holds onto so much
memory, but it all goes away when the namespace gets GC'd. Is the
compiler storing some kind of compilation-related data somewhere in
the module's data structures? I need to look into this...


Posted on the users mailing list.