Package: apachetop Version: 0.12.5-7 Severity: normal Tags: patch
hallo, hope I don't get too annoying. I've used apachetop now for some weeks running in screen on a moderately busy server - after some days (with 3-8 hits/s) it takes lots of ram, last time I've killed it it used over 300mb - so I started debugging, keeping the hits of the last 15min in memory should never take that much. The result are two found memory leaks, and two small changes/fixes to use even less ram. Description of the Changes: 1. src/timed_circle.cc src/hit_circle.cc missing twice: if (hit->ip_pos) im->sub_ref(hit->ip_pos); ip map entries are never freed, memory leak (notably if you have many users and a long running apachetop) needs small check in src/map.cc map::sub_ref(), for -1 in hit->ip_pos 2. src/timed_circle.cc src/hit_circle.cc if (hit->host_pos) - checks for '!= 0', but 0 is a valid position first entry in each map is never freed, memory leak (but small) still unfixed in my patch 3. src/map.cc map::destroy() calls tab_hash->destroy() twice, once direct and once through "delete tab_hash" (harmless because hashes are never freed/only at program exit) 4. src/map.cc map::sub_ref(): directly free/reinit tab positions to free no longer needed string memory And the patch: diff -ur apachetop-0.12.5/src/hits_circle.cc apachetop-0.12.5.new/src/hits_circle.cc --- apachetop-0.12.5/src/hits_circle.cc 2004-07-25 22:41:08.000000000 +0200 +++ apachetop-0.12.5.new/src/hits_circle.cc 2006-01-28 02:23:41.000000000 +0100 @@ -8,7 +8,7 @@ #include "apachetop.h" -extern map *hm, *um, *rm; +extern map *hm, *um, *rm, *im; int Hits_Circle::create(unsigned int passed_size) { @@ -48,7 +48,7 @@ hm->sub_ref(posptr->host_pos); um->sub_ref(posptr->url_pos); rm->sub_ref(posptr->ref_pos); - + im->sub_ref(posptr->ip_pos); } /* maintain some stats */ diff -ur apachetop-0.12.5/src/log.cc apachetop-0.12.5.new/src/log.cc --- apachetop-0.12.5/src/log.cc 2004-07-25 22:41:08.000000000 +0200 +++ apachetop-0.12.5.new/src/log.cc 2006-01-28 03:41:16.000000000 +0100 @@ -365,7 +365,8 @@ lb->want_host = false; lb->want_ip = false; delete lb->dns_query; - + lb->dns_query = NULL; + if (answer->status == adns_s_ok) { /* we have a reply */ diff -ur apachetop-0.12.5/src/map.cc apachetop-0.12.5.new/src/map.cc --- apachetop-0.12.5/src/map.cc 2004-05-08 01:46:16.000000000 +0200 +++ apachetop-0.12.5.new/src/map.cc 2006-01-28 03:42:24.000000000 +0100 @@ -41,7 +41,6 @@ { free(tab); - tab_hash->destroy(); delete tab_hash; return 0; @@ -99,7 +98,7 @@ * particular entry is incremented */ tab[x].refcount++; -// dprintf("%d Found %p %d for %s\n", time(NULL), this, x, string); +// dprintf("%d Found %p %d %d for %s\n", time(NULL), this, x, tab[x].refcount, string); return x; } @@ -188,10 +187,22 @@ void map::sub_ref(int pos) { -// dprintf("%d subref %p %d for %s\n", -// time(NULL), this, pos, tab[pos].string); +// dprintf("%d subref %p %d %d for %s\n", +// time(NULL), this, pos, tab[pos].refcount, tab[pos].string); + + /* -1 means no/invalid position, can happen with ip map */ + if (pos < 0) return; - if (tab[pos].refcount > 0) + if (tab[pos].refcount > 0) { tab[pos].refcount--; - + if ((tab[pos].refcount == 0) && (tab[pos].string)) { + /* remove from hash */ + tab_hash->remove(tab[pos].string); + + /* remove from table */ + free(tab[pos].string); + tab[pos].string = NULL; + tab[pos].time = 0; + } + } } diff -ur apachetop-0.12.5/src/timed_circle.cc apachetop-0.12.5.new/src/timed_circle.cc --- apachetop-0.12.5/src/timed_circle.cc 2004-05-13 17:43:31.000000000 +0200 +++ apachetop-0.12.5.new/src/timed_circle.cc 2006-01-28 03:41:09.000000000 +0100 @@ -15,7 +15,7 @@ extern time_t now; /* global ApacheTop-wide to save on time() calls */ extern struct gstat gstats; -extern map *hm, *um, *rm; +extern map *hm, *um, *rm, *im; int Timed_Circle::create(unsigned int size) { @@ -92,6 +92,7 @@ if (hit->host_pos) hm->sub_ref(hit->host_pos); if (hit->url_pos) um->sub_ref(hit->url_pos); if (hit->ref_pos) rm->sub_ref(hit->ref_pos); + if (hit->ip_pos) im->sub_ref(hit->ip_pos); } /* start at the beginning of the HIT array */ @@ -144,6 +145,7 @@ if (hit->host_pos) hm->sub_ref(hit->host_pos); if (hit->url_pos) um->sub_ref(hit->url_pos); if (hit->ref_pos) rm->sub_ref(hit->ref_pos); + if (hit->ip_pos) im->sub_ref(hit->ip_pos); /* store the data itself */ memcpy(hit, &lb, sizeof(lb)); -- System Information: Debian Release: testing/unstable APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.15.1-sdinet5-aurora Locale: LANG=en_US.ISO-8859-1, LC_CTYPE=de_DE.ISO-8859-1 (charmap=ISO-8859-1) Versions of packages apachetop depends on: ii fam 2.7.0-9 File Alteration Monitor ii libadns1 1.1-4 Asynchronous-capable DNS client li ii libc6 2.3.5-12 GNU C Library: Shared libraries an ii libfam0 2.7.0-9 Client library to control the FAM ii libgcc1 1:4.0.2-7 GCC support library ii libncurses5 5.5-1 Shared libraries for terminal hand ii libreadline5 5.1-5 GNU readline and history libraries ii libstdc++6 4.0.2-7 The GNU Standard C++ Library v3 apachetop recommends no packages. -- no debconf information -- To UNSUBSCRIBE, email to [EMAIL PROTECTED] with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]