diff options
author | Geoff Norton <grompf@sublimeintervention.com> | 2011-04-30 00:23:15 +0400 |
---|---|---|
committer | Geoff Norton <grompf@sublimeintervention.com> | 2011-04-30 00:34:27 +0400 |
commit | 84b9083b05ede4788e38e6617b6b2990c6cb2868 (patch) | |
tree | f89fb3a61ff16e6d3963506be5b87dd815ae9fb9 /libgc/os_dep.c | |
parent | b91eaaa40c7b0ddf0684f508cacbd21c651a77d8 (diff) |
[boehm] Avoid a ENOMEM when allocating across an unallocated page
A very rare allocation pattern could cause the boehm free list to call
the GC_unmap_gap function, which actually calls down into munmap().
Darwins virtual memory manager will return a KERN_INVALID_ADDRESS
which is translated into a ENOMEM, if mprotect attempts to change
the protection of a range which includes an unallocated page.
We address this by just mmap() back to ANON, instead of actually
unallocating the page.
Diffstat (limited to 'libgc/os_dep.c')
-rw-r--r-- | libgc/os_dep.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/libgc/os_dep.c b/libgc/os_dep.c index ecaa27c7d82..8c8e0981dd6 100644 --- a/libgc/os_dep.c +++ b/libgc/os_dep.c @@ -2131,7 +2131,14 @@ void GC_unmap_gap(ptr_t start1, word bytes1, ptr_t start2, word bytes2) len -= free_len; } # else - if (len != 0 && munmap(start_addr, len) != 0) ABORT("munmap failed"); + if (len != 0) { + /* Immediately remap as above. */ + void * result; + result = mmap(start_addr, len, PROT_NONE, + MAP_PRIVATE | MAP_FIXED | OPT_MAP_ANON, + zero_fd, 0/* offset */); + if (result != (void *)start_addr) ABORT("mmap(...PROT_NONE...) failed"); + } GC_unmapped_bytes += len; # endif } |