Steve Hay wrote:

we are talking about segfault in filter/both_str_con_add on win32.

The modperl_output_filter_handler in code goes:

    if (((modperl_filter_ctx_t *)f->ctx)->sent_eos) {
        MP_TRACE_f(MP_FUNC,
                   MP_FILTER_NAME_FORMAT
                   "write_out: EOS was already sent, "
                   "passing through the brigade\n",
                   MP_FILTER_NAME(f));
        return ap_pass_brigade(f->next, bb);
    }
    else {
        filter = modperl_filter_new(f, bb, MP_OUTPUT_FILTER_MODE,
                                    0, 0, 0);
        status = modperl_run_filter(filter);
    }

So ((modperl_filter_ctx_t *)f->ctx) is non-NULL, when it checks for sent_eos, right? Otherwise it'll segfault right there. Then it goes through modperl_filter_new which simply stashes f into filter->f. When it comes back (modperl_filter_ctx_t *)filter->f->ctx) should be non-null as well. Is it?


I've put a breakpoint on line 763 (the modperl_filter_new() call) of modperl_filter.c, and I attach to the Apache process when the both_str_con_add.t test starts (I put a sleep 30; into it to give me time to catch it.)

When the debugger first stops on the breakpoint I have:

f = 0x008e23c8
f->ctx = 0x008e23c8
filter = 0x0000000c [garbage]

After the modperl_filter_new() call f and f->ctx are unchanged, but filter is now 0x033552b0 and it has a new filter->f member which is 0x008e23c8.

So far so good, and sure enough the modperl_run_filter() call goes OK: filter->f->ctx is 0x008e23b8, handler gets set to 0x008e23a0, and the function returns 14716076.

I then let the debugger continue and it soon stops again on the breakpoint. Initially the values are all as before:

f = 0x008e23c8
f->ctx = 0x008e23c8
filter = 0x0000000c [garbage]

But now after the modperl_filter_new() call only f is unchanged: f->ctx is changed to 0x00000000 this time, and filter to 0x008e1cb8 (with a filter->f member of 0x008e23c8).

So this time, of course, modperl_run_filter() fails when trying to set handler because filter->f->ctx is NULL.

I re-ran everything and this time stepped into modperl_filter_new() on the second call to it. It seems that the apr_pcalloc() call on line 228 of modperl_filter.c is what changes f->ctx from 0x008e23c8 to 0x00000000.

So did you look at the value of f->ctx before and after the apr_pcalloc() call on line 228 and that's when it has changed? are you sure that your compiler reports the line number correctly? Sometimes with an optimized code it may report wrong lines. e.g. I'd suggest to change:
modperl_filter_t *filter = apr_pcalloc(p, sizeof(*filter));


to:

modperl_filter_t *filter;
filter = apr_pcalloc(p, sizeof(*filter));

Does this help at all?

Certainly. It is possible that the memory pool is messed up. If you change apr_pcalloc with apr_palloc does it still happen (if it doesn't it will crash elsewhere, since that just proves that apr_pcalloc allocates the already allocated memory). the next step would be to enable apr_pool debug tracing :(


Does the problem persist if you apply this patch (and re-run t/TEST -conf)? Most likely it'll go away, but this is not the right solution, just a sanity check.

Index: t/filter/TestFilter/both_str_con_add.pm
===================================================================
RCS file: /home/cvs/modperl-2.0/t/filter/TestFilter/both_str_con_add.pm,v
retrieving revision 1.6
diff -u -r1.6 both_str_con_add.pm
--- t/filter/TestFilter/both_str_con_add.pm 11 May 2003 23:51:11 -0000 1.6
+++ t/filter/TestFilter/both_str_con_add.pm 18 Sep 2003 09:28:38 -0000
@@ -7,11 +7,12 @@
use warnings FATAL => 'all';


 use Apache::Connection ();
-use Apache::Filter ();
 use APR::Bucket ();
 use APR::Brigade ();
 use APR::Util ();

+use base qw(Apache::Filter);
+
 use APR::Const -compile => qw(SUCCESS EOF);
 use Apache::Const -compile => qw(OK MODE_GETLINE);

@@ -20,12 +21,12 @@
 sub pre_connection {
     my Apache::Connection $c = shift;

-    $c->add_input_filter(\&in_filter);
-    $c->add_output_filter(\&out_filter);
+#    $c->add_input_filter(\&in_filter);
+#    $c->add_output_filter(\&out_filter);

     return Apache::OK;
 }
-sub in_filter {
+sub in_filter : FilterConnectionHandler {
     my $filter = shift;

     while ($filter->read(my $buffer, 1024)) {
@@ -38,7 +39,7 @@
     Apache::OK;
 }

-sub out_filter {
+sub out_filter : FilterConnectionHandler {
     my $filter = shift;

     while ($filter->read(my $buffer, 1024)) {
@@ -81,6 +82,8 @@
   <VirtualHost TestFilter::both_str_con_add>
       PerlModule                   TestFilter::both_str_con_add
       PerlPreConnectionHandler     TestFilter::both_str_con_add::pre_connection
+      PerlInputFilterHandler       TestFilter::both_str_con_add::in_filter
+      PerlOutputFilterHandler      TestFilter::both_str_con_add::out_filter
       PerlProcessConnectionHandler TestFilter::both_str_con_add
   </VirtualHost>
 </NoAutoConfig>



__________________________________________________________________
Stas Bekman            JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/     mod_perl Guide ---> http://perl.apache.org
mailto:[EMAIL PROTECTED] http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org   http://ticketmaster.com


--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to