在Solaris 9上休眠时的SIGALRM [英] SIGALRM while sleeping on Solaris 9

查看:131
本文介绍了在Solaris 9上休眠时的SIGALRM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆