Dear List-Members,
with interest I found the below thread. Starting in Oct. or Nov. last year I am
getting a lot of messages in apaches error_log like:
[Fri Feb 5 11:07:09 2010] -e: Software caused connection abort at ...
And it always happen in a print to STDOUT. I notice that it also happen with
smaller scripts (running under mod_perl) with no database connection, i.e.
scripts which do the following:
use CGI;
use IO::File;
my $q = CGI->new();
print $q->header() . $q->start_html();
my $fp = IO::File->new('< /somewhere/');
if ($fp) {
binmode STDOUT;
while (read($fp, $buffer, 1024)) {
print $buffer; # << abort points to here !!!
}
$fh->close();
}
print $q->end_html();
So I am really wondering whats going on here. The above file works for years
now, has not been touched and the content of the opened files isn't empty. The
server is a FreeBSD 7.0, apache apache-2.2.14, prefork MPM, mod_perl2-2.0.4
everything from a current freebsd ports.
I use a perl-startup script for apache:
---snip--snip---
#/usr/bin/perl
use CGI();
CGI->compile(':all');
use DBI;
DBI->install_driver("mysql");
use Carp;
---snap---snap---
which is loaded within httpd.conf with:
<IfModule mod_perl.c>
PerlWarn On
PerlTaintCheck On
PerlModule Apache::DBI
PerlRequire /usr/local/etc/apache22/perl-startup.pl
<Perl>
use CGI::Carp;
$SIG{__DIE__} = sub { confess shift };
$SIG{__WARN__} = \&Carp::cluck;
</Perl>
<Files *.pl>
SetHandler perl-script
PerlHandler ModPerl::Registry
Options ExecCGI
PerlSendHeader On
</Files>
</IfModule>
I would appreciate any help or ideas to get rid of the aborts.
Heiko
> On Tue, Jan 26, 2010 at 5:20 PM, Jonathan Swartz <[email protected]> wrote:
>> This never got a response. Which surprises me, since I think it is a
>> legitimate and nasty bug.
>>
>> So is the silence because
>> 1) people don't think it's really a bug
>> 2) people glazed over while reading the description
>> 3) ??
>
> 4) Don't understand how widespread or common this issue is, or if you
> are the only one seeing it.
>
>>
>> Thanks :)
>> Jon
>>
>> On Jan 8, 2010, at 6:15 AM, Jonathan Swartz wrote:
>>
>>> (A continuation of:
>>> http://marc.info/?l=apache-modperl&m=117507879929572&w=2
>>> http://marc.info/?l=apache-modperl&m=119072925228529&w=2
>>> )
>>>
>>> I've just spent many frustrating days debugging a situation that turned
>>> out to be caused by mod_perl's closing of file descriptor 1 (STDOUT).
>>>
>>> Here's the reproducible case I ultimately got it down to. Using mod_perl
>>> 2, with a dead-simple configuration and this handler:
>>>
>>> use DBI;
>>> sub handler {
>>> my $dbh = DBI->connect( "DBI:mysql:$database", $user, $pass, {
>>> RaiseError => 1 } );
>>> system('echo "hello"');
>>> eval { $dbh->do("select 1") };
>>> print "dbh - " . ( $@ ? "error: $...@\n" : "ok" ) . "\n";
>>> return 0;
>>> }
>>>
>>> This outputs:
>>>
>>> dbh - error: DBD::mysql::db do failed: Lost connection to MySQL server
>>> during query at...
>>>
>>> The DBI connection dies because mod_perl closes fd 1 (STDOUT). So the next
>>> open - in this case the remote mysql connection created by DBI - gets fd 1.
>>> The child process created by system() writes innocently to STDOUT, which
>>> goes to our mysql socket, causing havoc.
>>>
>>> We can confirm this by inserting this at the beginning of the handler:
>>>
>>> sub handler {
>>> open(my $fh, ">/dev/null");
>>> print "fh - " . fileno($fh) . "\n";
>>> ...
>>>
>>> Now this outputs:
>>>
>>> fh - 1
>>> dbh - ok
>>>
>>> The initial open grabs fd 1, which means that DBI gets a different fd, and
>>> the connection doesn't die.
>>>
>>> Now this example is contrived, but replace 'echo "hello"' with any
>>> innocuous system() or backtick call that accidentally sends a bit of output
>>> to STDOUT, and you can see how this would cause all kinds of baffling bugs.
>>> In my case, it was originally a call to "sendmail" that intermittently sent
>>> a warning to STDOUT, and thus destroyed our first database connection. It
>>> worked fine in mod_perl 1, but started breaking when we upgraded to mod_perl
>>> 2.
>>>
>>> Is there really no way to fix this in mod_perl, perhaps by automatically
>>> opening a /dev/null handle as I did above? Other future developers will
>>> surely endure the same hours of frustration I did if it is left alone.
>>>
>>> Thanks
>>> Jon
>>>
>>
>>