diff --git a/include/mimalloc-internal.h b/include/mimalloc-internal.h index 0543a6f4..97b96885 100644 --- a/include/mimalloc-internal.h +++ b/include/mimalloc-internal.h @@ -755,9 +755,13 @@ static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { // The base version declares the source parameter as MI_SOURCE_XPARAM and can pass it through as MI_SOURCE_XARG // // The big preprocessor macros that follow emit the 5 declarations with default -// implementations for the first 4 versions so only the 5th needs to be implemented. +// implementations for the first 4 versions so only the 5th (base version) needs to be implemented. +// +// For example, we write: +// > MI_ALLOC_API1(inline mi_decl_restrict void*, malloc_small, mi_heap_t*, heap, size_t, size) { ... } +// to implement `malloc_small` where we can use `MI_SOURCE_XARG` to pass on the possible source argument. // ------------------------------------------------------------------------------------------------------------- -#define MI_DEBUG_ONLY(x) x // we still allow dbg entry points in release mode to enable linking with a release build +#define MI_DEBUG_ONLY(x) x // we still emit dbg entry points in release mode to enable linking with a release build #define MI_ALLOC_API1(tp,name,tp0,arg0,tp1,arg1) \ static tp mi_base_##name(tp0 arg0, tp1 arg1 MI_SOURCE_XPARAM) mi_attr_noexcept; \ @@ -800,6 +804,9 @@ static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { static tp mi_base_##name(tp0 arg0, tp1 arg1, tp2 arg2, tp3 arg3, tp4 arg4, tp5 arg5 MI_SOURCE_XPARAM) mi_attr_noexcept +// MI_NEW_API +// These are for C++ `new` entry points that don't need entries with an explicit heap parameter (and can raise exceptions) + #define MI_NEW_API1(tp,name,tp1,arg1) \ static tp mi_base_##name(tp1 arg1 MI_SOURCE_XPARAM); \ tp mi_##name(tp1 arg1) { return mi_base_##name(arg1 MI_SOURCE_XRET()); } \ @@ -818,7 +825,9 @@ static inline uintptr_t _mi_thread_id(void) mi_attr_noexcept { MI_DEBUG_ONLY(tp dbg_mi_##name(tp1 arg1, tp2 arg2, tp3 arg3, mi_source_t __mi_source) { (void)__mi_source; return mi_base_##name(arg1, arg2, arg3 MI_SOURCE_XARG); }) \ static tp mi_base_##name(tp1 arg1, tp2 arg2, tp3 arg3 MI_SOURCE_XPARAM) - +// MI_SOURCE_API +// These are for C API entry points that don't need entries with an explicit heap parameter (like `aligned_alloc`) +// These are marked as noexcept. #define MI_SOURCE_API1(tp,name,tp1,arg1) \ static tp mi_base_##name(tp1 arg1 MI_SOURCE_XPARAM); \ diff --git a/include/mimalloc.h b/include/mimalloc.h index 13c50898..b7a388c2 100644 --- a/include/mimalloc.h +++ b/include/mimalloc.h @@ -495,13 +495,13 @@ template bool operator!=(const mi_stl_allocator&, const #else #define mi_return_address() NULL #endif -#define MI_SOURCE_XPARAM , mi_source_t __mi_source -#define MI_SOURCE_XARG , __mi_source -#define MI_SOURCE_XRET() , mi_source_ret(mi_return_address()) -#define MI_SOURCE_XLOC() , mi_source_loc(__FILE__,__LINE__) -#define MI_SOURCE_ARG(fun,...) dbg_##fun(__VA_ARGS__ MI_SOURCE_XARG) -#define MI_SOURCE_RET(fun,...) dbg_##fun(__VA_ARGS__ MI_SOURCE_XRET()) -#define MI_SOURCE_LOC(fun,...) dbg_##fun(__VA_ARGS__ MI_SOURCE_XLOC()) +#define MI_SOURCE_XPARAM , mi_source_t __mi_source // declare the extra source parameter +#define MI_SOURCE_XARG , __mi_source // pass the extra source parameter as a source argument +#define MI_SOURCE_XRET() , mi_source_ret(mi_return_address()) // pass the return address as a source argument +#define MI_SOURCE_XLOC() , mi_source_loc(__FILE__,__LINE__) // pass the current source location as a source argument +#define MI_SOURCE_ARG(fun,...) dbg_##fun(__VA_ARGS__ MI_SOURCE_XARG) // call the debug entry with the given source argument +#define MI_SOURCE_RET(fun,...) dbg_##fun(__VA_ARGS__ MI_SOURCE_XRET()) // call the debug entry with the return address as the source +#define MI_SOURCE_LOC(fun,...) dbg_##fun(__VA_ARGS__ MI_SOURCE_XLOC()) // call the debug entry with the current source location as the source #endif #if !defined(NDEBUG) && !defined(MI_DEBUG_NO_SOURCE_LOC) diff --git a/src/alloc.c b/src/alloc.c index 0498c767..bcd94673 100644 --- a/src/alloc.c +++ b/src/alloc.c @@ -11,6 +11,7 @@ terms of the MIT license. A copy of the license can be found in the file #include // memset, memcpy, strlen #include // malloc, exit +#include // snprintf #include // wcslen #define MI_IN_ALLOC_C @@ -240,7 +241,9 @@ static void mi_check_padding(const mi_page_t* page, const mi_block_t* block) { size_t size; size_t wrong; if (!mi_verify_padding(page,block,&size,&wrong)) { - _mi_page_block_error_message(EFAULT, page, block, "buffer overflow in heap block (write after %zu bytes)" ); + char msg[80]; + snprintf(msg, 79, "buffer overflow in heap block (write after %zu bytes)", (wrong > 0 ? wrong - 1 : wrong)); + _mi_page_block_error_message(EFAULT, page, block, msg ); } } diff --git a/test/main-override-static.c b/test/main-override-static.c index fac18ef7..c7c10ddc 100644 --- a/test/main-override-static.c +++ b/test/main-override-static.c @@ -17,11 +17,11 @@ int main() { mi_version(); // detect double frees and heap corruption - // double_free1(); - // double_free2(); - // corrupt_free(); - // block_overflow1(); - dangling_ptr_write(); + double_free1(); + double_free2(); + corrupt_free(); + block_overflow1(); + // dangling_ptr_write(); void* p1 = malloc(78); void* p2 = malloc(24);