【问题标题】:Why do I get "redefine" warnings with "use constant" under mod_perl?为什么我在 mod_perl 下会收到带有“使用常量”的“重新定义”警告?
【发布时间】:2009-07-31 01:53:07
【问题描述】:

我使用 apache2 运行 CGI 脚本,并且在 error.log 中有此警告行(我从输出中删除了所有类似的行):

[Thu Jul 30 09:39:37 2009] upload.pl:常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::UPLOAD_DIR 在 /usr/share/perl/5.10/constant.pm 第 115 行重新定义,第 133 行。 常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::BUFFER_SIZE 重新定义在 /usr/share/perl/5.10/constant.pm 第 115 行,第 133 行 (#1) [Thu Jul 30 09:39:37 2009] upload.pl:常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::BUFFER_SIZE 在 /usr/share/perl/5.10/constant.pm 第 115 行重新定义,第 133 行。 常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::MAX_FILE_SIZE 在 /usr/share/perl/5.10/constant.pm 第 115 行,第 133 行重新定义(#1) [Thu Jul 30 09:39:37 2009] upload.pl:常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::MAX_FILE_SIZE 在 /usr/share/perl/5.10/constant.pm 第 115 行重新定义,第 133 行。 常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::MAX_DIR_SIZE 重新定义在 /usr/share/perl/5.10/constant.pm 第 115 行,第 133 行 (#1) [Thu Jul 30 09:39:37 2009] upload.pl:常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::MAX_DIR_SIZE 在 /usr/share/perl/5.10/constant.pm 第 115 行重新定义,第 133 行。 常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::MAX_OPEN_TRIES 重新定义在 /usr/share/perl/5.10/constant.pm 第 115 行,第 133 行 (#1) [Thu Jul 30 09:39:37 2009] upload.pl:常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::MAX_OPEN_TRIES 在 /usr/share/perl/5.10/constant.pm 第 115 行重新定义,第 133 行。 子程序 dir_size 在 /home/stanislav/cgi/perl/upload.pl 第 79 行重新定义, 第 133 行(#2) [Thu Jul 30 09:39:37 2009] upload.pl:在 /home/stanislav/cgi/perl/upload.pl 第 79 行、第 133 行重新定义子例程 dir_size。 在 /home/stanislav/cgi/perl/upload.pl 第 90 行重新定义子程序错误, 第 133 行(#2) [Thu Jul 30 09:39:37 2009] upload.pl:在 /home/stanislav/cgi/perl/upload.pl 第 90 行,第 133 行重新定义了子程序错误。 参数 "" 在数字 ge (>=) 中不是数字 /home/stanislav/cgi/perl/upload.pl 第 62 行 (#4) [2009 年 7 月 30 日星期四 09:39:37] -e:参数“”在 /home/stanislav/cgi/perl/upload.pl 第 62 行的数字 ge (>=) 中不是数字。 文件句柄 OUTPUT 仅在 /home/stanislav/cgi/perl/upload.pl 处为输入打开 第 69 行(#5) [2009 年 7 月 30 日星期四 09:39:37] -e:文件句柄 OUTPUT 仅在 /home/stanislav/cgi/perl/upload.pl 第 69 行为输入打开。 常量子程序 ModPerl::ROOT::ModPerl::Registry::home_stanislav_cgi_perl_upload_2epl::UPLOAD_DIR 在 /usr/share/perl/5.10/constant.pm 第 115 行,第 133 行重新定义 (#1)

为什么会有这条线,有没有办法阻止它们?

发出此警告的代码(取自“CGI Programming with Perl”一书,其中包含一些 错误已修复):



#!/usr/bin/perl
use strict;
use warnings;


use CGI;
use CGI::Carp;
#use diagnostics qw/-verbose/;

use Fcntl qw( :DEFAULT :flock );
use constant UPLOAD_DIR     => "/tmp/test_upload/";
use constant BUFFER_SIZE    => 16_384;
use constant MAX_FILE_SIZE  => 1_048_576;       # Limit each upload to 1 MB
use constant MAX_DIR_SIZE   => 100 * 1_048_576; # Limit total uploads to 100 MB
use constant MAX_OPEN_TRIES => 100;

$CGI::DISABLE_UPLOADS   = 0;
$CGI::POST_MAX          = MAX_FILE_SIZE;
my $q = new CGI;
$q->cgi_error and error( $q, "Error transferring file: " . $q->cgi_error );
my $file      = $q->param( "file" )     || error( $q, "No file received." );
my $filename  = $q->param( "filename" ) || error( $q, "No filename entered." );
my $fh        = $q->upload( "file" )     || error( $q, "Something is wrong with file handle." );
#my $fh        = $q->upload( $file );
my $buffer    = "";
if ( dir_size( UPLOAD_DIR ) + $ENV{CONTENT_LENGTH} > MAX_DIR_SIZE ) {
    error( $q, "Upload directory is full." );
}
# Allow letters, digits, periods, underscores, dashes
# Convert anything else to an underscore
$filename =~ s/[^\w.-]/_/g;
if ( $filename =~ /^(\w[\w.-]*)/ ) {
    $filename = $1;
}
else {
    error( $q, "Invalid file name; files must start with a letter or number." );
}
# Open output file, making sure the name is unique
until ( sysopen OUTPUT, UPLOAD_DIR . $filename, O_CREAT | O_EXCL ) {
    $filename =~ s/(\d*)(\.\w+)$/($1||0) + 1 . $2/e;
    $1 >= MAX_OPEN_TRIES and error( $q, "Unable to save your file." );
}
# This is necessary for non-Unix systems; does nothing on Unix
binmode $fh;
binmode OUTPUT;
# Write contents to output file
while ( read( $fh, $buffer, BUFFER_SIZE ) ) {
    print OUTPUT $buffer;
}
close OUTPUT;

if ( -T $fh ) {
    print $q->header("text/plain");
    seek $fh, 0, 0;
    map { print } ;
}

sub dir_size {
    my $dir = shift;
    my $dir_size = 0;

    # Loop through files and sum the sizes; doesn't descend down subdirs
    opendir DIR, $dir or die "Unable to open $dir: $!";
    while ( $_ = readdir DIR ) {
        $dir_size += -s "$dir/$_";
    }
    return $dir_size;
}
sub error {
    my( $q, $reason ) = @_;

    print $q->header( "text/html" ),
          $q->start_html( "Error" ),
          $q->h1( "Error" ),
          $q->p( "Your upload was not procesed because the following error ",
                 "occured: " ),
          $q->p( $q->i( $reason ) ),
          $q->end_html;
    exit;
}

这段代码有类似的输出: $ perl -e 'sub FOO () { 1 } BEGIN{ *FOO = sub () { 2 }; } print FOO;'

常量子程序 main::FOO 在 -e 第 1 行重新定义。

我确实没有发出警告 qw/redefine/ 但它没有帮助。

【问题讨论】:

    标签: perl cgi warnings mod-perl


    【解决方案1】:

    AFAIK,只有在修改脚本时才会收到这些警告,然后mod_perl 为符合内联条件的子例程重新编译脚本。当子程序被重新编译时,如果它返回的值发生了变化,那么这个新值将不会反映在它之前被内联的地方。

    如果你改变了BUFFER_SIZE的值,你应该重新启动apache

    我也认为mod_perl / Apache::Registry accidental closures 与您的脚本相关。

    【讨论】:

      【解决方案2】:

      据推测,FOO 的第一个定义正在被优化掉。用正文中的语句定义它,我想你会发现错误消失了。

      $ perl -e 'sub FOO () { print 1; } BEGIN{ *FOO = sub () { 2 }; } print FOO;'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多