From: Mark Andrews Date: Fri, 10 Jun 2005 07:00:20 +0000 (+0000) Subject: 1885. [func] Additional memory debugging support to track size X-Git-Tag: v9.2.6b1~78^2~34 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=d4d68515d23668cfe804ab2a174a7e427decedd8;p=thirdparty%2Fbind9.git 1885. [func] Additional memory debugging support to track size and mctx arguements. [RT #14814] --- diff --git a/CHANGES b/CHANGES index 8ce16735c16..fc12d53a062 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,6 @@ +1885. [func] Additional memory debugging support to track size + and mctx arguements. [RT #14814] + 1884. [bug] process_dhtkey() was using the wrong memory context to free some memory. [RT #14890] diff --git a/bin/named/main.c b/bin/named/main.c index f9a05128c97..f40a8c6324d 100644 --- a/bin/named/main.c +++ b/bin/named/main.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: main.c,v 1.146 2005/04/29 00:36:15 marka Exp $ */ +/* $Id: main.c,v 1.147 2005/06/10 07:00:19 marka Exp $ */ /*! \file */ @@ -228,7 +228,7 @@ lwresd_usage(void) { " [-f|-g] [-n number_of_cpus] [-p port] " "[-P listen-port] [-s]\n" " [-t chrootdir] [-u username] [-i pidfile]\n" - " [-m {usage|trace|record}]\n"); + " [-m {usage|trace|record|size|mctx}]\n"); } static void @@ -241,7 +241,7 @@ usage(void) { "usage: named [-4|-6] [-c conffile] [-d debuglevel] " "[-f|-g] [-n number_of_cpus]\n" " [-p port] [-s] [-t chrootdir] [-u username]\n" - " [-m {usage|trace|record}]\n"); + " [-m {usage|trace|record|size|mctx}]\n"); } static void @@ -309,6 +309,8 @@ static struct flag_def { { "trace", ISC_MEM_DEBUGTRACE }, { "record", ISC_MEM_DEBUGRECORD }, { "usage", ISC_MEM_DEBUGUSAGE }, + { "size", ISC_MEM_DEBUGSIZE }, + { "mctx", ISC_MEM_DEBUGCTX }, { NULL, 0 } }; diff --git a/bin/tests/system/start.pl b/bin/tests/system/start.pl index 8e8bc82f963..785ca63ab6a 100644 --- a/bin/tests/system/start.pl +++ b/bin/tests/system/start.pl @@ -15,7 +15,7 @@ # OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR # PERFORMANCE OF THIS SOFTWARE. -# $Id: start.pl,v 1.5 2004/03/10 02:19:52 marka Exp $ +# $Id: start.pl,v 1.6 2005/06/10 07:00:19 marka Exp $ # Framework for starting test servers. # Based on the type of server specified, check for port availability, remove @@ -129,7 +129,7 @@ sub start_server { if ($options) { $command .= "$options"; } else { - $command .= "-m record -c named.conf -d 99 -g"; + $command .= "-m record,size,mctx -c named.conf -d 99 -g"; } $command .= " >named.run 2>&1 &"; $pid_file = "named.pid"; @@ -139,7 +139,7 @@ sub start_server { if ($options) { $command .= "$options"; } else { - $command .= "-m record -C resolv.conf -d 99 -g -i lwresd.pid -P 9210 -p 5300"; + $command .= "-m record,size,mctx -C resolv.conf -d 99 -g -i lwresd.pid -P 9210 -p 5300"; } $command .= " >lwresd.run 2>&1 &"; $pid_file = "lwresd.pid"; diff --git a/lib/isc/include/isc/mem.h b/lib/isc/include/isc/mem.h index e026082ba8c..19acbd2eb04 100644 --- a/lib/isc/include/isc/mem.h +++ b/lib/isc/include/isc/mem.h @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mem.h,v 1.63 2005/06/04 05:32:48 jinmei Exp $ */ +/* $Id: mem.h,v 1.64 2005/06/10 07:00:20 marka Exp $ */ #ifndef ISC_MEM_H #define ISC_MEM_H 1 @@ -87,6 +87,9 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; #define ISC_MEM_DEBUGTRACE 0x00000001U #define ISC_MEM_DEBUGRECORD 0x00000002U #define ISC_MEM_DEBUGUSAGE 0x00000004U +#define ISC_MEM_DEBUGSIZE 0x00000008U +#define ISC_MEM_DEBUGCTX 0x00000010U +#define ISC_MEM_DEBUGALL 0x0000001FU /*!< * The variable isc_mem_debugging holds a set of flags for * turning certain memory debugging options on or off at @@ -104,6 +107,14 @@ LIBISC_EXTERNAL_DATA extern unsigned int isc_mem_debugging; * \li #ISC_MEM_DEBUGUSAGE * If a hi_water mark is set, print the maximium inuse memory * every time it is raised once it exceeds the hi_water mark. + * + * \li #ISC_MEM_DEBUGSIZE + * Check the size arguement being passed to isc_mem_put() matches + * that passed to isc_mem_get(). + * + * \li #ISC_MEM_DEBUGCTX + * Check the mctx arguement being passed to isc_mem_put() matches + * that passed to isc_mem_get(). */ /*@}*/ diff --git a/lib/isc/mem.c b/lib/isc/mem.c index f20bd51c60d..f15f7317105 100644 --- a/lib/isc/mem.c +++ b/lib/isc/mem.c @@ -15,7 +15,7 @@ * PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: mem.c,v 1.120 2005/06/04 05:32:48 jinmei Exp $ */ +/* $Id: mem.c,v 1.121 2005/06/10 07:00:19 marka Exp $ */ /*! \file */ @@ -99,6 +99,7 @@ typedef struct { */ union { size_t size; + isc_mem_t *ctx; char bytes[ALIGNMENT_SIZE]; } u; } size_info; @@ -976,6 +977,8 @@ void isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { isc_mem_t *ctx; isc_boolean_t want_destroy = ISC_FALSE; + size_info *si; + size_t oldsize; REQUIRE(ctxp != NULL); ctx = *ctxp; @@ -988,6 +991,26 @@ isc__mem_putanddetach(isc_mem_t **ctxp, void *ptr, size_t size FLARG) { */ *ctxp = NULL; + if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) { + if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) { + si = &(((size_info *)ptr)[-1]); + oldsize = si->u.size - ALIGNMENT_SIZE; + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) + oldsize -= ALIGNMENT_SIZE; + INSIST(oldsize == size); + } + isc__mem_free(ctx, ptr FLARG_PASS); + + MCTXLOCK(ctx, &ctx->lock); + ctx->references--; + if (ctx->references == 0) + want_destroy = ISC_TRUE; + MCTXUNLOCK(ctx, &ctx->lock); + if (want_destroy) + destroy(ctx); + + return; + } #if ISC_MEM_USE_INTERNAL_MALLOC MCTXLOCK(ctx, &ctx->lock); mem_putunlocked(ctx, ptr, size); @@ -1055,6 +1078,8 @@ isc__mem_get(isc_mem_t *ctx, size_t size FLARG) { REQUIRE(VALID_CONTEXT(ctx)); + if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) + return (isc__mem_allocate(ctx, size FLARG_PASS)); #if ISC_MEM_USE_INTERNAL_MALLOC MCTXLOCK(ctx, &ctx->lock); ptr = mem_getunlocked(ctx, size); @@ -1090,10 +1115,24 @@ void isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG) { isc_boolean_t call_water = ISC_FALSE; + size_info *si; + size_t oldsize; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(ptr != NULL); + if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) { + if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) { + si = &(((size_info *)ptr)[-1]); + oldsize = si->u.size - ALIGNMENT_SIZE; + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) + oldsize -= ALIGNMENT_SIZE; + INSIST(oldsize == size); + } + isc__mem_free(ctx, ptr FLARG_PASS); + return; + } + #if ISC_MEM_USE_INTERNAL_MALLOC MCTXLOCK(ctx, &ctx->lock); mem_putunlocked(ctx, ptr, size); @@ -1249,6 +1288,8 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) { size_info *si; size += ALIGNMENT_SIZE; + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) + size += ALIGNMENT_SIZE; #if ISC_MEM_USE_INTERNAL_MALLOC si = mem_getunlocked(ctx, size); #else /* ISC_MEM_USE_INTERNAL_MALLOC */ @@ -1256,6 +1297,10 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) { #endif /* ISC_MEM_USE_INTERNAL_MALLOC */ if (si == NULL) return (NULL); + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { + si->u.ctx = ctx; + si++; + } si->u.size = size; return (&si[1]); } @@ -1263,6 +1308,7 @@ isc__mem_allocateunlocked(isc_mem_t *ctx, size_t size) { void * isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) { size_info *si; + isc_boolean_t call_water = ISC_FALSE; REQUIRE(VALID_CONTEXT(ctx)); @@ -1279,9 +1325,23 @@ isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) { #if ISC_MEM_TRACKLINES ADD_TRACE(ctx, si, si[-1].u.size, file, line); #endif - + if (ctx->hi_water != 0U && !ctx->hi_called && + ctx->inuse > ctx->hi_water) { + ctx->hi_called = ISC_TRUE; + call_water = ISC_TRUE; + } + if (ctx->inuse > ctx->maxinuse) { + ctx->maxinuse = ctx->inuse; + if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water && + (isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0) + fprintf(stderr, "maxinuse = %lu\n", + (unsigned long)ctx->inuse); + } MCTXUNLOCK(ctx, &ctx->lock); + if (call_water) + (ctx->water)(ctx->water_arg, ISC_MEM_HIWATER); + return (si); } @@ -1289,12 +1349,19 @@ void isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) { size_info *si; size_t size; + isc_boolean_t call_water= ISC_FALSE; REQUIRE(VALID_CONTEXT(ctx)); REQUIRE(ptr != NULL); - si = &(((size_info *)ptr)[-1]); - size = si->u.size; + if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) { + si = &(((size_info *)ptr)[-2]); + REQUIRE(si->u.ctx == ctx); + size = si[1].u.size; + } else { + si = &(((size_info *)ptr)[-1]); + size = si->u.size; + } #if ISC_MEM_USE_INTERNAL_MALLOC MCTXLOCK(ctx, &ctx->lock); @@ -1307,7 +1374,22 @@ isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) { DELETE_TRACE(ctx, ptr, size, file, line); + /* + * The check against ctx->lo_water == 0 is for the condition + * when the context was pushed over hi_water but then had + * isc_mem_setwater() called with 0 for hi_water and lo_water. + */ + if (ctx->hi_called && + (ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) { + ctx->hi_called = ISC_FALSE; + + if (ctx->water != NULL) + call_water = ISC_TRUE; + } MCTXUNLOCK(ctx, &ctx->lock); + + if (call_water) + (ctx->water)(ctx->water_arg, ISC_MEM_LOWATER); }