4

スクリプトの例を次に示します。

#!/usr/bin/perl
use FCGI;
my $request = FCGI::Request();
while($request->Accept() >= 0) {
    die "test";
}

FCGI仕様に従って、Apacheエラーログに「テスト」を出力すると思いますが、代わりに何も起こりません。サイコロを while ループの外側と前に移動すると、エラー ログにメッセージが出力されます。

Apache 構成に関する詳細情報。この行を使用してハンドラーを構成します。

Addhandler fcgid-script .fcgi

suexec が使用されており、fcgi ラッパーとして機能していると言われています。


編集:

部分的な解決策は、FCGI.pm 自体によってもたらされます。

デフォルトでは、die および warn ハンドラはインストールされていません。これは、sfio 対応の perl を実行していない場合、warn または die メッセージがデフォルトでサーバーのログに記録されないことを意味します。自分でダイと警告のハンドラーを設定することをお勧めします。FCGI.pm には、die および warn ハンドラの例が含まれています。

そのため、次の方法で試しました:

#!/usr/bin/perl

use FCGI;
use IO::Handle;

my ( $stdin, $stdout, $stderr ) = ( IO::Handle->new, IO::Handle->new, IO::Handle->new );
my $request = FCGI::Request( $stdin, $stdout, $stderr );
my $err_handler = sub { print {$stderr} @_ };

while($request->Accept() >= 0) {
    $SIG{__WARN__} =  $SIG{__DIE__} = $err_handler;

    warn "test1";
    die "test2";
}

test2問題なくエラー ログに表示されますが、表示されtest1ません。

4

1 に答える 1

0

Perl で記述された FastCGI クライアントで問題を再現しようとしましたが、FCGI.pm は予期した出力を生成します。mod_fcgid に問題がある可能性があります。

#!/usr/bin/perl

use strict;
use warnings;

use IO::Socket             qw[];
use Net::FastCGI::Constant qw[:type :role];
use Net::FastCGI::IO       qw[read_record write_record write_stream];
use Net::FastCGI::Protocol qw[build_params dump_record build_begin_request_body];

use warnings FATAL => 'Net::FastCGI::IO';
use constant TRUE  => !!1;

my $socket = IO::Socket::INET->new(Proto => 'tcp', Listen => 5)
  or die qq/Could not create a listener socket: '$!'/;

my $host = $socket->sockhost;
my $port = $socket->sockport;

defined(my $pid = fork())
  or die qq/Could not fork(): '$!'/;

if (!$pid) {
    close STDIN;
    open(STDIN, '+>&', $socket)
      or die qq/Could not dup socket to STDIN: '$!'/;

    require FCGI;

    my $r = FCGI::Request()
      or die qq/Could not create a FCGI request: '$!'./;

    while ($r->Accept >= 0) {
        print "Perl: $] OS: $^O FCGI: $FCGI::VERSION\n";
        warn "test1";
        die "test2";
    }
    exit(0);
}

close $socket;
$socket = IO::Socket::INET->new(Proto => 'tcp', PeerHost => $host, PeerPort => $port)
  or die qq/Could not connect to '$host:$port': '$@'/;

write_record($socket, FCGI_BEGIN_REQUEST, 1, build_begin_request_body(FCGI_RESPONDER, 0));
write_stream($socket, FCGI_PARAMS, 1, build_params({}), TRUE);
write_stream($socket, FCGI_STDIN, 1, '', TRUE);
while () {
    my ($type, $request_id, $content) = read_record($socket)
      or exit;
    warn dump_record($type, $request_id, $content), "\n";
    last if $type == FCGI_END_REQUEST;
}

出力:

{FCGI_STDERR, 1, "test1 at fcgi-die.pl line 35.\ntest2 at fcgi-die.pl line 36.\n"}
{FCGI_STDERR, 1, ""}
{FCGI_STDOUT, 1, "Perl: 5.014001 OS: darwin FCGI: 0.74\n"}
{FCGI_STDOUT, 1, ""}
{FCGI_END_REQUEST, 1, {0, FCGI_REQUEST_COMPLETE}}
于 2013-04-06T17:50:43.663 に答える