Bojan Smojver
Thu, 17 Jul 2008 21:02:57 -0700
On Fri, 2008-07-18 at 11:20 +1000, Bojan Smojver wrote: > The attached program crashes (double free) with or without that > change. He, he... It's always good to go through code again. There was a bug in the test program that caused it to crash. The attached program runs fine with pre cleanup and regular cleanup. Apologies for barking up the wrong tree and wasting everyone's time :-( -- Bojan
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <apr.h>
#include <apr_pools.h>
#include <apr_strings.h>
#include <apr_reslist.h>
struct res{
apr_pool_t *p;
char *r;
};
struct sub{
struct res *r; /* parent resource */
char *s;
};
static apr_status_t res_clean(void *data){
struct res *r=data;
free(r->r);
r->r=NULL;
return APR_SUCCESS;
}
static apr_status_t sub_clean(void *data){
struct sub *s=data;
/* use parent resource a bit */
printf("%s\n",s->r->r);
free(s->s);
s->s=NULL;
return APR_SUCCESS;
}
static apr_status_t con(void **res,void *parm,apr_pool_t *pool){
apr_pool_t *rpool,*spool;
struct res **r=(struct res **)res;
struct sub *s;
apr_pool_create(&rpool,pool);
*r=apr_pcalloc(rpool,sizeof(**r));
(*r)->p=rpool;
(*r)->r=malloc(5);
memcpy((*r)->r,"data",5);
apr_pool_cleanup_register(rpool,*r,res_clean,apr_pool_cleanup_null);
apr_pool_create(&spool,rpool);
s=apr_pcalloc(spool,sizeof(*s));
s->r=*r;
s->s=malloc(5);
memcpy(s->s,"data",5);
apr_pool_cleanup_register(spool,s,sub_clean,apr_pool_cleanup_null);
return APR_SUCCESS;
}
static apr_status_t de(void *res,void *parm,apr_pool_t *pool){
struct res *r=res;
apr_pool_destroy(r->p);
return APR_SUCCESS;
}
int main(int argc,char **argv){
int i,j;
struct res *r[10];
apr_pool_t *pool;
apr_reslist_t *list;
apr_initialize();
apr_pool_create(&pool,NULL);
apr_reslist_create(&list,0,0,10,0,con,de,NULL,pool);
for(j=0;j<1000;j++){
for(i=0;i<10;i++)
apr_reslist_acquire(list,(void **)&r[i]);
for(i=0;i<10;i++)
apr_reslist_release(list,r[i]);
}
apr_terminate();
return 0;
}