You are viewing a plain text version of this content. The canonical link for it is here.
Posted to modperl@perl.apache.org by Alexander Bergolth <le...@strike.wu-wien.ac.at> on 2004/01/08 16:58:54 UTC
mod_perl2 (ModPerl::Registry) crashes httpd if request-object is
used in a subroutine
Hi!
I'm suffering from the following problem:
When I'm using the request-object in a subroutine without having passed
it to the sub as a parameter, the apache child processes die with a
segmentation fault when being reused. If httpd is started with prefork
and StartServers 8, the first 8 requests work but the 9th request kills
all 8 httpd child processes. (They are being restarted by the main http
process after that.) If httpd is started as "httpd -X" (single process),
the first request works and the second crashes the server.
An example script that I've be used to reproce the error on two machines
running Fedora Core 1 is added below.
I've tried
httpd-2.0.47-10
mod_perl-1.99_09-10
perl-5.8.1-92
apr-0.9.4-2
and
httpd-2.0.48-4
mod_perl-1.99_11-3
perl-5.8.2-7
apr-0.9.4-2
(from Fedora Development)
Unfortunately I couldn't get a useful stacktrace with those binary (and
-debuginfo) rpms.
---------- snipp! ----------
#!/usr/bin/perl
use strict;
my $r = shift;
$r->content_type("text/html");
$r->print( "<html>\n"
."<head><title>Testpage</title></head>\n"
."<body>\n" );
&printline1($r, "This works");
&printline2("This crashes the httpd process when it is reused");
$r->print( "</body>\n"
."</html>\n" );
sub printline1 {
my $r = shift;
$r->print($_[0]."<br>\n");
}
sub printline2 {
$r->print($_[0]."<br>\n");
}
1;
---------- snipp! ----------
Any hints?
Cheers,
--leo
--
-----------------------------------------------------------------------
Alexander (Leo) Bergolth leo@leo.wu-wien.ac.at
WU-Wien - Zentrum fuer Informatikdienste http://leo.wu-wien.ac.at
Computers are like air conditioners -
they stop working properly when you open Windows
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Stas Bekman <st...@stason.org>.
Perrin Harkins wrote:
> On Thu, 2004-01-08 at 16:34, Stas Bekman wrote:
>
>>But since we expect most modules to run under any MPM, it usually applies to
>>any code.
>
>
> Any code that you plan to release on CPAN, that is. It's still okay in
> internal code when you know you won't be running threaded MPMs.
You are correct, Perrin.
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Perrin Harkins <pe...@elem.com>.
On Thu, 2004-01-08 at 16:34, Stas Bekman wrote:
> But since we expect most modules to run under any MPM, it usually applies to
> any code.
Any code that you plan to release on CPAN, that is. It's still okay in
internal code when you know you won't be running threaded MPMs.
- Perrin
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Stas Bekman <st...@stason.org>.
Perrin Harkins wrote:
[...]
>>Moreover I've read that Apache->request should be avoided in mod_perl2:
>>http://perl.apache.org/docs/2.0/user/porting/compat.html#C_Apache_E_gt_request_
>
>
> That only applies to threaded MPMs, and modules you release that others
> might want to run under threaded MPMs.
But since we expect most modules to run under any MPM, it usually applies to
any code.
I doubt one ever needs to use Apache->request. CGI.pm now accepts $r as an
argument to CGI->new() and if you need to access $r from elsewhere in your
code a Singleton should be used.
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Alexander Bergolth <le...@strike.wu-wien.ac.at>.
On 01/08/2004 10:14 PM, Perrin Harkins wrote:
> On Thu, 2004-01-08 at 15:43, Alexander Bergolth wrote:
>
>>Why do I create a closure? If i'd create a closure I would have to store
>>a reference to an _anonymous sub
>
> No, that's a common misconception. Closures and anonymous subs are two
> totally separate things, although they can be used together. See the
> explanation here:
> http://perl.apache.org/docs/general/perl_reference/perl_reference.html#Understanding_Closures____the_Easy_Way
Thanks for the explanation!
--leo
--
-----------------------------------------------------------------------
Alexander (Leo) Bergolth leo@leo.wu-wien.ac.at
WU-Wien - Zentrum fuer Informatikdienste http://leo.wu-wien.ac.at
Computers are like air conditioners -
they stop working properly when you open Windows
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Perrin Harkins <pe...@elem.com>.
On Thu, 2004-01-08 at 15:43, Alexander Bergolth wrote:
> Why do I create a closure? If i'd create a closure I would have to store
> a reference to an _anonymous sub
No, that's a common misconception. Closures and anonymous subs are two
totally separate things, although they can be used together. See the
explanation here:
http://perl.apache.org/docs/general/perl_reference/perl_reference.html#Understanding_Closures____the_Easy_Way
There is more discussion in the list archives.
> My version uses a regular (named-) sub and the scope of the variable $r
> should be lexically local to the enclosing block.
And it is, but your sub creates a closure so that when $r changes in the
enclosing block that is not seen in your sub. The simplest solution is
to pass $r every time.
> Moreover I've read that Apache->request should be avoided in mod_perl2:
> http://perl.apache.org/docs/2.0/user/porting/compat.html#C_Apache_E_gt_request_
That only applies to threaded MPMs, and modules you release that others
might want to run under threaded MPMs.
- Perrin
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Alexander Bergolth <le...@strike.wu-wien.ac.at>.
On 01/08/04 19:15, Perrin Harkins wrote:
> Alexander Bergolth wrote:
>
>> When I'm using the request-object in a subroutine without having passed
>> it to the sub as a parameter, the apache child processes die with a
>> segmentation fault when being reused.
>
> Well, it probably shouldn't segfault, but you can't do that. You are
> creating a closure which will permanently keep a copy of the very first
> $r that existed in that process, but $r is really an apache structure
> that gets freed after each request. If you need a copy of $r but don't
> want to pass it, and you are running in pre-fork MPM, you can use the
> Apache->request() call.
Why do I create a closure? If i'd create a closure I would have to store
a reference to an _anonymous sub, something like that:
---------- snipp! ----------
my $r = shift;
my $printline3 = sub {
$r->print($_[0]."<br>\n");
}
&$printline3("Uses frozen request variable.");
---------- snipp! ----------
( See http://www.perldoc.com/perl5.6/pod/perlref.html#4. )
My version uses a regular (named-) sub and the scope of the variable $r
should be lexically local to the enclosing block. So the value of $r
should be the same as in the "main" block, where it is assigned via
"$r = shift;" at every new request. (I've again attached my version
below for the sake of completeness.)
Moreover I've read that Apache->request should be avoided in mod_perl2:
http://perl.apache.org/docs/2.0/user/porting/compat.html#C_Apache_E_gt_request_
---------- snipp! ----------
#!/usr/bin/perl
use strict;
my $r = shift;
$r->content_type("text/html");
$r->print( "<html>\n"
."<head><title>Testpage</title></head>\n"
."<body>\n" );
&printline1($r, "This works");
&printline2("This crashes the httpd process when it is reused");
$r->print( "</body>\n"
."</html>\n" );
sub printline1 {
my $r = shift;
$r->print($_[0]."<br>\n");
}
sub printline2 {
$r->print($_[0]."<br>\n");
}
1;
---------- snipp! ----------
Cheers,
--leo
--
-----------------------------------------------------------------------
Alexander (Leo) Bergolth leo@leo.wu-wien.ac.at
WU-Wien - Zentrum fuer Informatikdienste http://leo.wu-wien.ac.at
Computers are like air conditioners -
they stop working properly when you open Windows
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Stas Bekman <st...@stason.org>.
Perrin Harkins wrote:
> Alexander Bergolth wrote:
>
>> When I'm using the request-object in a subroutine without having passed
>> it to the sub as a parameter, the apache child processes die with a
>> segmentation fault when being reused.
>
>
> Well, it probably shouldn't segfault, but you can't do that. You are
> creating a closure which will permanently keep a copy of the very first
> $r that existed in that process, but $r is really an apache structure
> that gets freed after each request. If you need a copy of $r but don't
> want to pass it, and you are running in pre-fork MPM, you can use the
> Apache->request() call.
I've looked at trying to avoid the segfault. I think we can't much do about
it. Any object with C guts can be trapped in the closure and contain a pointer
to invalid data on subsequent accesses. You can't check whether the pointer to
the C object is invalid or not. Since its members all look valid and the
memory it used to occupy has been freed already, it may or may not be
overtaken by someone else, so there is no reliable test.
Let's say we have added some signature to each object that marks it as
destroyed on DESTROY. Then we could check that validity flag in every method
attempting to use that object. But it'll add CPU and memory overhead which
normally is not needed, since the closure created by Alexander is a bug in his
program and not a normal behavior.
I'm quite sure that you will have the same problem with mp1, if you run that
closure script on it.
__________________________________________________________________
Stas Bekman JAm_pH ------> Just Another mod_perl Hacker
http://stason.org/ mod_perl Guide ---> http://perl.apache.org
mailto:stas@stason.org http://use.perl.org http://apacheweek.com
http://modperlbook.org http://apache.org http://ticketmaster.com
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html
Re: mod_perl2 (ModPerl::Registry) crashes httpd if request-object
is used in a subroutine
Posted by Perrin Harkins <pe...@elem.com>.
Alexander Bergolth wrote:
> When I'm using the request-object in a subroutine without having passed
> it to the sub as a parameter, the apache child processes die with a
> segmentation fault when being reused.
Well, it probably shouldn't segfault, but you can't do that. You are
creating a closure which will permanently keep a copy of the very first
$r that existed in that process, but $r is really an apache structure
that gets freed after each request. If you need a copy of $r but don't
want to pass it, and you are running in pre-fork MPM, you can use the
Apache->request() call.
- Perrin
--
Reporting bugs: http://perl.apache.org/bugs/
Mail list info: http://perl.apache.org/maillist/modperl.html