Guarded allocator: Function to rename block for debugging
We have plenty of sorta generic functions, that allocate memory with some generic name for debugging. When such a function is called and the memory leaks, it may be unclear which call to it allocated the unfreed memory (and thus which execution path leads to the leak). The added function is only available if `NDEBUG` is not defined. Differential Revision: https://developer.blender.org/D15605 Reviewed by: Sergey Sharybin, Bastien Montagne
This commit is contained in:
parent
fdd282021a
commit
28e0cc424d
|
@ -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
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
Loading…
Reference in New Issue