Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/libgc
diff options
context:
space:
mode:
authorGeoff Norton <grompf@sublimeintervention.com>2011-04-30 00:23:15 +0400
committerGeoff Norton <grompf@sublimeintervention.com>2011-04-30 00:34:27 +0400
commit84b9083b05ede4788e38e6617b6b2990c6cb2868 (patch)
treef89fb3a61ff16e6d3963506be5b87dd815ae9fb9 /libgc
parentb91eaaa40c7b0ddf0684f508cacbd21c651a77d8 (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')
-rw-r--r--libgc/os_dep.c9
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
}