在Solaris 9上休眠时的SIGALRM [英] SIGALRM while sleeping on Solaris 9
问题描述
在Solaris 9(Sparc)的chroot环境中运行Perl时,我遇到了一个奇怪的错误.我们 使用的是自定义的Perl,但是它几乎与Perl 5.8.7完全一样,并且该版本已经在包括Solaris 8-10在内的各种平台上运行了多年.
I'm running into a bit of a weird error while running Perl in a chroot environment on Solaris 9 (Sparc). We are using a custom Perl, but it's almost exactly Perl 5.8.7, and this version has been running for years on various platforms including 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环境中发生.
However, if I run that, "Just woke up!" never gets printed - instead, the program ends and "Alarm Clock" is echoed to the screen. This only happens if there's a sleep - if I write a program that does a lot of math and takes 10 seconds to run, everything works fine. It also only happens in a chroot environment.
我已经转储了%SIG,它的条目为'ALRM => undef',这是可以预期的-非受限环境具有相同的行为.但是,如果我将脚本更改为包括以下内容:
I've dumped %SIG, which has an entry of 'ALRM => undef', which is expected - the non-chrooted environment has the same behaviour. However, if I change the script to include:
$SIG{ALRM} = sub {};
...一切正常.那么,这是怎么回事?我没有使用Solaris的丰富经验,但是必须有一种方法可以使默认信号处理程序正常运行.
... everything works just fine. So, what's the deal? I don't have a lot of experience with Solaris, but there's got to be a way to make the default signal handlers behave properly.
推荐答案
我要尝试的第一件事是在truss下运行示例程序:
The first thing I'd try is to run your sample program under truss:
truss testprogram.pl
这将显示用于实施睡眠的实际系统调用.在我可以访问的Solaris 8系统上,输出的相关部分是:
This will show the actual system calls used to implement the sleep. On a Solaris 8 system that I have access to, the relevant part of the output is:
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主机上,它输出:
On a Solaris 10 host, it outputs:
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()调用由于某种原因而失败.
I imagine you'll get something closer to the Solaris 8 output, and it'll probably show the sigaction() call fail for some reason.
除此之外,我还要检查chroot/usr/lib中的共享库是否实际上是主机和OS版本的正确版本. truss输出还将准确显示perl正在加载哪些共享库.
Beyond that, I'd check that the shared libraries within the chroot /usr/lib are actually the correct versions for the host and OS version. The truss output will also show you exactly which shared libraries are being loaded by perl.
这篇关于在Solaris 9上休眠时的SIGALRM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!