1

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

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

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

我已经以单用户模式(使用 -X)启动了 apache 服务器,并运行带有跟踪的交互式 perl 调试器,以查看循环从哪里开始。我已经这样做了好几次,每次它都在完全相同的地方开始,在处理“使用”语句期间。我看到成堆的“使用”和“要求”语句以及其他垃圾,但它总是停在:

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>

在此之前还涉及其他模块,但这是引发问题的模块。

4

1 回答 1

2

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

于 2012-10-24T17:58:15.030 回答