diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index fca19fb9731..64987548a11 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -199,6 +199,15 @@ extern size_t (*MEM_get_peak_memory)(void) ATTR_WARN_UNUSED_RESULT; #ifndef NDEBUG extern const char *(*MEM_name_ptr)(void *vmemh); +/** + * Change the debugging name/string assigned to the memory allocated at \a vmemh. Only affects the + * guarded allocator. The name must be a static string, because only a pointer to it is stored! + * + * Handy when debugging leaking memory allocated by some often called, generic function with a + * unspecific name. A caller with more info can set a more specific name, and see which call to the + * generic function allocates the leaking memory. + */ +extern void (*MEM_name_ptr_set)(void *vmemh, const char *str) ATTR_NONNULL(); #endif /** diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index f7979168799..63f06ced31d 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -49,6 +49,7 @@ size_t (*MEM_get_peak_memory)(void) = MEM_lockfree_get_peak_memory; #ifndef NDEBUG const char *(*MEM_name_ptr)(void *vmemh) = MEM_lockfree_name_ptr; +void (*MEM_name_ptr_set)(void *vmemh, const char *str) = MEM_lockfree_name_ptr_set; #endif void *aligned_malloc(size_t size, size_t alignment) @@ -128,6 +129,7 @@ void MEM_use_lockfree_allocator(void) #ifndef NDEBUG MEM_name_ptr = MEM_lockfree_name_ptr; + MEM_name_ptr_set = MEM_lockfree_name_ptr_set; #endif } @@ -159,5 +161,6 @@ void MEM_use_guarded_allocator(void) #ifndef NDEBUG MEM_name_ptr = MEM_guarded_name_ptr; + MEM_name_ptr_set = MEM_guarded_name_ptr_set; #endif } diff --git a/intern/guardedalloc/intern/mallocn_guarded_impl.c b/intern/guardedalloc/intern/mallocn_guarded_impl.c index 8bf1680e6f8..cd4b99ecde8 100644 --- a/intern/guardedalloc/intern/mallocn_guarded_impl.c +++ b/intern/guardedalloc/intern/mallocn_guarded_impl.c @@ -1199,4 +1199,18 @@ const char *MEM_guarded_name_ptr(void *vmemh) return "MEM_guarded_name_ptr(NULL)"; } + +void MEM_guarded_name_ptr_set(void *vmemh, const char *str) +{ + if (!vmemh) { + return; + } + + MemHead *memh = vmemh; + memh--; + memh->name = str; + if (memh->prev) { + MEMNEXT(memh->prev)->nextname = str; + } +} #endif /* NDEBUG */ diff --git a/intern/guardedalloc/intern/mallocn_intern.h b/intern/guardedalloc/intern/mallocn_intern.h index f8b16ff6ddf..ce5683a04ae 100644 --- a/intern/guardedalloc/intern/mallocn_intern.h +++ b/intern/guardedalloc/intern/mallocn_intern.h @@ -131,6 +131,7 @@ void MEM_lockfree_reset_peak_memory(void); size_t MEM_lockfree_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT; #ifndef NDEBUG const char *MEM_lockfree_name_ptr(void *vmemh); +void MEM_lockfree_name_ptr_set(void *vmemh, const char *str); #endif /* Prototypes for fully guarded allocator functions */ @@ -174,6 +175,7 @@ void MEM_guarded_reset_peak_memory(void); size_t MEM_guarded_get_peak_memory(void) ATTR_WARN_UNUSED_RESULT; #ifndef NDEBUG const char *MEM_guarded_name_ptr(void *vmemh); +void MEM_guarded_name_ptr_set(void *vmemh, const char *str); #endif #ifdef __cplusplus diff --git a/intern/guardedalloc/intern/mallocn_lockfree_impl.c b/intern/guardedalloc/intern/mallocn_lockfree_impl.c index 300e2000a14..b5ee539ff4d 100644 --- a/intern/guardedalloc/intern/mallocn_lockfree_impl.c +++ b/intern/guardedalloc/intern/mallocn_lockfree_impl.c @@ -426,4 +426,8 @@ const char *MEM_lockfree_name_ptr(void *vmemh) return "MEM_lockfree_name_ptr(NULL)"; } + +void MEM_lockfree_name_ptr_set(void *UNUSED(vmemh), const char *UNUSED(str)) +{ +} #endif /* NDEBUG */