我在 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 1select(undef, undef, undef, 1)呼叫,并避免整个问题。

这是你给的症状,我打赌你执行chroot Perl脚本在sleep方面实现SIGALRM(如通过POSIX允许的),以及由于某种原因perl的不没收的信号,因为它应该,也许是因为它没有预料到的是执行。它是Perl中的自定义生成?它是在执行chroot libc的特质?请问下chroot环境perl -e "sleep 1"表现出同样的问题?等等,等等硬不访问环境和类似的工具桁架说的。

再次能够避免整个问题:select不会与SIGALRM淤泥

您还有 Solaris 附带的 Perl 版本吗?如果是这样,请尝试您的代码。如果您没有该版本,建议您下载 珀尔 5.8.7, ,编译库存版本,然后在其上测试您的脚本。

如果您的脚本在这两个版本中的任何一个上正确运行,那么您就知道问题与 Perl 版本的更改有关。如果脚本有同样的错误,那么我建议下载 珀尔 5.8.9, ,编译它,然后检查错误是否消失。如果没有,那么恭喜您,您发现了 Perl 中的错误。你可能会想跑 错误 报告它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top