This is a bug report for perl from powe...@sky.net.ua,
generated with the help of perlbug 1.34 running under perl v5.8.0.
-----------------------------------------------------------------
[Please enter your report here]
powerman:~$ time perl -e '
use Time::HiRes qw(alarm);
$SIG{ALRM} = sub { 1 for 1..100000 };
alarm(0.01, 0.01);
sleep(1);
'
Segmentation fault
real 0m33.523s
user 0m33.520s
sys 0m0.000s
Hardcoded constant 100000 should be large enough: loop 1..100000 should take
more than 0.01 sec, so new signal arrives before old signal processed.
The workaround is to reinstall alarm after previous signal handler finished:
powerman:~$ time perl -e '
use Time::HiRes qw(alarm);
$SIG{ALRM} = sub { 1 for 1..100000; alarm(0.01) };
alarm(0.01);
sleep(1) for 1..100;
'
real 0m2.041s
user 0m1.020s
sys 0m0.000s
This bug seems to be related to "Safe Signals" introduced in 5.8.0 because
5.6.1 don't die with 'Segmentation fault', it just hang (and it should hang!).
[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
category=core
severity=critical
---
Site configuration information for perl v5.8.0:
Configured by root at Tue Feb 11 17:22:15 EET 2003.
Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration:
Platform:
osname=linux, osvers=2.4.19, archname=i686-linux-thread-multi
uname='linux home.power 2.4.19 #1 вск авг 18 00:22:21 eest 2002 i686 unknown '
config_args='-Dprefix=/usr -Doptimize= -O3 -march=athlon -mcpu=athlon -d -e -s -Dinstallprefix=/usr -Dusethreads'
hint=recommended, useposix=true, d_sigaction=define
usethreads=define use5005threads=undef useithreads=define usemultiplicity=define
useperlio=define d_sfio=undef uselargefiles=define usesocks=undef
use64bitint=undef use64bitall=undef uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
optimize=' -O3 -march=athlon -mcpu=athlon ',
cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing'
ccversion='', gccversion='3.0', gccosandvers=''
intsize=4, longsize=4, ptrsize=4, doublesize=8, byteorder=1234
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=12
ivtype='long', ivsize=4, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
alignbytes=4, prototype=define
Linker and Libraries:
ld='cc', ldflags =' -L/usr/local/lib'
libpth=/usr/local/lib /lib /usr/lib
libs=-lnsl -lndbm -ldbm -ldb -ldl -lm -lpthread -lc -lcrypt -lutil
perllibs=-lnsl -ldl -lm -lpthread -lc -lcrypt -lutil
libc=/lib/libc-2.2.5.so, so=so, useshrplib=false, libperl=libperl.a
gnulibc_version='2.2.5'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-rdynamic'
cccdlflags='-fpic', lddlflags='-shared -L/usr/local/lib'
Locally applied patches:
---
@INC for perl v5.8.0:
/usr/lib/perl5/5.8.0/i686-linux-thread-multi
/usr/lib/perl5/5.8.0
/usr/lib/perl5/site_perl/5.8.0/i686-linux-thread-multi
/usr/lib/perl5/site_perl/5.8.0
/usr/lib/perl5/site_perl
.
---
Environment for perl v5.8.0:
HOME=/home/powerman
LANG=ru_RU.koi8r
LANGUAGE (unset)
LD_LIBRARY_PATH (unset)
LOGDIR (unset)
PATH=/home/powerman/bin:/bin:/usr/bin:/sbin:/usr/sbin:/usr/X11R6/bin:/usr/local/bin:/usr/local/sbin
PERL_BADLANG (unset)
SHELL=/bin/bash
The safe signals implementation has the side effect that signals are
not blocked anymore if the same signal is raised while the signal
handler is running. This is normally done automatically by the OS and
should now be manually set using sigprocmask (see patch below).
--- bleedperl/mg.c Sun Feb 2 18:59:19 2003
+++ bleedperl2/mg.c Fri Feb 14 08:47:04 2003
@@ -1159,8 +1159,24 @@ Perl_despatch_signals(pTHX)
PL_sig_pending = 0;
for (sig = 1; sig < SIG_SIZE; sig++) {
if (PL_psig_pend[sig]) {
+#define PERL_BLOCK_SIGNALS
+#if defined(HAS_SIGPROCMASK) && defined(PERL_BLOCK_SIGNALS)
+ /* From sigaction(2) (FreeBSD man page):
+ * | Signal routines normally execute with the signal that
+ * | caused their invocation blocked, but other signals may
+ * | yet occur.
+ * Emulate this behavior.
+ */
+ sigset_t set;
+ sigemptyset(&set);
+ sigaddset(&set,sig);
PL_psig_pend[sig] = 0;
+ sigprocmask(SIG_BLOCK, &set, NULL);
+#endif /* HAS_SIGPROCMASK */
(*PL_sighandlerp)(sig);
+#if defined(HAS_SIGPROCMASK) && defined(PERL_BLOCK_SIGNALS)
+ sigprocmask(SIG_UNBLOCK, &set, NULL);
+#endif /* HAS_SIGPROCMASK */
}
}
}
--
Slaven Rezic - sla...@rezic.de
Berlin Perl Mongers - http://berliner.pm.org
Does this SIG_UNBLOCK code get called if (*PL_sighandlerp)(sig) die()s?
--
"So, who beat the clueless idiot today?"
"Well, we flipped for it, but when Kuno
landed, he wasn't in any shape to fight."
"Next time, try flipping a *coin.*"
> Slaven Rezic wrote:
> [snip]
> > + sigprocmask(SIG_BLOCK, &set, NULL);
> > +#endif /* HAS_SIGPROCMASK */
> > (*PL_sighandlerp)(sig);
> > +#if defined(HAS_SIGPROCMASK) && defined(PERL_BLOCK_SIGNALS)
> > + sigprocmask(SIG_UNBLOCK, &set, NULL);
> > +#endif /* HAS_SIGPROCMASK */
>
> Does this SIG_UNBLOCK code get called if (*PL_sighandlerp)(sig) die()s?
>
Not this one, but there's already another SIG_UNBLOCK in
Perl_sighandler which will be called if the signal handler dies.
Regards,
Slaven
--
Slaven Rezic - sla...@rezic.de
tkruler - Perl/Tk program for measuring screen distances
http://ptktools.sourceforge.net/#tkruler
Thanks, applied as change #18765.
--
Jarkko Hietaniemi <j...@iki.fi> http://www.iki.fi/jhi/ "There is this special
biologist word we use for 'stable'. It is 'dead'." -- Jack Cohen