Re: [mp2] mod_perl closes apache's stdin and/or stdout
Jonathan Swartz <[email protected]>
| Newsgroups | gmane.comp.apache.mod-perl |
|---|---|
| Message-ID | <[email protected]> |
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) ??
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
>