mod_perl脚本在“使用”处理期间进入紧密循环

时间:2012-10-24 17:18:36

标签: perl apache cgi mod-perl

我有一个相当复杂的问题需要描述。我正在寻找任何进一步调试的建议。

我正在尝试从常规cgi转换为mod_perl。我向一个加载页面的脚本发送一个http请求,并在该页面上有链接来加载通过其他脚本检索的图像(换句话说,图像是通过cgi脚本加载的,而不仅仅是普通的链接) 。因此,当页面在浏览器中加载时,浏览器会启动另外六个运行脚本以加载图像的请求。

第一个脚本(初始页面加载)运行正常,但在此之后的某个时候,apache服务器在处理图像加载脚本时进入紧密循环(非常高的CPU使用率并且必须被杀死)。有时其中一个图像加载脚本运行正常,但另外一个循环,有时它是循环的第一个图像加载脚本。 strace在循环过程中不显示任何内容。

我在单用户模式下启动了apache服务器(使用-X)并运行带有跟踪的交互式perl调试器以查看循环的开始位置。我已经多次这样做了,每次在完全相同的地方开始,在处理'use'语句时。我看到一堆堆的'使用'和'需要'语句以及其他垃圾,但它始终停在:

Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:97):
97:     eval { local $SIG{__DIE__};
Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:97):
97:     eval { local $SIG{__DIE__};
Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:98):
98:             require XSLoader;
Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:99):
99:             XSLoader::load(__PACKAGE__, $VERSION);
Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:102):
102:    if($@ eq "") {
Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:103):
103:            close(DATA);
Params::Classify::CODE(0x7f43b0b46dd8)(/usr/lib/perl5/Params/Classify.pm:130):
130:    1;
Data::Entropy::CODE(0x7f43b0b46dd8)(/usr/share/perl5/Data/Entropy.pm:46):
46:     use Params::Classify 0.000 qw(is_ref);
Data::Entropy::CODE(0x7f43b0b46dd8)(/usr/share/perl5/Data/Entropy.pm:46):
46:     use Params::Classify 0.000 qw(is_ref);

“使用”处理的这一部分在我的脚本中启动:

use Authen::Passphrase::BlowfishCrypt;

我已经对Data :: Entropy和Params :: Classify进行了一些搜索,但没有找到任何有用的东西(这是我的预期 - 我怀疑它们有错误)。

以前的脚本运行会产生内存损坏的感觉,但我不确定如何跟踪它。由于我是mod_perl的新手,我以为我会让一些专家运行它,看看他们是否遇到过类似的问题,或者对如何进一步调试这个问题提出建议。

运行apache / 2.2.22 mod_perl / 2.0.5 perl / 5.14.2。

代码非常基本,但在这里:

package Wii::Web;

use strict;
use warnings;

use base qw(Wii);

use Data::Dumper;
use Params::Validate qw(:all);
use Log::Log4perl qw(get_logger :easy);
use CGI;
use Carp qw(cluck);
use Email::Valid;
use Authen::Passphrase::BlowfishCrypt;
use Digest::SHA;
use Digest::HMAC;
use Time::HiRes qw(gettimeofday tv_interval);
use Wii::Web::View;
use Wii::Web::Register;
use Wii::Web::Login;
use Wii::Web::Session;
use Wii::Web::User;
use Wii::Web::Found;

$CGI::POST_MAX = 1024 * 5000;

BEGIN {
  $SIG{__DIE__} = \&sigDie;
}

sub sigDie {
  return if $^S; # we are in an eval block

  # assume this is the first print
  my ($error) = @_;
  print "Status: 500\n";
  print "Content-type: text/html\n\n";
  print "<html><body>\n";
  print "<h3>Whoops there was an error!</h3>\n";
  print "<!-- $error  -->\n";
  print "Please try again later<br />\n";
  print "<b>$error</b>\n";
  print "</body></html>\n";

  Wii::sigDie(@_);

  return 1;
}
<snip>

在此之前还涉及其他模块,但这是解决问题的方法。

1 个答案:

答案 0 :(得分:2)

Params :: Classify :: XS不是线程安全的。从使用XS切换到perl Perl版本。