Closer still:
- perl t/TEST t/api/lookup_uri t/api/rflush t/apr/pool t/filter/both_str_con_add
fails
- perl t/TEST t/api/lookup_uri t/api/rflush t/filter/both_str_con_add passes
- perl t/TEST t/api/lookup_uri t/apr/pool t/filter/both_str_con_add fails
- perl t/TEST t/api/rflush t/apr/pool t/filter/both_str_con_add passes
Concentrating on the shortest sequence that still fails (lookup_uri + pool + both_str_con_add), I find that the attached patch (which truncates the t/apr/pool tests from 13 to just 2) makes this test sequence succeed.
Most interestingly, if you move the "return Apache::OK;" that I've inserted into pool.pm down one more line, to just *after* the "$p->destroy();", then the test sequence fails again.
Perhaps there is a problem with APR::Pool->destroy()?
More tidbits that might help someone sort this out:
1. If I further hack pool.pm to remove all reference to $subp, i.e. delete these lines:
my $subp = $p->new;
ok $subp->isa('APR::Pool');
$subp->cleanup_register(\&set_cleanup, [$r, 'child']);(so now there is only 1 test left!) then it works *with* the $p->destroy() call left in. That call is commented "# should destroy the subpool too"; it seems that it destroys more than just the subpool ;-)
2. Having the ability to make the failing test sequence work allows me to compare what's going on in modperl_filter_new() in a run that fails with a run that works. Here's what I find:
On the failed run (with the destroy() call) I have these values before and after the apr_pcalloc() call:
VARIABLE BEFORE AFTER
f 0x008e23c8 unchanged f->ctx 0x008e23b8 NULL f->r NULL unchanged - still NULL f->c 0x008e1db8 NULL f->c->pool 0x008e1cb8 N/A since f->c is NULL
filter 0x01d175dc 0x008e1cb8 (*) filter->f 0x34302e00 NULL filter->pool 0x016e484c NULL
p 0x008e1cb8 unchanged
The interesting thing there is marked (*): It seems that what apr_pcalloc() has returned (which gets assigned to filter) is the address held in p -- i.e. the address that was passed into it. I would (naively) expect apr_pcalloc() to have zeroed the memory at the address that it returns, and, indeed, everything "under" filter is NULL or 0. However, p came from f->c->pool, so zeroing that could potentially affect things "under" f, and sure enough f->ctx and f->c do get changed to NULL (causing the crash).
By contrast, on the successful run (without the destroy() call) I have this:
VARIABLE BEFORE AFTER
f 0x008e23c8 unchanged f->ctx 0x008e23b8 unchanged f->r NULL unchanged f->c 0x008e1db8 unchanged f->c->pool 0x008e1cb8 unchanged
filter 0x01f0f704 0x033692e8 (*) filter->f 0x34302e00 NULL filter->pool 0xffffffff NULL
p 0x008e1cb8 unchanged
This time, the return value from apr_pcalloc(), assigned to filter, is an address that we haven't seen before. Again, everything "under" filter is NULL or 0, but this time nothing "under" f has been changed at all.
It looks like the problem is not so much that f->ctx et al gets zeroed, as that apr_pcalloc() returns something "under" f (namely, f->c->pool) as the zeroed memory, rather than a "new" area of memory. The fact that f->ctx et al gets zeroed is just a consequence of that.
Was it at all relevant that on the successful run filter->pool was 0xffffffff to start with? That value wouldn't normally just crop up by accident!
- Steve
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
