diff options
-rw-r--r-- | intern/guardedalloc/intern/mallocn.c | 66 |
1 files changed, 65 insertions, 1 deletions
diff --git a/intern/guardedalloc/intern/mallocn.c b/intern/guardedalloc/intern/mallocn.c index 65d3c11bc23..48738acc22a 100644 --- a/intern/guardedalloc/intern/mallocn.c +++ b/intern/guardedalloc/intern/mallocn.c @@ -87,6 +87,17 @@ */ //#define DEBUG_THREADS +/* Only for debugging: + * Defining DEBUG_BACKTRACE will store a backtrace from where + * memory block was allocated and print this trace for all + * unfreed blocks. + */ +#define DEBUG_BACKTRACE + +#ifdef DEBUG_BACKTRACE +# define BACKTRACE_SIZE 100 +#endif + #ifdef DEBUG_MEMCOUNTER /* set this to the value that isn't being freed */ # define DEBUG_MEMCOUNTER_ERROR_VAL 0 @@ -127,6 +138,11 @@ typedef struct MemHead { #ifdef DEBUG_MEMDUPLINAME int need_free_name, pad; #endif + +#ifdef DEBUG_BACKTRACE + void *backtrace[BACKTRACE_SIZE]; + int backtrace_size; +#endif } MemHead; /* for openmp threading asserts, saves time troubleshooting @@ -147,6 +163,15 @@ typedef struct MemHead { static pthread_t mainid; #endif +#ifdef DEBUG_BACKTRACE +# if defined(__linux__) || defined(__APPLE__) +# include <execinfo.h> +// Windows is not supported yet. +//# elif defined(_MSV_VER) +//# include <DbgHelp.h> +# endif +#endif + typedef struct MemTail { int tag3, pad; } MemTail; @@ -409,6 +434,38 @@ void *MEM_recallocN(void *vmemh, size_t len) return newp; } +#ifdef DEBUG_BACKTRACE +# if defined(__linux__) || defined(__APPLE__) +static void make_memhead_backtrace(MemHead *memh) +{ + memh->backtrace_size = backtrace(memh->backtrace, BACKTRACE_SIZE); +} + +static void print_memhead_backtrace(MemHead *memh) +{ + char **strings; + int i; + + strings = backtrace_symbols(memh->backtrace, memh->backtrace_size); + for (i = 0; i < memh->backtrace_size; i++) { + print_error(" %s\n", strings[i]); + } + + free(strings); +} +# else +static void make_memhead_backtrace(MemHead *memh) +{ + (void) memh; /* Ignored. */ +} + +static void print_memhead_backtrace(MemHead *memh) +{ + (void) memh; /* Ignored. */ +} +# endif /* defined(__linux__) || defined(__APPLE__) */ +#endif /* DEBUG_BACKTRACE */ + static void make_memhead_header(MemHead *memh, size_t len, const char *str) { MemTail *memt; @@ -423,7 +480,11 @@ static void make_memhead_header(MemHead *memh, size_t len, const char *str) #ifdef DEBUG_MEMDUPLINAME memh->need_free_name = 0; #endif - + +#ifdef DEBUG_BACKTRACE + make_memhead_backtrace(memh); +#endif + memt = (MemTail *)(((char *) memh) + sizeof(MemHead) + len); memt->tag3 = MEMTAG3; @@ -674,6 +735,9 @@ static void MEM_printmemlist_internal(int pydict) print_error("%s len: " SIZET_FORMAT " %p\n", membl->name, SIZET_ARG(membl->len), membl + 1); #endif +#ifdef DEBUG_BACKTRACE + print_memhead_backtrace(membl); +#endif } if (membl->next) membl = MEMNEXT(membl->next); |