in reply to Re: Setting signal handlers considered unsafe?
in thread Setting signal handlers considered unsafe?

Just tried on my home Ubuntu system (perl 5.8.8). Ran for a few seconds (a new record!) and crashed with

Unable to create sub named "" at crash.pl line 15.

This is the exact code I used:
#!/usr/bin/perl use warnings FATAL => qw( all ); use strict; use POSIX qw( :signal_h ); $SIG{ALRM} = sub { print "SIGARLM: main handler\n" }; sub f { my $sigset = POSIX::SigSet->new; my $blockset = POSIX::SigSet->new( SIGALRM ); sigprocmask(SIG_BLOCK, $blockset, $sigset ); local $SIG{ALRM} = sub { print "SIGALRM\n" }; # line 15 sigprocmask(SIG_SETMASK, $sigset ); } if (fork) { # parent f while 1; } else { # child sleep 1; print "child starting\n"; 1 while kill ALRM => getppid; }

Replies are listed 'Best First'.
Re^3: Setting signal handlers considered unsafe?
by TGI (Parson) on Nov 05, 2008 at 23:32 UTC

    I'm no master of perlguts either, but it occurs to me that there are two places where you are vulnerable to signal changes: 1. when you set the localized handler, 2. when the localization goes out of scope and the old handler is installed.

    Your code traps only one of the two vulnerable points.

    What happens if you do:

    #!/usr/bin/perl use warnings FATAL => qw( all ); use strict; use POSIX qw( :signal_h ); $SIG{ALRM} = sub { print "SIGARLM: main handler\n" }; sub f { my $sigset = POSIX::SigSet->new; my $blockset = POSIX::SigSet->new( SIGALRM ); my $old_handler = $SIG{ALRM}; # Install new handler sigprocmask(SIG_BLOCK, $blockset, $sigset ); $SIG{ALRM} = sub { print "SIGALRM\n" }; # line 15 sigprocmask(SIG_SETMASK, $sigset ); # spin a bit. my $x; $x = $_ for 1..10; # Restore old handler. sigprocmask(SIG_BLOCK, $blockset, $sigset ); $SIG{ALRM} = $old_handler; sigprocmask(SIG_SETMASK, $sigset ); } if (fork) { # parent f while 1; } else { # child sleep 1; print "child starting\n"; 1 while kill ALRM => getppid; }


    TGI says moo

Re^3: Setting signal handlers considered unsafe?
by ig (Vicar) on Nov 11, 2008 at 17:41 UTC

    On my system (This is perl, v5.8.8 built for i386-linux-thread-multi) your script ran for many minutes, until I stopped it. I am running CentOS 5.2 with the CentOS distribution of perl.

    Is it possible that your system is not running with safe/deferred signals (environment variable PERL_SIGNALS set to "unsafe")?

      Is it possible that your system is not running with safe/deferred signals (environment variable PERL_SIGNALS set to "unsafe")?

      No. Rather not. All my perl binaries are distribution-provided (perl -V | grep -i sig only returns hint=recommended, useposix=true, d_sigaction=define) and I don't have anything containing 'PERL' in my environment either. The plot thickens... ;)