From b12ae95d1dd1300bec9b54275d1447467a8e1569 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Fri, 10 Aug 2007 09:07:19 +0000 Subject: [PATCH] total allocation tracking. git-svn-id: file:///svn/unbound/trunk@507 be551aaa-1e26-0410-a405-d3ace91eadb9 --- configure.ac | 25 +++++++++++++ daemon/worker.c | 5 ++- doc/Changelog | 4 +++ doc/TODO | 2 ++ util/alloc.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 128 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 93580da71..f13c9017b 100644 --- a/configure.ac +++ b/configure.ac @@ -631,6 +631,31 @@ struct sockaddr_storage; #include "ldns/ldns.h" +/* use statistics for allocs and frees, for debug use */ +#define UNBOUND_ALLOC_STATS +#ifdef UNBOUND_ALLOC_STATS +# ifdef malloc +# undef malloc +# endif +# ifdef realloc +# undef realloc +# endif +# ifdef calloc +# undef calloc +# endif +# ifdef free +# undef free +# endif +# define malloc unbound_stat_malloc +# define calloc unbound_stat_calloc +# define free unbound_stat_free +# define realloc unbound_stat_realloc +void *unbound_stat_malloc(size_t size); +void *unbound_stat_calloc(size_t nmemb, size_t size); +void unbound_stat_free(void *ptr); +void *unbound_stat_realloc(void *ptr, size_t size); +#endif /* UNBOUND_ALLOC_STATS */ + /** default port for DNS traffic. */ #define UNBOUND_DNS_PORT 53 ]) diff --git a/daemon/worker.c b/daemon/worker.c index e5d118057..1773a3756 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -74,9 +74,12 @@ static void debug_total_mem() { extern void* unbound_start_brk; + extern size_t unbound_mem_alloc, unbound_mem_freed; void* cur = sbrk(0); int total = cur-unbound_start_brk; - log_info("Total heap memory estimate: %u", (unsigned)total); + log_info("Total heap memory estimate: %u total-alloc: %u " + "total-free: %u", (unsigned)total, + (unsigned)unbound_mem_alloc, (unsigned)unbound_mem_freed); } /** Report on memory usage by this thread and global */ diff --git a/doc/Changelog b/doc/Changelog index 56295e5a4..03db89e18 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,7 @@ +10 August 2007: Wouter + - malloc and free overrides that track total allocation and frees. + for memory debugging. + 9 August 2007: Wouter - canonicalization, signature checks - dname signature label count and unit test. diff --git a/doc/TODO b/doc/TODO index d25c95b76..da4f025d2 100644 --- a/doc/TODO +++ b/doc/TODO @@ -29,3 +29,5 @@ o (option) to not send replies to clients after a timeout of (say 5 secs) has o private TTL feature o pretend-dnssec-unaware, and pretend-edns-unaware modes for debug/workshops. o delegpt use rbtree for ns-list, to avoid slowdown for very large NS sets. +o be able to have different listen and query-to addresses to bind to, + so you can listen to localhost and query-to to the internet. diff --git a/util/alloc.c b/util/alloc.c index fcdf68871..97cd1eebc 100644 --- a/util/alloc.c +++ b/util/alloc.c @@ -252,3 +252,96 @@ size_t alloc_get_mem(struct alloc_cache* alloc) } return s; } + +/** global debug value to keep track of total memory mallocs */ +size_t unbound_mem_alloc = 0; +/** global debug value to keep track of total memory frees */ +size_t unbound_mem_freed = 0; +#ifdef UNBOUND_ALLOC_STATS +/** special value to know if the memory is being tracked */ +uint64_t mem_special = (uint64_t)0xfeed43327766abcdLL; +#ifdef malloc +#undef malloc +#endif +/** malloc with stats */ +void *unbound_stat_malloc(size_t size) +{ + void* res; + if(size == 0) size = 1; + res = malloc(size+16); + if(!res) return NULL; + unbound_mem_alloc += size; + memcpy(res, &size, sizeof(size)); + memcpy(res+8, &mem_special, sizeof(mem_special)); + return res+16; +} +#ifdef calloc +#undef calloc +#endif +/** calloc with stats */ +void *unbound_stat_calloc(size_t nmemb, size_t size) +{ + size_t s = (nmemb*size==0)?(size_t)1:nmemb*size; + void* res = calloc(1, s+16); + if(!res) return NULL; + unbound_mem_alloc += s; + memcpy(res, &s, sizeof(s)); + memcpy(res+8, &mem_special, sizeof(mem_special)); + return res+16; +} +#ifdef free +#undef free +#endif +/** free with stats */ +void unbound_stat_free(void *ptr) +{ + size_t s; + if(!ptr) return; + if(memcmp(ptr-8, &mem_special, sizeof(mem_special)) != 0) { + free(ptr); + return; + } + ptr-=16; + memcpy(&s, ptr, sizeof(s)); + memset(ptr+8, 0, 8); + unbound_mem_freed += s; + free(ptr); +} +#ifdef realloc +#undef realloc +#endif +/** realloc with stats */ +void *unbound_stat_realloc(void *ptr, size_t size) +{ + size_t cursz; + void* res; + if(!ptr) return unbound_stat_malloc(size); + if(memcmp(ptr-8, &mem_special, sizeof(mem_special)) != 0) { + return realloc(ptr, size); + } + if(size==0) { + unbound_stat_free(ptr); + return NULL; + } + ptr -= 16; + memcpy(&cursz, ptr, sizeof(cursz)); + if(cursz == size) { + /* nothing changes */ + return ptr; + } + res = malloc(size+16); + if(!res) return NULL; + unbound_mem_alloc += size; + unbound_mem_freed += cursz; + if(cursz > size) { + memcpy(res+16, ptr+16, size); + } else if(size > cursz) { + memcpy(res+16, ptr+16, cursz); + } + memset(ptr+8, 0, 8); + free(ptr); + memcpy(res, &size, sizeof(size)); + memcpy(res+8, &mem_special, sizeof(mem_special)); + return res+16; +} +#endif /* UNBOUND_ALLOC_STATS */ -- 2.47.2