summaryrefslogtreecommitdiff
path: root/navit/debug.c
diff options
context:
space:
mode:
authormartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-05-01 10:34:46 +0000
committermartin-s <martin-s@ffa7fe5e-494d-0410-b361-a75ebd5db220>2010-05-01 10:34:46 +0000
commit9c61ad067e4f9e088058fa53fbbb858fd1091c7e (patch)
tree1357bee0704c91759ba52027e508735ff350528b /navit/debug.c
parentbf67d39649921c4f5895403378f1014ea1bfd4d0 (diff)
downloadnavit-svn-9c61ad067e4f9e088058fa53fbbb858fd1091c7e.tar.gz
Add:Core:Support for debugging memory leaks
git-svn-id: http://svn.code.sf.net/p/navit/code/trunk/navit@3213 ffa7fe5e-494d-0410-b361-a75ebd5db220
Diffstat (limited to 'navit/debug.c')
-rw-r--r--navit/debug.c128
1 files changed, 127 insertions, 1 deletions
diff --git a/navit/debug.c b/navit/debug.c
index fa73c783..8b35401b 100644
--- a/navit/debug.c
+++ b/navit/debug.c
@@ -87,7 +87,7 @@ debug_update_level(gpointer key, gpointer value, gpointer user_data)
}
void
-debug_level_set(const char *name, gint level)
+debug_level_set(const char *name, int level)
{
if (!strcmp(name, "segv")) {
segv_level=level;
@@ -222,7 +222,133 @@ void debug_set_logfile(const char *path)
}
}
+struct malloc_head {
+ int magic;
+ int size;
+ char *where;
+ void *return_address[8];
+ struct malloc_head *prev;
+ struct malloc_head *next;
+} *malloc_heads;
+
+struct malloc_tail {
+ int magic;
+};
+
+int mallocs;
+
+void
+debug_dump_mallocs(void)
+{
+ struct malloc_head *head=malloc_heads;
+ int i;
+ dbg(0,"mallocs %d\n",mallocs);
+ while (head) {
+ fprintf(stderr,"unfreed malloc from %s of size %d\n",head->where,head->size);
+ for (i = 0 ; i < 8 ; i++)
+ fprintf(stderr,"\tlist *%p\n",head->return_address[i]);
+#if 0
+ fprintf(stderr,"%s\n",head+1);
+#endif
+ head=head->next;
+ }
+}
+
+void *
+debug_malloc(const char *where, int line, const char *func, int size)
+{
+ struct malloc_head *head;
+ struct malloc_tail *tail;
+ if (!size)
+ return NULL;
+ mallocs++;
+ head=malloc(size+sizeof(*head)+sizeof(*tail));
+ head->magic=0xdeadbeef;
+ head->size=size;
+ head->prev=NULL;
+ head->next=malloc_heads;
+ malloc_heads=head;
+ if (head->next)
+ head->next->prev=head;
+ head->where=g_strdup_printf("%s:%d %s",where,line,func);
+ head->return_address[0]=__builtin_return_address(0);
+ head->return_address[1]=__builtin_return_address(1);
+ head->return_address[2]=__builtin_return_address(2);
+ head->return_address[3]=__builtin_return_address(3);
+ head->return_address[4]=__builtin_return_address(4);
+ head->return_address[5]=__builtin_return_address(5);
+ head->return_address[6]=__builtin_return_address(6);
+ head->return_address[7]=__builtin_return_address(7);
+ head++;
+ tail=(struct malloc_tail *)((unsigned char *)head+size);
+ tail->magic=0xdeadbef0;
+ return head;
+}
+
+
+void *
+debug_malloc0(const char *where, int line, const char *func, int size)
+{
+ void *ret=debug_malloc(where, line, func, size);
+ if (ret)
+ memset(ret, 0, size);
+ return ret;
+}
+
+char *
+debug_strdup(const char *where, int line, const char *func, const char *ptr)
+{
+ int size;
+ char *ret;
+
+ if (!ptr)
+ return NULL;
+ size=strlen(ptr)+1;
+ ret=debug_malloc(where, line, func, size);
+ memcpy(ret, ptr, size);
+ return ret;
+}
+
+char *
+debug_guard(const char *where, int line, const char *func, char *str)
+{
+ char *ret=debug_strdup(where, line, func, str);
+ g_free(str);
+ return ret;
+}
+
+void
+debug_free(const char *where, int line, const char *func, void *ptr)
+{
+ struct malloc_head *head,*tail;
+ if (!ptr)
+ return;
+ mallocs--;
+ head=(struct malloc_head *)((unsigned char *)ptr-sizeof(*head));
+ tail=(struct malloc_tail *)((unsigned char *)ptr+head->size);
+ if (head->magic != 0xdeadbeef || tail->magic != 0xdeadbef0) {
+ fprintf(stderr,"Invalid free from %s:%d %s\n",where,line,func);
+ }
+ head->magic=0;
+ tail->magic=0;
+ if (head->prev)
+ head->prev->next=head->next;
+ else
+ malloc_heads=head->next;
+ if (head->next)
+ head->next->prev=head->prev;
+ free(head->where);
+ free(head);
+}
+
+void
+debug_free_func(void *ptr)
+{
+ debug_free("unknown",0,"unknown",ptr);
+}
+
void debug_finished(void) {
+ debug_dump_mallocs();
g_free(gdb_program);
g_hash_table_destroy(debug_hash);
debug_destroy();