From 0ea5235cd1ff2a73c72647932cfba8f65bea670a Mon Sep 17 00:00:00 2001 From: daan Date: Sun, 30 Oct 2022 14:55:32 -0700 Subject: [PATCH 1/2] update readme for valgrind --- readme.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 46b48ef6..2dfadfb4 100644 --- a/readme.md +++ b/readme.md @@ -350,7 +350,12 @@ executables. To build with valgrind support, use the `MI_VALGRIND=ON` cmake opti ``` This can also be combined with secure mode or debug mode. -You can then run your programs directly under the `valgrind ` tool. +You can then run your programs directly under valgrind: + +``` +> valgrind +``` + If you rely on overriding `malloc`/`free` by mimalloc (instead of using the `mi_malloc`/`mi_free` API directly), you also need to tell `valgrind` to not intercept those calls itself, and use: From 74117d329de87fded131176fcc763260d48625b7 Mon Sep 17 00:00:00 2001 From: daan Date: Sun, 30 Oct 2022 19:00:54 -0700 Subject: [PATCH 2/2] fix realloc memory tracking in valgrind --- src/alloc-aligned.c | 8 +++++++- src/alloc.c | 8 +++++--- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/src/alloc-aligned.c b/src/alloc-aligned.c index 10e145b4..5672078e 100644 --- a/src/alloc-aligned.c +++ b/src/alloc-aligned.c @@ -31,7 +31,8 @@ static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t* } // otherwise over-allocate - void* p = _mi_heap_malloc_zero(heap, size + alignment - 1, zero); + const size_t oversize = size + alignment - 1; + void* p = _mi_heap_malloc_zero(heap, oversize, zero); if (p == NULL) return NULL; // .. and align within the allocation @@ -42,10 +43,15 @@ static mi_decl_noinline void* mi_heap_malloc_zero_aligned_at_fallback(mi_heap_t* mi_assert_internal(((uintptr_t)aligned_p + offset) % alignment == 0); mi_assert_internal(p == _mi_page_ptr_unalign(_mi_ptr_segment(aligned_p), _mi_ptr_page(aligned_p), aligned_p)); + #if MI_TRACK_ENABLED if (p != aligned_p) { mi_track_free(p); mi_track_malloc(aligned_p,size,zero); } + else { + mi_track_resize(aligned_p,oversize,size); + } + #endif return aligned_p; } diff --git a/src/alloc.c b/src/alloc.c index ee3f8b8e..fc613187 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -648,12 +648,12 @@ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) // else if size == 0 then reallocate to a zero-sized block (and don't return NULL, just as mi_malloc(0)). // (this means that returning NULL always indicates an error, and `p` will not have been freed in that case.) const size_t size = _mi_usable_size(p,"mi_realloc"); // also works if p == NULL (with size 0) - #if !MI_TRACK_ENABLED if mi_unlikely(newsize <= size && newsize >= (size / 2) && newsize > 0) { // note: newsize must be > 0 or otherwise we return NULL for realloc(NULL,0) // todo: adjust potential padding to reflect the new size? + mi_track_free(p); + mi_track_malloc(p,newsize,true); return p; // reallocation still fits and not more than 50% waste } - #endif void* newp = mi_heap_malloc(heap,newsize); if mi_likely(newp != NULL) { if (zero && newsize > size) { @@ -663,7 +663,9 @@ void* _mi_heap_realloc_zero(mi_heap_t* heap, void* p, size_t newsize, bool zero) } if mi_likely(p != NULL) { if mi_likely(_mi_is_aligned(p, sizeof(uintptr_t))) { // a client may pass in an arbitrary pointer `p`.. - _mi_memcpy_aligned(newp, p, (newsize > size ? size : newsize)); + const size_t copysize = (newsize > size ? size : newsize); + mi_track_mem_defined(p,copysize); // _mi_useable_size may be too large for byte precise memory tracking.. + _mi_memcpy_aligned(newp, p, copysize); } mi_free(p); // only free the original pointer if successful }