You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@perl.apache.org by Steve Hay <St...@planit.com> on 2010/12/08 19:31:59 UTC

APR errors not working on Win32

I have some mod_perl-2 software which keeps causing the Apache server to
crash, and I believe the cause of it is users pressing the Stop button
in their browsers, causing the pipe to be broken, which then leads to
the crash when CGI::Carp's fatalsToBrowser feature tries to send an HTML
error message to the browser (... saying that data can't be sent to the
client!!!).

I want to catch the "broken pipe" error and simply log it in the
error.log, and rethrow other exceptions (to be picked up by CGI::Carp's
fatalsToBrowser), but instead of getting an APR::Error object, I'm
getting a string saying "APR does not understand this error code"

The following program (running via ModPerl::Registry) reproduces the
problem:

use strict;
use warnings;
BEGIN {
    require CGI::Carp;
    CGI::Carp->import(qw(fatalsToBrowser));
    CGI::Carp::set_message(' ');
}
print "Content-Type: text/plain\n\n";
print '-' x 80, "\n" while (1);

Set the program running, then press Stop in the web browser. The Apache
server crashes (usually just the child exiting with status 9, and the
parent spawns a new one, but occasionally the whole thing seems to abort
with status 2) with this in the error.log:

[Wed Dec 08 18:07:02 2010] [info] [client 10.23.100.22] (OS 10054)An
existing connection was forcibly closed by the remote host.  :
core_output_filter: writing data to the network
:Apache2 IO flush: (620018) APR does not understand this error code at
-e line 0[Wed Dec 08 18:07:02 2010] [notice] Parent: child process
exited with status 9 -- Restarting.

If I change the last two lines of code to:

my $ok = eval {
    print "Content-Type: text/plain\n\n";
    print '-' x 80, "\n" while (1);
};
if (not defined $ok) {
    if ($@) {
        if (ref $@) {
            printf STDERR "Caught an %s: %s\n", ref($@), $@;
        }
        else {
            printf STDERR "Caught a string: %s\n", $@;
        }
    }
    else {
        printf STDERR "Unexpected\n";
    }
}

then it no longer crashes. The error is simply caught and logged to
error.log, which now says:

[Wed Dec 08 18:23:35 2010] [info] [client 10.23.100.22] (OS 10054)An
existing connection was forcibly closed by the remote host.  :
core_output_filter: writing data to the network
Caught a string: APR does not understand this error code at
C:/Radview/apache/cgi-bin/problem.pl line 12.

However, I want to only do that in certain cases where a useful HTML
error message can't be written back to the browser, but (as seen above)
$@ is a fairly useless string (not even with the "(620018)" bit that
Apache normally logs) instead of the useful APR::Error object that I was
hoping for.

What's gone wrong here and/or is there some other way of handling this
situation (which works on Win32!)?

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


RE: APR errors not working on Win32

Posted by Steve Hay <St...@planit.com>.
Steve Hay wrote on 2010-12-13:
> Steve Hay wrote on 2010-12-08:
>> I have some mod_perl-2 software which keeps causing the Apache server
>> to crash, and I believe the cause of it is users pressing the Stop
>> button in their browsers, causing the pipe to be broken, which then
>> leads to the crash when CGI::Carp's fatalsToBrowser feature tries to
>> send an HTML error message to the browser (... saying that data can't
>> be sent to the client!!!).
>> 
>> I want to catch the "broken pipe" error and simply log it in the
>> error.log, and rethrow other exceptions (to be picked up by
CGI::Carp's
>> fatalsToBrowser), but instead of getting an APR::Error object, I'm
>> getting a string saying "APR does not understand this error code"
>> 
> 
> Found where the problem is. PerlIOApache_write() mistakenly called
> Perl_croak() with a stringified apr_status_t instead of using
> MP_RUN_CROAK() (which makes a proper APR::Error object to croak with)
> like PerlIOApache_flush() does.
> 
> The attached patch fixes this.
> 
> I will apply it soon unless anyone knows of any reason why
> PerlIOApache_write() should be different.


Now applied as r1052232.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@perl.apache.org
For additional commands, e-mail: dev-help@perl.apache.org


RE: APR errors not working on Win32

Posted by Steve Hay <St...@planit.com>.
Steve Hay wrote on 2010-12-08:
> I have some mod_perl-2 software which keeps causing the Apache server
to
> crash, and I believe the cause of it is users pressing the Stop button
> in their browsers, causing the pipe to be broken, which then leads to
> the crash when CGI::Carp's fatalsToBrowser feature tries to send an
HTML
> error message to the browser (... saying that data can't be sent to
the
> client!!!).
> 
> I want to catch the "broken pipe" error and simply log it in the
> error.log, and rethrow other exceptions (to be picked up by
CGI::Carp's
> fatalsToBrowser), but instead of getting an APR::Error object, I'm
> getting a string saying "APR does not understand this error code"
> 

Found where the problem is. PerlIOApache_write() mistakenly called
Perl_croak() with a stringified apr_status_t instead of using
MP_RUN_CROAK() (which makes a proper APR::Error object to croak with)
like PerlIOApache_flush() does.

The attached patch fixes this.

I will apply it soon unless anyone knows of any reason why
PerlIOApache_write() should be different.