我有一个相当复杂的问题需要描述。我正在寻找任何进一步调试的建议。
我正在尝试从常规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>
在此之前还涉及其他模块,但这是解决问题的方法。
答案 0 :(得分:2)
Params :: Classify :: XS不是线程安全的。从使用XS切换到perl Perl版本。