Hello,
I encountered a problem which is best represented as Perl code:
#!/usr/bin/perl use warnings FATAL => qw( all ); use strict; $SIG{ALRM} = sub { print "SIGARLM: main handler\n" }; sub f { local $SIG{ALRM} = sub { print "SIGALRM\n" }; # line 9 } if (fork) { # parent f while 1; } else { # child sleep 1; print "child starting\n"; 1 while kill ALRM => getppid; }
When I run this code, the parent process dies within seconds of the child entering the loop. It looks like the default handler gets occasionally executed (the really default one, terminating the process). I have also seen things like:
and (in a less stripped-down chunk of code throwing exceptions instead of printing stuff) just about every possible error message and several impossible ones.Unable to create sub named "" at testdrive/signal.pl line 9.
I tested this on Debian and Ubuntu systems, both brand new and several years old, with perls 5.8.4, 5.8.8 and 5.10.0. Setting the signal mask manually (via sigprocmask) doesn't help either. Setting the handler without using local also doesn't change anything. I couldn't reproduce it under strace, due to changes in timing or weird things that strace does to signal handlers, I don't really know.
Any ideas?
Thanks,
Grzegorz Nosek
UPDATE:
Yes, the code is silly. My point is atomicity of setting signal handlers, not the most efficient way of catching SIGALRM :)
UPDATE 2:
local $SIG{FOO} = \&bar; is unsafe (the signal handler gets reset to SIG_DFL for a short moment, possibly crashing the process). I haven't been able to wrap it in sigprocmask safely in any way.
Setting $SIG{FOO} without local is apparently safe.
UPDATE 3:
A signal handler may sometimes leak out of an eval block even when it seems impossible from looking at Perl code. A simple workaround is to yield the CPU to allow signal delivery (Time::HiRes and sleep 1.01e-6 seems sufficient, although sleep 1e-6 is not). I guess it's nasty enough for a workaround.
UPDATE 4:
My real-world code still doesn't work though...
In reply to Setting signal handlers considered unsafe? by gnosek
| For: | Use: | ||
| & | & | ||
| < | < | ||
| > | > | ||
| [ | [ | ||
| ] | ] |