]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
1885. [func] Additional memory debugging support to track size
authorMark Andrews <marka@isc.org>
Fri, 10 Jun 2005 07:00:20 +0000 (07:00 +0000)
committerMark Andrews <marka@isc.org>
Fri, 10 Jun 2005 07:00:20 +0000 (07:00 +0000)
                        and mctx arguements. [RT #14814]

CHANGES
bin/named/main.c
bin/tests/system/start.pl
lib/isc/include/isc/mem.h
lib/isc/mem.c

diff --git a/CHANGES b/CHANGES
index 8ce16735c16a0ecf5228ad3162a4c436e8a853c1..fc12d53a06212e186a22f3c0901b5146d2379550 100644 (file)
--- 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]
 
index f9a05128c9778b337af7b9f13582a85aa4395012..f40a8c6324d3ea0c73c00ed7b0ca349e90a2bf06 100644 (file)
@@ -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 }
 };
 
index 8e8bc82f963a604dc2ee4d3ac46fb7e230295ac0..785ca63ab6a6927a247b624ff1d36d4a0151d906 100644 (file)
@@ -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";
index e026082ba8c62d67b20fd365baabd45d5f816231..19acbd2eb0493df8151722e70b0b638136706489 100644 (file)
@@ -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().
  */
 /*@}*/
 
index f20bd51c60dee4e6385a58b2fa1cf910ab8df70e..f15f7317105085983f2173f27c2c032ec9e8a3c5 100644 (file)
@@ -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);
 }