be explicit about memory tracking in os.c

This commit is contained in:
daanx 2023-04-23 16:40:01 -07:00
parent c9dd6f6dc9
commit 7f93bf02c9
4 changed files with 26 additions and 7 deletions

View file

@ -370,7 +370,7 @@ void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset
// try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data) // try to allocate in an arena if the alignment is small enough and the object is not too small (as for heap meta data)
if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0) { if (size >= MI_ARENA_MIN_OBJ_SIZE && alignment <= MI_SEGMENT_ALIGN && align_offset == 0) {
void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld); void* p = mi_arena_try_alloc(numa_node, size, alignment, commit, allow_large, req_arena_id, memid, tld);
if (p != NULL) return p; if (p != NULL) return p;
// otherwise, try to first eagerly reserve a new arena // otherwise, try to first eagerly reserve a new arena
if (req_arena_id == _mi_arena_id_none()) { if (req_arena_id == _mi_arena_id_none()) {
@ -396,7 +396,7 @@ void* _mi_arena_alloc_aligned(size_t size, size_t alignment, size_t align_offset
} }
else { else {
return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld->stats); return _mi_os_alloc_aligned(size, alignment, commit, allow_large, memid, tld->stats);
} }
} }
void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld) void* _mi_arena_alloc(size_t size, bool commit, bool allow_large, mi_arena_id_t req_arena_id, mi_memid_t* memid, mi_os_tld_t* tld)

View file

@ -155,6 +155,7 @@ static void mi_os_prim_free(void* addr, size_t size, bool still_committed, mi_st
mi_assert_internal((size % _mi_os_page_size()) == 0); mi_assert_internal((size % _mi_os_page_size()) == 0);
if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr) if (addr == NULL || size == 0) return; // || _mi_os_is_huge_reserved(addr)
int err = _mi_prim_free(addr, size); int err = _mi_prim_free(addr, size);
mi_track_mem_noaccess(addr,size);
if (err != 0) { if (err != 0) {
_mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr); _mi_warning_message("unable to free OS memory (error: %d (0x%x), size: 0x%zx bytes, address: %p)\n", err, err, size, addr);
} }
@ -218,7 +219,12 @@ static void* mi_os_prim_alloc(size_t size, size_t try_alignment, bool commit, bo
_mi_stat_increase(&stats->reserved, size); _mi_stat_increase(&stats->reserved, size);
if (commit) { if (commit) {
_mi_stat_increase(&stats->committed, size); _mi_stat_increase(&stats->committed, size);
mi_track_mem_defined(p,size); // seems needed for asan (or `mimalloc-test-api` fails) // seems needed for asan (or `mimalloc-test-api` fails)
if (*is_zero) { mi_track_mem_defined(p,size); }
else { mi_track_mem_undefined(p,size); }
}
else {
mi_track_mem_noaccess(p,size);
} }
} }
return p; return p;
@ -283,7 +289,7 @@ static void* mi_os_prim_alloc_aligned(size_t size, size_t alignment, bool commit
if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); } if (post_size > 0) { mi_os_prim_free((uint8_t*)aligned_p + mid_size, post_size, commit, stats); }
// we can return the aligned pointer on `mmap` (and sbrk) systems // we can return the aligned pointer on `mmap` (and sbrk) systems
p = aligned_p; p = aligned_p;
*base = aligned_p; // since we freed the pre part, `*base == p`. *base = aligned_p; // since we freed the pre part, `*base == p`.
} }
} }
@ -417,7 +423,10 @@ bool _mi_os_commit(void* addr, size_t size, bool* is_zero, mi_stats_t* tld_stats
if (os_is_zero && is_zero != NULL) { if (os_is_zero && is_zero != NULL) {
*is_zero = true; *is_zero = true;
mi_assert_expensive(mi_mem_is_zero(start, csize)); mi_assert_expensive(mi_mem_is_zero(start, csize));
} }
// note: the following seems required for asan (otherwise `mimalloc-test-stress` fails)
if (os_is_zero) { mi_track_mem_defined(start,csize); }
else { mi_track_mem_undefined(start,csize); }
return true; return true;
} }
@ -439,6 +448,7 @@ static bool mi_os_decommit_ex(void* addr, size_t size, bool* needs_recommit, mi_
_mi_warning_message("cannot decommit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); _mi_warning_message("cannot decommit OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize);
} }
mi_assert_internal(err == 0); mi_assert_internal(err == 0);
mi_track_mem_noaccess(start,csize);
return (err == 0); return (err == 0);
} }
@ -468,6 +478,7 @@ bool _mi_os_reset(void* addr, size_t size, mi_stats_t* stats) {
if (err != 0) { if (err != 0) {
_mi_warning_message("cannot reset OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize); _mi_warning_message("cannot reset OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", err, err, start, csize);
} }
mi_track_mem_undefined(start,csize);
return (err == 0); return (err == 0);
} }
@ -517,6 +528,8 @@ static bool mi_os_protectx(void* addr, size_t size, bool protect) {
if (err != 0) { if (err != 0) {
_mi_warning_message("cannot %s OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", (protect ? "protect" : "unprotect"), err, err, start, csize); _mi_warning_message("cannot %s OS memory (error: %d (0x%x), address: %p, size: 0x%zx bytes)\n", (protect ? "protect" : "unprotect"), err, err, start, csize);
} }
if (protect) { mi_track_mem_noaccess(start,csize); }
else { mi_track_mem_undefined(start,csize); }
return (err == 0); return (err == 0);
} }
@ -639,6 +652,8 @@ void* _mi_os_alloc_huge_os_pages(size_t pages, int numa_node, mi_msecs_t max_mse
*memid = _mi_memid_create_os(true /* is committed */, all_zero, true /* is_large */); *memid = _mi_memid_create_os(true /* is committed */, all_zero, true /* is_large */);
memid->memkind = MI_MEM_OS_HUGE; memid->memkind = MI_MEM_OS_HUGE;
mi_assert(memid->is_pinned); mi_assert(memid->is_pinned);
if (all_zero) { mi_track_mem_defined(start,size); }
else { mi_track_mem_undefined(start,size); }
} }
return (page == 0 ? NULL : start); return (page == 0 ? NULL : start);
} }

View file

@ -190,7 +190,11 @@ static void* unix_mmap_prim(void* addr, size_t size, size_t try_alignment, int p
if (hint != NULL) { if (hint != NULL) {
p = mmap(hint, size, protect_flags, flags, fd, 0); p = mmap(hint, size, protect_flags, flags, fd, 0);
if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) { if (p==MAP_FAILED || !_mi_is_aligned(p,try_alignment)) {
#if MI_TRACK_ENABLED // asan sometimes does not instrument errno correctly?
int err = 0;
#else
int err = errno; int err = errno;
#endif
_mi_warning_message("unable to directly request hinted aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\n", err, err, size, try_alignment, hint); _mi_warning_message("unable to directly request hinted aligned OS memory (error: %d (0x%x), size: 0x%zx bytes, alignment: 0x%zx, hint address: %p)\n", err, err, size, try_alignment, hint);
} }
if (p!=MAP_FAILED) return p; if (p!=MAP_FAILED) return p;

View file

@ -536,9 +536,9 @@ static mi_segment_t* mi_segment_os_alloc(bool eager_delayed, size_t page_alignme
// commit failed; we cannot touch the memory: free the segment directly and return `NULL` // commit failed; we cannot touch the memory: free the segment directly and return `NULL`
_mi_arena_free(segment, segment_size, 0, memid, tld_os->stats); _mi_arena_free(segment, segment_size, 0, memid, tld_os->stats);
return NULL; return NULL;
} }
} }
MI_UNUSED(info_size); MI_UNUSED(info_size);
segment->memid = memid; segment->memid = memid;
segment->allow_decommit = !memid.is_pinned; segment->allow_decommit = !memid.is_pinned;