Seems this should be tried straight into the allocator debugging, rather than separately configurable. Use-after-free is quite bad, so I think it should always die right away.
Your work on reporting unfreed items is a bit different, as some applications *may* choose to leave some allocations until the process exits. On Thu, Nov 5, 2015 at 1:40 AM, <i...@apache.org> wrote: > Author: ivan > Date: Thu Nov 5 07:40:58 2015 > New Revision: 1712718 > > URL: http://svn.apache.org/viewvc?rev=1712718&view=rev > Log: > Add another diagnostic macro SERF__DEBUG_USE_AFTER_FREE to detect usage of > bucket allocator after it destroyed by pool cleanup. > > * buckets/allocator.c > (SERF__DEBUG_USE_AFTER_FREE): New. Commented by default. > (allocator_cleanup): Set ALLOCATOR->POOL to NULL if > SERF__DEBUG_USE_AFTER_FREE is defined. > (serf_bucket_mem_alloc, serf_bucket_mem_free): Abort if ALLOCATOR->POOL > is NULL and SERF__DEBUG_USE_AFTER_FREE is defined. > > Modified: > serf/trunk/buckets/allocator.c > > Modified: serf/trunk/buckets/allocator.c > URL: > http://svn.apache.org/viewvc/serf/trunk/buckets/allocator.c?rev=1712718&r1=1712717&r2=1712718&view=diff > > ============================================================================== > --- serf/trunk/buckets/allocator.c (original) > +++ serf/trunk/buckets/allocator.c Thu Nov 5 07:40:58 2015 > @@ -35,6 +35,11 @@ > * unfreed blocks on pool cleanup. */ > /* #define SERF__DEBUG_UNFREED_MEMORY */ > > +/* Define SERF__DEBUG_USE_AFTER_FREE if you're interested to prevent > + * access bucket allocator after free. > + * TODO: Should we do this by default? */ > +/* #define SERF__DEBUG_USE_AFTER_FREE */ > + > typedef struct node_header_t { > apr_size_t size; > union { > @@ -151,6 +156,10 @@ static apr_status_t allocator_cleanup(vo > apr_allocator_destroy(allocator->allocator); > } > > +#ifdef SERF__DEBUG_USE_AFTER_FREE > + /* Set POOL to NULL to detect allocator usage after destroy. */ > + allocator->pool = NULL; > +#endif > return APR_SUCCESS; > } > > @@ -214,6 +223,14 @@ void *serf_bucket_mem_alloc( > node_header_t *node; > void *block; > > +#ifdef SERF__DEBUG_USE_AFTER_FREE > + if (allocator->pool == NULL) { > + /* Attempt to use bucket allocator after it destroyed by > + * pool cleanup. */ > + abort(); > + } > +#endif > + > ++allocator->num_alloc; > > size += SIZEOF_NODE_HEADER_T; > @@ -297,6 +314,13 @@ void serf_bucket_mem_free( > { > node_header_t *node; > > +#ifdef SERF__DEBUG_USE_AFTER_FREE > + if (allocator->pool == NULL) { > + /* Attempt to use bucket allocator after it destroyed by > + * pool cleanup. */ > + abort(); > + } > +#endif > --allocator->num_alloc; > > node = (node_header_t *)((char *)block - SIZEOF_NODE_HEADER_T); > > >