在 Solaris 9 上休眠时发出 SIGALRM
题
我在 Solaris 9 (Sparc) 的 chroot 环境中运行 Perl 时遇到了一些奇怪的错误。我们 是 使用自定义 Perl,但它几乎完全是 Perl 5.8.7,并且该版本已在包括 Solaris 8-10 在内的各种平台上运行多年。
下面的代码非常简单:
#!/usr/bin/perl
use strict;
use warnings;
print "About to sleep(1)\n";
sleep 1;
print "Just woke up!\n";
但是,如果我运行的话,“醒来!”永远不会打印 - 相反,程序结束,“闹钟”回荡在屏幕上。只有在睡眠时才会发生这种情况 - 如果我编写一个执行大量数学运算并需要 10 秒运行的程序,则一切正常。它也只发生在 chroot 环境中。
我已经转储了 %SIG,它有一个“ALRM => undef”条目,这是预期的 - 非 chroot 环境具有相同的行为。但是,如果我更改脚本以包括:
$SIG{ALRM} = sub {};
...一切都很好。那么,到底是怎么回事呢?我对 Solaris 没有太多经验,但必须有一种方法可以使默认信号处理程序正常运行。
解决方案
我想尝试的第一件事是在运行示例程序下桁架:
truss testprogram.pl
这将显示用于实现睡眠实际的系统调用。上,我必须访问Solaris 8系统中,输出的相关部分是:
write(1, " A b o u t t o s l e".., 18) = 18
time() = 1247258429
alarm(0) = 0
sigaction(SIGALRM, 0xFFBEF6E0, 0xFFBEF790) = 0
sigfillset(0xFF0C28D0) = 0
sigprocmask(SIG_BLOCK, 0xFFBEF780, 0xFFBEF770) = 0
alarm(1) = 0
Received signal #14, SIGALRM, in sigsuspend() [caught]
sigsuspend(0xFFBEF760) Err#4 EINTR
setcontext(0xFFBEF448)
alarm(0) = 0
sigprocmask(SIG_UNBLOCK, 0xFFBEF780, 0x00000000) = 0
sigaction(SIGALRM, 0xFFBEF6E0, 0x00000000) = 0
time() = 1247258430
Just woke up!
write(1, " J u s t w o k e u p".., 14) = 14
在Solaris 10主机时,它输出:
write(1, " A b o u t t o s l e".., 18) = 18
time() = 1247258270
nanosleep(0xFFBFF770, 0xFFBFF768) = 0
time() = 1247258271
Just woke up!
write(1, " J u s t w o k e u p".., 14) = 14
我想你会得到的东西更接近到Solaris 8个输出,它可能会显示的sigaction()调用失败,出于某种原因。
除此之外,我会检查的chroot / usr / lib中内的共享库实际上是正确的版本的主机和操作系统版本。桁架输出也将恰好显示您库正被perl的加载哪个共享。
其他提示
我建议简单地更换与sleep 1
的select(undef, undef, undef, 1)
呼叫,并避免整个问题。
这是你给的症状,我打赌你执行chroot Perl脚本在sleep
方面实现SIGALRM
(如通过POSIX允许的),以及由于某种原因perl的不没收的信号,因为它应该,也许是因为它没有预料到的是执行。它是Perl中的自定义生成?它是在执行chroot libc
的特质?请问下chroot环境perl -e "sleep 1"
表现出同样的问题?等等,等等硬不访问环境和类似的工具桁架说的。
再次能够避免整个问题:select
不会与SIGALRM
淤泥