我有一个相当复杂的问题要描述。我正在寻找进一步调试的任何建议。
我正在尝试从常规 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>
在此之前还涉及其他模块,但这是引发问题的模块。