【发布时间】:2012-05-12 17:21:06
【问题描述】:
我服务器上的 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 gude 我发现:
% gdb httpd <pid of spinning process>
(gdb) where
(gdb) source mod_perl-x.xx/.gdbinit
(gdb) curinfo
但我不知道 .gdbinit 位于何处或我需要安装哪个包 还是我需要自己从源头制作这个文件(可能是Devel::DebugInit::GDB)?
【问题讨论】:
-
为什么要为 SIGUSR2 和 SIGALRM 设置处理程序?
-
警报处理程序应该自动处理程序挂起时间过长的情况。当我发现进程挂起时,usr2 处理程序应该提供对 kill -USR2 做出反应的可能性。但是你是对的,警报处理程序就足够了。我得出的结论是它不起作用,因为在设置警报计时器之前该过程正在停止。可能在 perl 的 bulid(编译)阶段。
标签: perl apache gdb freeze mod-perl2