[PATCH] gwmem-check: add backtrace support

Alexander Malysh <[email protected]>
Newsgroups gmane.comp.mobile.kannel.devel
Message-ID <[email protected]>
Hallo together,

attached you can find a patch that adds backtrace support to gwmem-check.
w/o backtrace is this module really hard to use.

Comments and votes please!

-- 
Thanks,
Alex
gwmem-check-backtrace.patch (text/x-diff, 3.2 KB)
Index: gwlib/gwmem-check.c
===================================================================
RCS file: /home/cvs/gateway/gwlib/gwmem-check.c,v
retrieving revision 1.26
diff -a -u -p -r1.26 gwmem-check.c
--- gwlib/gwmem-check.c	22 Jan 2004 14:08:25 -0000	1.26
+++ gwlib/gwmem-check.c	20 Jan 2005 13:56:45 -0000
@@ -85,12 +85,17 @@
  * after it's been freed.
  * 
  * Richard Braakman
+ * Alexander Malysh (added backtrace support)
  */
 
+#include "gw-config.h"
 
 #include <stdlib.h>
 #include <errno.h>
 #include <string.h>
+#if HAVE_BACKTRACE
+#include <execinfo.h>
+#endif
 
 #include "gwlib.h"
 
@@ -146,6 +151,10 @@ struct area
     struct location allocator;     /* Caller that alloced area */
     struct location reallocator;   /* Caller that last realloced area */
     struct location claimer;       /* Owner of area, set by caller */
+#if HAVE_BACKTRACE
+    void *frames[10]; /* 10 callers should be sufficient */
+    size_t frame_size;
+#endif
 };
 
 /* Number of bytes to reserve on either side of each allocated area,
@@ -153,7 +162,8 @@ struct area
  * enough to hold a long. */
 #define MARKER_SIZE 16
 
-#define MAX_TAB_SIZE (1024*1024L)
+/* 100 MB */
+#define MAX_TAB_SIZE (100*1024*1024L)
 #define MAX_ALLOCATIONS ((long) (MAX_TAB_SIZE/sizeof(struct area)))
 
 /* Freed areas are thrown into the free ring.  They are not released
@@ -184,12 +194,12 @@ static long total_size;
 
 /* Static functions */
 
-static void lock(void)
+static inline void lock(void)
 {
     mutex_lock(&gwmem_lock);
 }
 
-static void unlock(void)
+static inline void unlock(void)
 {
     mutex_unlock(&gwmem_lock);
 }
@@ -241,7 +251,7 @@ static int untouched(unsigned char *p, s
 }
 
 /* Fill the end marker for this area */
-static void endmark(unsigned char *p, size_t size)
+static inline void endmark(unsigned char *p, size_t size)
 {
     fill(p + size, MARKER_SIZE, END_MARK_PATTERN);
 }
@@ -320,7 +330,7 @@ static void dump_area(struct area *area)
         unsigned char *p;
         char buf[MAX_DUMP * 3 + 1];
 
-    	p = area->area;
+        p = area->area;
         buf[0] = '\0';
         for (i = 0; i < area->area_size && i < MAX_DUMP; ++i)
             sprintf(strchr(buf, '\0'), "%02x ", p[i]);
@@ -328,6 +338,20 @@ static void dump_area(struct area *area)
         debug("gwlib.gwmem", 0, "Contents of area (first %d bytes):", MAX_DUMP);
         debug("gwlib.gwmem", 0, "  %s", buf);
     }
+#if HAVE_BACKTRACE
+    {
+        size_t i;
+        char **strings = backtrace_symbols(area->frames, area->frame_size);
+        debug("gwlib.gwmem", 0, "Backtrace of last malloc/realloc:");
+        for (i = 0; i < area->frame_size; i++) {
+            if (strings != NULL)
+                debug("gwlib.gwmem", 0, "%s", strings[i]);
+            else
+                debug("gwlib.gwmem", 0, "%p", area->frames[i]);
+        }
+        free(strings);
+    }
+#endif
 }
 
 static struct area *find_area(unsigned char *p)
@@ -408,6 +432,9 @@ static struct area *record_allocation(un
     area->allocator.filename = filename;
     area->allocator.lineno = lineno;
     area->allocator.function = function;
+#if HAVE_BACKTRACE
+    area->frame_size = backtrace(area->frames, sizeof(area->frames) / sizeof(void*));
+#endif
 
     startmark(area->area, num_allocations);
     endmark(area->area, area->area_size);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.