From bf9c3bd08847e7dc1972db52b419b21171bc6c6e Mon Sep 17 00:00:00 2001 From: Igor Kostenko Date: Mon, 14 Sep 2020 10:50:22 +0100 Subject: [PATCH 1/2] Fix rare access violation on out of memory --- src/region.c | 8 ++++++-- src/segment.c | 9 ++++++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/region.c b/src/region.c index bebc29fd..fa51c298 100644 --- a/src/region.c +++ b/src/region.c @@ -297,9 +297,13 @@ static void* mi_region_try_alloc(size_t blocks, bool* commit, bool* is_large, bo mi_bitmap_claim(®ion->commit, 1, blocks, bit_idx, &any_uncommitted); if (any_uncommitted) { mi_assert_internal(!info.x.is_large); - bool commit_zero; - _mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld); + bool commit_zero = false; + bool ok = _mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld); if (commit_zero) *is_zero = true; + if (!ok) + { + return NULL; + } } } else { diff --git a/src/segment.c b/src/segment.c index a5077711..35fc3ba7 100644 --- a/src/segment.c +++ b/src/segment.c @@ -208,7 +208,11 @@ static void mi_segment_protect(mi_segment_t* segment, bool protect, mi_os_tld_t* uint8_t* start = (uint8_t*)segment + segment->segment_size - os_psize; if (protect && !segment->mem_is_committed) { // ensure secure page is committed +#if (MI_DEBUG>1) + bool ok = +#endif _mi_mem_commit(start, os_psize, NULL, tld); + mi_assert_internal(ok); } mi_segment_protect_range(start, os_psize, protect); } @@ -606,8 +610,11 @@ static mi_segment_t* mi_segment_init(mi_segment_t* segment, size_t required, mi_ // ensure the initial info is committed if (segment->capacity < capacity) { bool commit_zero = false; - _mi_mem_commit(segment, pre_size, &commit_zero, tld->os); + bool ok = _mi_mem_commit(segment, pre_size, &commit_zero, tld->os); if (commit_zero) is_zero = true; + if (!ok) { + return NULL; + } } } } From 840eba28742b324d45b09e44e351767de29a8ced Mon Sep 17 00:00:00 2001 From: daan Date: Mon, 14 Sep 2020 09:02:06 -0700 Subject: [PATCH 2/2] improve handling of out-of-memory situations --- src/region.c | 8 ++++---- src/segment.c | 16 +++++++++------- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/src/region.c b/src/region.c index fa51c298..aa4f95b5 100644 --- a/src/region.c +++ b/src/region.c @@ -298,12 +298,12 @@ static void* mi_region_try_alloc(size_t blocks, bool* commit, bool* is_large, bo if (any_uncommitted) { mi_assert_internal(!info.x.is_large); bool commit_zero = false; - bool ok = _mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld); - if (commit_zero) *is_zero = true; - if (!ok) - { + if (!_mi_mem_commit(p, blocks * MI_SEGMENT_SIZE, &commit_zero, tld)) { + // failed to commit! unclaim and return + mi_bitmap_unclaim(®ion->in_use, 1, blocks, bit_idx); return NULL; } + if (commit_zero) *is_zero = true; } } else { diff --git a/src/segment.c b/src/segment.c index 35fc3ba7..0daf8ddb 100644 --- a/src/segment.c +++ b/src/segment.c @@ -207,14 +207,16 @@ static void mi_segment_protect(mi_segment_t* segment, bool protect, mi_os_tld_t* mi_assert_internal(MI_SECURE <= 1 || segment->page_kind >= MI_PAGE_LARGE); uint8_t* start = (uint8_t*)segment + segment->segment_size - os_psize; if (protect && !segment->mem_is_committed) { - // ensure secure page is committed -#if (MI_DEBUG>1) - bool ok = -#endif - _mi_mem_commit(start, os_psize, NULL, tld); - mi_assert_internal(ok); + if (protect) { + // ensure secure page is committed + if (_mi_mem_commit(start, os_psize, NULL, tld)) { // if this fails that is ok (as it is an unaccessible page) + mi_segment_protect_range(start, os_psize, protect); + } + } + } + else { + mi_segment_protect_range(start, os_psize, protect); } - mi_segment_protect_range(start, os_psize, protect); } else { // or protect every page