You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@apr.apache.org by Joshua Moore-Oliva <jo...@chatgris.com> on 2003/07/10 23:45:45 UTC
Bug Report -- sorry if duplicate my first attempt at sending my email was not working.
Currently in apr_pool_destroy there is this chunk of code
while (pool->child)
apr_pool_destroy(pool->child);
run_cleanups(&pool->cleanups);
The problem here is if I created a subpool for temporary scratch space, then
registered that subpool as a cleanup the pool will be cleaned up in the first
chunk of code.
while (pool->child)
apr_pool_destroy(pool->child);
THEN will be run again with
run_cleanups(&pool->cleanups);
causing a segmentation fault.
This code here Fixed the problem by running the cleanups first then destroying
the subpools.
run_cleanups(&pool->cleanups);
while (pool->child)
apr_pool_destroy(pool->child);
Sample pseudo//simplified code that causes the problem is below for further
clarification.
apr_status_t file_field_clean( t ) {
apr_pool_destroy( t->read_pool );
apr_pool_destroy( t->write_pool );
free(t);
return APR_SUCCESS;
}
struct ffm_t file_field_init( apr_pool_t * pool ) {
struct ffm_t * t;
t = malloc( sizeof( struct ffm_t ) );
if ( apr_pool_create( &(t->read_pool), pool ) != APR_SUCCESS ) {
return NULL;
}
if ( apr_pool_create( &(t->write_pool), pool ) != APR_SUCCESS ) {
return NULL;
}
apr_pool_cleanup_register( pool, t, file_field_clean, file_field_clean );
return t;
}
Re: Bug Report -- sorry if duplicate my first attempt at sending my email was not working.
Posted by Joshua Moore-Oliva <jo...@chatgris.com>.
Yep, thanks and I should have clarified in my response that I wasn't sure
whether it was for earlier reasons or just a we've already set a spec.
Josh.
On July 10, 2003 06:26 pm, Cliff Woolley wrote:
> On Thu, 10 Jul 2003, Joshua Moore-Oliva wrote:
> > Regardless of it's usefulness, it is something that people can do. I do
> > not see any performance penalty by running the cleanups before clearing
> > the subpools, and it eliminates a possible segmentation fault.
>
> Actually it would cause a lot more segfaults if you changed it. The
> reason I asked you to just take my word for it before is that these
> cleanup problems are horrendously complicated and intertwined and hard to
> explain, not because I was trying to say "we've already decided it and you
> have no input."
>
> Here's one example: Let's say you have an object a in pool p and a
> childpool q that has an object b (which refers to object a) in it. If you
> destroy a before you cleanup pool q, then the cleanup for b will run after
> things it depends on from object a are already destroyed.
>
> So the pool cleanup order is always LIFO... we always guarantee that when
> q's cleanups run, everything in p still exists. If that were not the
> case, then it would be very difficult to cleanup things in q.
>
> Does that help clarify?
>
> --Cliff
Re: Bug Report -- sorry if duplicate my first attempt at sending my
email was not working.
Posted by Cliff Woolley <jw...@virginia.edu>.
On Thu, 10 Jul 2003, Joshua Moore-Oliva wrote:
> Regardless of it's usefulness, it is something that people can do. I do not
> see any performance penalty by running the cleanups before clearing the
> subpools, and it eliminates a possible segmentation fault.
Actually it would cause a lot more segfaults if you changed it. The
reason I asked you to just take my word for it before is that these
cleanup problems are horrendously complicated and intertwined and hard to
explain, not because I was trying to say "we've already decided it and you
have no input."
Here's one example: Let's say you have an object a in pool p and a
childpool q that has an object b (which refers to object a) in it. If you
destroy a before you cleanup pool q, then the cleanup for b will run after
things it depends on from object a are already destroyed.
So the pool cleanup order is always LIFO... we always guarantee that when
q's cleanups run, everything in p still exists. If that were not the
case, then it would be very difficult to cleanup things in q.
Does that help clarify?
--Cliff
Re: Bug Report -- sorry if duplicate my first attempt at sending my email was not working.
Posted by Joshua Moore-Oliva <jo...@chatgris.com>.
<snip>
> All you have to do is get rid of those two apr_pool_destroy() lines and it
> will work fine. You can go ahead and free(t) in your cleanup function.
> Then when you cleanup "pool", read_pool and write_pool will be cleaned up
> and then t will be freed.
>
> The point is that you should never register a cleanup in a parent pool
> that calls apr_pool_destroy() on a child pool. It's already done
> implicitly.
I do understand that it is done implicitly. However, I do believe that this
small change should be done. So I shall state my case and be done with it.
(this is all IMHO, you guys have a great project )
Regardless of it's usefulness, it is something that people can do. I do not
see any performance penalty by running the cleanups before clearing the
subpools, and it eliminates a possible segmentation fault. Why leave
something in the code that can be a trip-up when there is no reason to
eliminate the possible bug in another persons program? (saying that the bug
is technically in the persons program, but why allow there to be a bug at
all? )
Anyways, I have changed my code to work with the current design.
Josh.
Re: Bug Report -- sorry if duplicate my first attempt at sending my
email was not working.
Posted by Cliff Woolley <jw...@virginia.edu>.
On Thu, 10 Jul 2003, Joshua Moore-Oliva wrote:
> This code here Fixed the problem by running the cleanups first then destroying
> the subpools.
>
> run_cleanups(&pool->cleanups);
>
> while (pool->child)
> apr_pool_destroy(pool->child);
-1 .. the order is correct as-is by design, I promise. :)
> Sample pseudo//simplified code that causes the problem is below for further
> clarification.
>
> apr_status_t file_field_clean( t ) {
> apr_pool_destroy( t->read_pool );
> apr_pool_destroy( t->write_pool );
> free(t);
>
> return APR_SUCCESS;
> }
All you have to do is get rid of those two apr_pool_destroy() lines and it
will work fine. You can go ahead and free(t) in your cleanup function.
Then when you cleanup "pool", read_pool and write_pool will be cleaned up
and then t will be freed.
The point is that you should never register a cleanup in a parent pool
that calls apr_pool_destroy() on a child pool. It's already done
implicitly.
--Cliff