1

我服务器上的 apache 子进程(ubuntu 12.04 从 11.10 升级,apache 2.2.22,perl 5.14.2,mod_perl 2.0.5)正在挂起。

我试图捕捉信号 usr2,并发出警报,但没有成功(当使用 sleep 进行测试时,它的工作方式与预期的一样,但当程序自行挂起时没有给出输出)

sub handler : method{
my $mask      = POSIX::SigSet->new(&POSIX::SIGUSR2, &POSIX::SIGALRM);
my $oldaction_usr2 = POSIX::SigAction->new();
my $oldaction_alarm = POSIX::SigAction->new();
my $action = POSIX::SigAction->new(sub {
    Carp::confess("hm caught SIGUSR2 or ALARM DEAD LOCK YOU can run but not hide!");
},$mask,&POSIX::SA_NODEFER);
POSIX::sigaction(&POSIX::SIGUSR2,$action, $oldaction_usr2);
POSIX::sigaction(&POSIX::SIGALRM,$action, $oldaction_alarm);
alarm(30); #max 30 seconds per request

所以我使用 Apache 状态来获取挂起的孩子的 pid(cpu 时间没有增加,但只有 SS(自最近请求开始以来的秒数)。

然后我将 gdb 与 pid 连接起来以获取回溯:

(gdb) bt
#0  0x00007fc4610fb606 in myck_entersub (my_perl=0x7fc47f7f63e0, op=0x7fc484b40910) at lib/Params/Classify.xs:682
#1  0x00007fc477a67abd in Perl_convert () from /usr/lib/libperl.so.5.14
#2  0x00007fc477a6f769 in Perl_utilize () from /usr/lib/libperl.so.5.14
#3  0x00007fc477a9daef in Perl_yyparse () from /usr/lib/libperl.so.5.14
#4  0x00007fc477b1635d in ?? () from /usr/lib/libperl.so.5.14

问题是我不知道如何解决这个问题或这意味着什么。在modper 1 上,我发现:

% gdb httpd <pid of spinning process>
(gdb) where
(gdb) source mod_perl-x.xx/.gdbinit
(gdb) curinfo

但我不知道 .gdbinit 位于何处,或者我需要安装哪个软件包,还是我需要自己从源代码(可能使用Devel::DebugInit::GDB)制作这个文件?

4

1 回答 1

1

问题可能是“Params::Classify”,它不是线程安全的。看:

https://bugs.launchpad.net/ubuntu/+source/libmodule-runtime-perl/+bug/991650

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

http://www.perlmonks.org/?node_id=886909

Params::Classify 的作者在 2011 年 11 月承认了这个问题,但尚未发布修复程序。

于 2013-06-03T01:50:59.107 回答