apr-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Cliff Woolley <jwool...@virginia.edu>
Subject [PATCH] bucket debugging.
Date Wed, 13 Aug 2003 03:20:13 GMT

Any objections to the following patch?  All you do is pass
-DAPR_BUCKET_DEBUG to ./configure and then several things happen:

  1) the brigades get checked for consistency at various strategic points
  2) and apr_bucket_free() calls are checked for double-free conditions
     (eg, you destroyed the same bucket twice, or destroyed one and then
     kept on using it, which causes all kinds of nasty and impossible to
     debug things to happen).

If you don't define APR_BUCKET_DEBUG, it's all a no-op and is thrown away
by the preprocessor.

--Cliff



Index: buckets/apr_brigade.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_brigade.c,v
retrieving revision 1.57
diff -u -d -r1.57 apr_brigade.c
--- buckets/apr_brigade.c	1 Jan 2003 00:02:17 -0000	1.57
+++ buckets/apr_brigade.c	13 Aug 2003 03:14:43 -0000
@@ -127,6 +127,10 @@
         APR_RING_UNSPLICE(e, f, link);
         APR_RING_SPLICE_HEAD(&a->list, e, f, apr_bucket, link);
     }
+
+    APR_BRIGADE_CHECK_CONSISTENCY(a);
+    APR_BRIGADE_CHECK_CONSISTENCY(b);
+
     return a;
 }

@@ -147,6 +151,8 @@
         *after_point = APR_BRIGADE_FIRST(b);
         return APR_SUCCESS;
     }
+
+    APR_BRIGADE_CHECK_CONSISTENCY(b);

     APR_BRIGADE_FOREACH(e, b) {
         if ((e->length == (apr_size_t)(-1)) && (point > (apr_size_t)(-1)))
{
Index: buckets/apr_buckets_alloc.c
===================================================================
RCS file: /home/cvs/apr-util/buckets/apr_buckets_alloc.c,v
retrieving revision 1.11
diff -u -d -r1.11 apr_buckets_alloc.c
--- buckets/apr_buckets_alloc.c	2 Jul 2003 06:35:59 -0000	1.11
+++ buckets/apr_buckets_alloc.c	13 Aug 2003 03:14:43 -0000
@@ -151,12 +151,33 @@
     return ((char *)node) + SIZEOF_NODE_HEADER_T;
 }

+#ifdef APR_BUCKET_DEBUG
+#include <assert.h>
+static int not_already_free(node_header_t *node)
+{
+    apr_bucket_alloc_t *list = node->alloc;
+    node_header_t *curr = list->freelist;
+
+    while (curr) {
+        if (node == curr) {
+            return 0;
+        }
+        curr = curr->next;
+    }
+    return 1;
+}
+#define CHECK_NOT_ALREADY_FREE(node) assert(not_already_free(node))
+#else
+#define CHECK_NOT_ALREADY_FREE(node)
+#endif
+
 APU_DECLARE_NONSTD(void) apr_bucket_free(void *mem)
 {
     node_header_t *node = (node_header_t *)((char *)mem - SIZEOF_NODE_HEADER_T);
     apr_bucket_alloc_t *list = node->alloc;

     if (node->size == SMALL_NODE_SIZE) {
+        CHECK_NOT_ALREADY_FREE(node);
         node->next = list->freelist;
         list->freelist = node;
     }
Index: include/apr_buckets.h
===================================================================
RCS file: /home/cvs/apr-util/include/apr_buckets.h,v
retrieving revision 1.152
diff -u -d -r1.152 apr_buckets.h
--- include/apr_buckets.h	2 Jul 2003 06:35:59 -0000	1.152
+++ include/apr_buckets.h	13 Aug 2003 03:14:43 -0000
@@ -315,6 +315,38 @@
  */
 typedef apr_status_t (*apr_brigade_flush)(apr_bucket_brigade *bb, void *ctx);

+/*
+ * define APR_BUCKET_DEBUG if you want your brigades to be checked for
+ * validity at every possible instant.  this will slow your code down
+ * substantially but is a very useful debugging tool.
+ */
+#ifdef APR_BUCKET_DEBUG
+#define APR_RING_DEBUG
+
+#define APR_BRIGADE_CHECK_CONSISTENCY(b)				\
+        APR_RING_CHECK_CONSISTENCY(&(b)->list, apr_bucket, link)
+
+#define APR_BUCKET_CHECK_CONSISTENCY(e)				\
+        APR_RING_CHECK_ELEM_CONSISTENCY((e), apr_bucket, link)
+
+#else
+/**
+ * checks the ring pointers in a bucket brigade for consistency.  an
+ * assertion failure will occur if any inconsistencies are found.
+ *   note: this is a no-op unless APR_BUCKET_DEBUG is defined.
+ * @param b The brigade
+ */
+#define APR_BRIGADE_CHECK_CONSISTENCY(b)
+/**
+ * checks the brigade a bucket is in for ring consistency.  an
+ * assertion failure will occur if any inconsistencies are found.
+ *   note: this is a no-op unless APR_BUCKET_DEBUG is defined.
+ * @param e The bucket
+ */
+#define APR_BUCKET_CHECK_CONSISTENCY(e)
+#endif
+
+
 /**
  * Wrappers around the RING macros to reduce the verbosity of the code
  * that handles bucket brigades.
@@ -405,6 +437,7 @@
 #define APR_BRIGADE_INSERT_HEAD(b, e) do {				\
 	apr_bucket *ap__b = (e);                                        \
 	APR_RING_INSERT_HEAD(&(b)->list, ap__b, apr_bucket, link);	\
+        APR_BRIGADE_CHECK_CONSISTENCY((b));				\
     } while (0)

 /**
@@ -415,6 +448,7 @@
 #define APR_BRIGADE_INSERT_TAIL(b, e) do {				\
 	apr_bucket *ap__b = (e);					\
 	APR_RING_INSERT_TAIL(&(b)->list, ap__b, apr_bucket, link);	\
+        APR_BRIGADE_CHECK_CONSISTENCY((b));				\
     } while (0)

 /**
@@ -422,16 +456,20 @@
  * @param a The first brigade
  * @param b The second brigade
  */
-#define APR_BRIGADE_CONCAT(a, b)					\
-	APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link)
+#define APR_BRIGADE_CONCAT(a, b) do {					\
+        APR_RING_CONCAT(&(a)->list, &(b)->list, apr_bucket, link);	\
+        APR_BRIGADE_CHECK_CONSISTENCY((a));				\
+    } while (0)

 /**
  * Prepend brigade b onto the beginning of brigade a, leaving brigade b empty
  * @param a The first brigade
  * @param b The second brigade
  */
-#define APR_BRIGADE_PREPEND(a, b)					\
-	APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link)
+#define APR_BRIGADE_PREPEND(a, b) do {					\
+        APR_RING_PREPEND(&(a)->list, &(b)->list, apr_bucket, link);	\
+        APR_BRIGADE_CHECK_CONSISTENCY((a));				\
+    } while (0)

 /**
  * Insert a list of buckets before a specified bucket
@@ -441,6 +479,7 @@
 #define APR_BUCKET_INSERT_BEFORE(a, b) do {				\
 	apr_bucket *ap__a = (a), *ap__b = (b);				\
 	APR_RING_INSERT_BEFORE(ap__a, ap__b, link);			\
+        APR_BUCKET_CHECK_CONSISTENCY(ap__a);				\
     } while (0)

 /**
@@ -451,6 +490,7 @@
 #define APR_BUCKET_INSERT_AFTER(a, b) do {				\
 	apr_bucket *ap__a = (a), *ap__b = (b);				\
 	APR_RING_INSERT_AFTER(ap__a, ap__b, link);			\
+        APR_BUCKET_CHECK_CONSISTENCY(ap__a);				\
     } while (0)

 /**

Mime
View raw message