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:
authorSergey Sharybin <sergey.vfx@gmail.com>2013-05-30 18:27:24 +0400
committerSergey Sharybin <sergey.vfx@gmail.com>2013-05-30 18:27:24 +0400
commit1be293629833a43a5ecf3a76c6ed838d183a2683 (patch)
treebcde692c387b9a0da38d18cbc7fb90aadf349db9 /intern/guardedalloc
parent7586580241f7eceb4961c2860b3cbe9b4e9bafd6 (diff)
Backtrace for unfreed memory blocks
Added an option to show backtrace from where non-freed datablock was allocated from. To enable this feature, simply enable DEBUG_BACKTRACE in mallocn.c file and all unfreed datablocks will be followed up by a backtrace. Currently works on linux and osx only, windows support is on TODO. This feature is for sure disabled by default, so does not affect any builds which don't explicitly define DEBUG_BACKTRACE.
Diffstat (limited to 'intern/guardedalloc')
-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);