Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/guardedalloc/intern/mallocn.c66
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);