apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From stri...@apache.org
Subject cvs commit: apr/memory/unix apr_pools.c
Date Thu, 24 Jan 2002 12:18:18 GMT
striker     02/01/24 04:18:18

  Modified:    .        configure.in
               memory/unix apr_pools.c
  Log:
  Introduce a new configure option: --enable-pool-debug
  This allows us to select the pools debug mode at configure
  time without messing about in source files.
  
  At the same time we switch to a flag system, so different
  debug features can be switched on or off. e.g.:
   --enable-pool-debug="verbose lifetime"
  
  Revision  Changes    Path
  1.400     +41 -0     apr/configure.in
  
  Index: configure.in
  ===================================================================
  RCS file: /home/cvs/apr/configure.in,v
  retrieving revision 1.399
  retrieving revision 1.400
  diff -u -r1.399 -r1.400
  --- configure.in	23 Jan 2002 06:10:30 -0000	1.399
  +++ configure.in	24 Jan 2002 12:18:18 -0000	1.400
  @@ -188,6 +188,47 @@
     fi
   )dnl
   
  +AC_ARG_ENABLE(pool-debug,
  +  [  --enable-pool-debug[[=yes|no|verbose|lifetime|owner|all]]    Turn on pools debugging],
  +  [ if test -z "$enableval"; then
  +        APR_ADDTO(CPPFLAGS, -DAPR_POOL_DEBUG=1)
  +    elif test ! "$enableval" = "no"; then
  +        apr_pool_debug=1
  +    
  +        for i in $enableval
  +        do
  +            flag=0
  +        
  +            case $i in
  +            yes)
  +                flag=1
  +                ;;
  +            verbose)
  +                flag=2
  +                ;;
  +            lifetime)
  +                flag=4
  +                ;;
  +            owner)
  +                flag=8
  +                ;;
  +            all)
  +                apr_pool_debug=15
  +                ;;
  +            *)
  +                ;;
  +            esac
  +
  +            if test $flag -gt 0; then
  +                apr_pool_debug=`expr '(' $apr_pool_debug - $apr_pool_debug % \
  +                    '(' $flag '*' 2 ')' ')' + $flag + $apr_pool_debug % $flag`
  +            fi
  +        done
  +      
  +        APR_ADDTO(CPPFLAGS, -DAPR_POOL_DEBUG=$apr_pool_debug)
  +    fi
  +  ])
  +
   dnl Electric Fence malloc checker.
   dnl --with-efence specifies the path to Electric Fence
   AC_ARG_WITH(efence, 
  
  
  
  1.142     +215 -155  apr/memory/unix/apr_pools.c
  
  Index: apr_pools.c
  ===================================================================
  RCS file: /home/cvs/apr/memory/unix/apr_pools.c,v
  retrieving revision 1.141
  retrieving revision 1.142
  diff -u -r1.141 -r1.142
  --- apr_pools.c	21 Jan 2002 18:28:52 -0000	1.141
  +++ apr_pools.c	24 Jan 2002 12:18:18 -0000	1.142
  @@ -70,6 +70,31 @@
   #include <stdlib.h>     /* for malloc, free and abort */
   #endif
   
  +#include <unistd.h>     /* for getpid */
  +
  +
  +/*
  + * Debug level
  + */
  +
  +#define APR_POOL_DEBUG_GENERAL  0x01
  +#define APR_POOL_DEBUG_VERBOSE  0x02
  +#define APR_POOL_DEBUG_LIFETIME 0x04
  +#define APR_POOL_DEBUG_OWNER    0x08
  +
  +/* When no level was specified, assume APR_POOL_DEBUG_GENERAL */ 
  +#if defined(APR_POOL_DEBUG) && (APR_POOL_DEBUG != 0) && (APR_POOL_DEBUG
- 0 == 0)
  +#undef APR_POOL_DEBUG
  +#define APR_POOL_DEBUG APR_POOL_DEBUG_GENERAL
  +#endif
  +
  +/* We don't have debug level 0, assume APR_POOL_DEBUG_GENERAL. */
  +#if APR_POOL_DEBUG == 0
  +#undef APR_POOL_DEBUG
  +#define APR_POOL_DEBUG APR_POOL_DEBUG_GENERAL
  +#endif
  + 
  + 
   /*
    * Magic numbers
    */
  @@ -98,7 +123,7 @@
   
   typedef struct cleanup_t cleanup_t;
   
  -#if !defined(APR_POOL_DEBUG)
  +#if !APR_POOL_DEBUG
   typedef struct allocator_t allocator_t;
   typedef struct node_t node_t;
   
  @@ -121,7 +146,7 @@
   #define SIZEOF_NODE_T       APR_ALIGN_DEFAULT(sizeof(node_t))
   #define SIZEOF_ALLOCATOR_T  APR_ALIGN_DEFAULT(sizeof(allocator_t))
   
  -#else /* !defined(APR_POOL_DEBUG) */
  +#else /* APR_POOL_DEBUG */
   
   typedef struct debug_node_t debug_node_t;
   
  @@ -134,7 +159,7 @@
   
   #define SIZEOF_DEBUG_NODE_T APR_ALIGN_DEFAULT(sizeof(debug_node_t))
   
  -#endif /* !defined(APR_POOL_DEBUG) */
  +#endif /* APR_POOL_DEBUG */
   
   /* The ref field in the apr_pool_t struct holds a
    * pointer to the pointer referencing this pool.
  @@ -153,13 +178,13 @@
       apr_hash_t           *user_data;
       const char           *tag;
   
  -#if !defined(APR_POOL_DEBUG)
  +#if !APR_POOL_DEBUG
       allocator_t          *allocator;
       node_t               *active;
       node_t               *self; /* The node containing the pool itself */
       char                 *self_first_avail;
   
  -#else /* !defined(APR_POOL_DEBUG) */
  +#else /* APR_POOL_DEBUG */
       debug_node_t         *nodes;
       const char           *file_line;
       apr_uint32_t          creation_flags;
  @@ -167,9 +192,10 @@
       unsigned int          stat_total_alloc;
       unsigned int          stat_clear;
   #if APR_HAS_THREADS
  -    apr_thread_mutex_t *mutex;
  -#endif
  -#endif /* !defined(APR_POOL_DEBUG) */
  +    apr_os_thread_t       owner;
  +    apr_thread_mutex_t   *mutex;
  +#endif /* APR_HAS_THREADS */
  +#endif /* APR_POOL_DEBUG */
   };
   
   #define SIZEOF_POOL_T       APR_ALIGN_DEFAULT(sizeof(apr_pool_t))
  @@ -182,7 +208,7 @@
   static apr_byte_t   apr_pools_initialized = 0;
   static apr_pool_t  *global_pool = NULL;
   
  -#if !defined(APR_POOL_DEBUG)
  +#if !APR_POOL_DEBUG
   static allocator_t  global_allocator = { 
       0,          /* max_index */
   #if APR_HAS_THREADS
  @@ -191,9 +217,9 @@
       NULL,       /* owner */
       { NULL }    /* free[0] */
   };
  -#endif /* !defined(APR_POOL_DEBUG) */
  +#endif /* !APR_POOL_DEBUG */
   
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)
   static apr_file_t *file_stderr = NULL;
   #endif
   
  @@ -206,7 +232,7 @@
   static void free_proc_chain(struct process_chain *procs);
   
   
  -#if !defined(APR_POOL_DEBUG)
  +#if !APR_POOL_DEBUG
   /*
    * Initialization
    */
  @@ -850,73 +876,69 @@
   }
   
   
  -#else /* !defined(APR_POOL_DEBUG) */
  +#else /* APR_POOL_DEBUG */
   /*
  - * Initialization (debug)
  + * Debug helper functions
    */
   
  -APR_DECLARE(apr_status_t) apr_pool_initialize(void)
  +static void apr_pool_log_event(apr_pool_t *pool, const char *event,
  +                               const char *file_line, int deref)
   {
  -    apr_status_t rv;
  -
  -    if (apr_pools_initialized++)
  -        return APR_SUCCESS;
  -    
  -    /* Since the debug code works a bit differently then the
  -     * regular pools code, we ask for a lock here.  The regular
  -     * pools code has got this lock embedded in the global
  -     * allocator, a concept unknown to debug mode.
  -     */
  -    if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL, 
  -                  APR_POOL_FNEW_ALLOCATOR|APR_POOL_FLOCK)) != APR_SUCCESS) {
  -        return rv;
  -    }
  -
  -    apr_pool_tag(global_pool, "APR global pool");
  -
  -    apr_pools_initialized = 1;
  -
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  -    apr_file_open_stderr(&file_stderr, global_pool);
  +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)
       if (file_stderr) {
  -        apr_file_printf(file_stderr,
  -            "POOL DEBUG: ACTION  [SIZE      /POOL SIZE /TOTAL SIZE] "
  -            "POOL       TAG [__FILE__:__LINE__] (ALLOCS/TOTAL ALLOCS/CLEARS)\n");
  -            
  -        apr_file_printf(file_stderr,
  -            "POOL DEBUG: GLOBAL                                     "
  -            "0x%08X \"%s\"\n",
  -            (unsigned int)global_pool, global_pool->tag); 
  -    }
  +        if (deref) {
  +            apr_file_printf(file_stderr,
  +                "POOL DEBUG: "
  +                "[%lu"
  +#if APR_HAS_THREADS
  +                "/%lu"
   #endif
  -    
  -    return APR_SUCCESS;
  -}
  -
  -APR_DECLARE(void) apr_pool_terminate(void)
  -{
  -    if (!apr_pools_initialized)
  -        return;
  -
  -    apr_pools_initialized = 0;
  -    
  -    apr_pool_destroy(global_pool); /* This will also destroy the mutex */
  -    global_pool = NULL;
  -
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  -    file_stderr = NULL;
  +                "] "
  +                "%7s "
  +                "(%10lu/%10lu/%10lu) "
  +                "0x%08X \"%s\" "
  +                "<%s> "
  +                "(%u/%u/%u) "
  +                "\n",
  +                (unsigned long)getpid(),
  +#if APR_HAS_THREADS
  +                (unsigned long)apr_os_thread_current(),
  +#endif
  +                event,
  +                (unsigned long)apr_pool_num_bytes(pool, 0),
  +                (unsigned long)apr_pool_num_bytes(pool, 1),
  +                (unsigned long)apr_pool_num_bytes(global_pool, 1),
  +                (unsigned int)pool, pool->tag,
  +                file_line,
  +                pool->stat_alloc, pool->stat_total_alloc, pool->stat_clear);
  +        }
  +        else {
  +            apr_file_printf(file_stderr,
  +                "POOL DEBUG: "
  +                "[%lu"
  +#if APR_HAS_THREADS
  +                "/%lu"
   #endif
  +                "] "
  +                "%7s "
  +                "                                   "
  +                "0x%08X "
  +                "<%s> "
  +                "\n",
  +                (unsigned long)getpid(),
  +#if APR_HAS_THREADS
  +                (unsigned long)apr_os_thread_current(),
  +#endif
  +                event,
  +                (unsigned int)pool,
  +                file_line);
  +        }
  +    }
  +#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */
   }
   
  -/*
  - * Integrity checking
  - * This basically checks to see if the pool being used is still
  - * a relative to the global pool.  If not it was previously
  - * destroyed, in which case we abort().
  - */
  -
   #if APR_HAS_THREADS
  -static int pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent,
  +static int apr_pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent,
                               apr_thread_mutex_t *mutex)
   {
       apr_pool_t *child;
  @@ -930,7 +952,7 @@
       child = parent->child;
   
       while (child) {
  -        if (pool == child || pool_is_child_of(pool, child, parent->mutex)) {
  +        if (pool == child || apr_pool_is_child_of(pool, child, parent->mutex)) {
               if (parent->mutex && parent->mutex != mutex)
                   apr_thread_mutex_unlock(parent->mutex);
   
  @@ -946,8 +968,9 @@
       return 0;
   }
   
  -#else
  -static int pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent)
  +#else /* !APR_HAS_THREADS */
  +static int apr_pool_is_child_of(apr_pool_t *pool, apr_pool_t *parent,
  +                            void *dummy)
   {
       apr_pool_t *child;
   
  @@ -966,32 +989,103 @@
   
       return 0;
   }
  -#endif
  +#endif /* !APR_HAS_THREADS */
   
  -static void check_integrity(apr_pool_t *pool)
  +static void apr_pool_check_integrity(apr_pool_t *pool)
   {
  +    /* Rule of thumb: use of the global pool is always
  +     * ok, since the only user this apr_pools.c.  Unless
  +     * people have searched for the top level parent and
  +     * started to use that...
  +     */
       if (pool == global_pool || global_pool == NULL)
           return;
   
  -#if APR_HAS_THREADS    
  -    if (!pool_is_child_of(pool, global_pool, NULL))
  -#else
  -    if (!pool_is_child_of(pool, global_pool))
  -#endif
  -    {
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  -        if (file_stderr) {
  -            apr_file_printf(file_stderr,
  -                "POOL DEBUG: INVALID                                     "
  -                "0x%08X, abort().\n", 
  -                (unsigned int)pool);
  -        }
  -#endif         
  +    /* Lifetime
  +     * This basically checks to see if the pool being used is still
  +     * a relative to the global pool.  If not it was previously
  +     * destroyed, in which case we abort().
  +     */
  +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME)
  +    if (!apr_pool_is_child_of(pool, global_pool, NULL)) {
  +        apr_pool_log_event(pool, "LIFE", 
  +                           __FILE__ ":apr_pool_integrity check", 0);
  +
  +        abort();
  +    }
  +#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_LIFETIME) */
   
  +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER)
  +#if APR_HAS_THREADS
  +    if (!apr_os_thread_equal(pool->owner, apr_os_thread_current())) {
  +        apr_pool_log_event(pool, "THREAD",
  +                           __FILE__ ":apr_pool_integrity check", 0);
           abort();
       }
  +#endif /* APR_HAS_THREADS */
  +#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_OWNER) */
   }
   
  +
  +/*
  + * Initialization (debug)
  + */
  +
  +APR_DECLARE(apr_status_t) apr_pool_initialize(void)
  +{
  +    apr_status_t rv;
  +
  +    if (apr_pools_initialized++)
  +        return APR_SUCCESS;
  +    
  +    /* Since the debug code works a bit differently then the
  +     * regular pools code, we ask for a lock here.  The regular
  +     * pools code has got this lock embedded in the global
  +     * allocator, a concept unknown to debug mode.
  +     */
  +    if ((rv = apr_pool_create_ex(&global_pool, NULL, NULL, 
  +                  APR_POOL_FNEW_ALLOCATOR|APR_POOL_FLOCK)) != APR_SUCCESS) {
  +        return rv;
  +    }
  +
  +    apr_pool_tag(global_pool, "APR global pool");
  +
  +    apr_pools_initialized = 1;
  +
  +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)
  +    apr_file_open_stderr(&file_stderr, global_pool);
  +    if (file_stderr) {
  +        apr_file_printf(file_stderr,
  +            "POOL DEBUG: [PID"
  +#if APR_HAS_THREADS
  +            "/TID"
  +#endif
  +            "] ACTION  (SIZE      /POOL SIZE /TOTAL SIZE) "
  +            "POOL       \"TAG\" <__FILE__:__LINE__> (ALLOCS/TOTAL ALLOCS/CLEARS)\n");
  +
  +        apr_pool_log_event(global_pool, "GLOBAL", __FILE__ ":apr_pool_initialize", 0);
       
  +    }
  +#endif /* (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE) */
  +    
  +    return APR_SUCCESS;
  +}
  +
  +APR_DECLARE(void) apr_pool_terminate(void)
  +{
  +    if (!apr_pools_initialized)
  +        return;
  +
  +    apr_pools_initialized = 0;
  +    
  +    apr_pool_destroy(global_pool); /* This will also destroy the mutex */
  +    global_pool = NULL;
  +
  +#if (APR_POOL_DEBUG & APR_POOL_DEBUG_VERBOSE)
  +    file_stderr = NULL;
  +#endif
  +}
  +
  +
   /*
    * Memory allocation (debug)
    */
  @@ -1001,7 +1095,7 @@
       debug_node_t *node;
       void *mem;
   
  -    check_integrity(pool);
  +    apr_pool_check_integrity(pool);
       
       if ((mem = malloc(size)) == NULL) {
           if (pool->abort_fn)
  @@ -1019,6 +1113,8 @@
               return NULL;
           }
   
  +        memset(node, 0, SIZEOF_DEBUG_NODE_T);
  +
           node->next = pool->nodes;
           pool->nodes = node;
           node->index = 0;
  @@ -1038,7 +1134,7 @@
   {
       void *mem;
   
  -    check_integrity(pool);
  +    apr_pool_check_integrity(pool);
       
       mem = apr_palloc(pool, size);
       memset(mem, 0, size);
  @@ -1090,23 +1186,8 @@
   APR_DECLARE(void) apr_pool_clear_debug(apr_pool_t *pool, 
                                          const char *file_line)
   {
  -    check_integrity(pool);
  -    
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  -    if (file_stderr) {
  -        apr_file_printf(file_stderr,
  -            "POOL DEBUG: CLEAR   [%10lu/%10lu/%10lu] "
  -            "0x%08X \"%s\" [%s] (%u/%u/%u) "
  -            "parent=0x%08X\n",
  -            (unsigned long)apr_pool_num_bytes(pool, 0),
  -            (unsigned long)apr_pool_num_bytes(pool, 1),
  -            (unsigned long)apr_pool_num_bytes(global_pool, 1),
  -            (unsigned int)pool, pool->tag,
  -            file_line,
  -            pool->stat_alloc, pool->stat_total_alloc, pool->stat_clear,
  -            (unsigned int)pool->parent);
  -    }
  -#endif
  +    apr_pool_check_integrity(pool);
  +    apr_pool_log_event(pool, "CLEAR", file_line, 1);
   
       pool_clear_debug(pool, file_line);
   }
  @@ -1114,24 +1195,9 @@
   APR_DECLARE(void) apr_pool_destroy_debug(apr_pool_t *pool, 
                                            const char *file_line)
   {
  -    check_integrity(pool);
  +    apr_pool_check_integrity(pool);
  +    apr_pool_log_event(pool, "DESTROY", file_line, 1);
       
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  -    if (file_stderr) {
  -        apr_file_printf(file_stderr,
  -            "POOL DEBUG: DESTROY [%10lu/%10lu/%10lu] "
  -            "0x%08X \"%s\" [%s] (%u/%u/%u) "
  -            "parent=0x%08X\n",
  -            (unsigned long)apr_pool_num_bytes(pool, 0),
  -            (unsigned long)apr_pool_num_bytes(pool, 1),
  -            (unsigned long)apr_pool_num_bytes(global_pool, 1),
  -            (unsigned int)pool, pool->tag,
  -            file_line,
  -            pool->stat_alloc, pool->stat_total_alloc, pool->stat_clear,
  -            (unsigned int)pool->parent);
  -    }
  -#endif
  -
       pool_clear_debug(pool, file_line);
   
       /* Remove the pool from the parents child list */
  @@ -1166,10 +1232,12 @@
   
       *newpool = NULL;
   
  -    if (!parent)
  +    if (!parent) {
           parent = global_pool;
  -    else
  -       check_integrity(parent);
  +    }
  +    else {
  +       apr_pool_check_integrity(parent);
  +    }
   
       if (!abort_fn && parent)
           abort_fn = parent->abort_fn;
  @@ -1209,6 +1277,10 @@
           pool->ref = NULL;
       }
   
  +#if APR_HAS_THREADS
  +    pool->owner = apr_os_thread_current();
  +#endif
  +
       if ((flags & APR_POOL_FNEW_ALLOCATOR) == APR_POOL_FNEW_ALLOCATOR) {
   #if APR_HAS_THREADS
           apr_status_t rv;
  @@ -1237,20 +1309,7 @@
   
       *newpool = pool;
   
  -#if defined(APR_POOL_DEBUG_VERBOSE)
  -    if (file_stderr) {
  -        apr_file_printf(file_stderr,
  -            "POOL DEBUG: CREATE  [%10lu/%10lu/%10lu] "
  -            "0x%08X \"%s\" [%s] flags=0x%X, parent=0x%08X \"%s\"\n",
  -            (unsigned long)0,
  -            (unsigned long)0,
  -            (unsigned long)apr_pool_num_bytes(global_pool, 1),
  -            (unsigned int)pool, pool->tag, 
  -            file_line,
  -            flags,
  -            (unsigned int)parent, parent ? parent->tag : "<null>");
  -    }
  -#endif
  +    apr_pool_log_event(pool, "CREATE", file_line, 1);
   
       return APR_SUCCESS;
   }
  @@ -1327,7 +1386,7 @@
       struct psprintf_data ps;
       debug_node_t *node;
   
  -    check_integrity(pool);
  +    apr_pool_check_integrity(pool);
       
       ps.size = 64;
       ps.mem = malloc(ps.size);
  @@ -1495,7 +1554,8 @@
   APR_DECLARE(void) apr_pool_lock(apr_pool_t *pool, int flag)
   {
   }
  -#endif /* !defined(APR_POOL_DEBUG) */
  +
  +#endif /* !APR_POOL_DEBUG */
   
   
   /*
  @@ -1565,8 +1625,8 @@
                                                   apr_status_t (*cleanup) (void *),
                                                   apr_pool_t *pool)
   {
  -#if defined(APR_POOL_DEBUG)
  -    check_integrity(pool);
  +#if APR_POOL_DEBUG
  +    apr_pool_check_integrity(pool);
   #endif
       
       if (pool->user_data == NULL)
  @@ -1590,8 +1650,8 @@
                                                    apr_status_t (*cleanup) (void *),
                                                    apr_pool_t *pool)
   {
  -#if defined(APR_POOL_DEBUG)
  -    check_integrity(pool);
  +#if APR_POOL_DEBUG
  +    apr_pool_check_integrity(pool);
   #endif
       
       if (pool->user_data == NULL)
  @@ -1607,8 +1667,8 @@
   
   APR_DECLARE(apr_status_t) apr_pool_userdata_get(void **data, const char *key, apr_pool_t
*pool)
   {
  -#if defined(APR_POOL_DEBUG)
  -    check_integrity(pool);
  +#if APR_POOL_DEBUG
  +    apr_pool_check_integrity(pool);
   #endif
       
       if (pool->user_data == NULL)
  @@ -1637,8 +1697,8 @@
   {
       cleanup_t *c;
       
  -#if defined(APR_POOL_DEBUG)
  -    check_integrity(p);
  +#if APR_POOL_DEBUG
  +    apr_pool_check_integrity(p);
   #endif
       
       if (p != NULL) {
  @@ -1656,8 +1716,8 @@
   {
       cleanup_t *c, **lastp;
   
  -#if defined(APR_POOL_DEBUG)
  -    check_integrity(p);
  +#if APR_POOL_DEBUG
  +    apr_pool_check_integrity(p);
   #endif
      
       if (p == NULL)
  @@ -1682,8 +1742,8 @@
   {
       cleanup_t *c;
   
  -#if defined(APR_POOL_DEBUG)
  -    check_integrity(p);
  +#if APR_POOL_DEBUG
  +    apr_pool_check_integrity(p);
   #endif
   
       if (p == NULL)
  
  
  

Mime
View raw message