On Tue, Jan 26, 2010 at 5:20 PM, Jonathan Swartz <swa...@pobox.com> 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
>>
>
>

Reply via email to