Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

How bad is $SIG{__DIE__} really?

by haukex (Archbishop)
on Oct 11, 2016 at 09:59 UTC ( [id://1173708]=perlquestion: print w/replies, xml ) Need Help??

haukex has asked for the wisdom of the Perl Monks concerning the following question:

Fellow Monks,

The thread Getting the Behavior of the "file open or die" Pragma but with a Program Pause got me thinking about this. The documentation of $SIG{__DIE__} says this:

Having to even think about the $^S variable in your exception handlers is simply wrong. $SIG{__DIE__} as currently implemented invites grievous and difficult to track down errors. Avoid it and use an END{} or CORE::GLOBAL::die override instead.

That exact paragraph has been present in perlvar since 1999, and although it sounds like a pretty dire warning, currently it's at the bottom of that section of documentation. I've seen $SIG{__DIE__} used in lots of places, and I've used it myself a few times, mostly to rewrite the die message and add additional information, and sometimes to send error messages to syslog as well. Although the code seems to work fine, now I'm wondering about that. Is $SIG{__DIE__} really as bad as the documentation says and should I be avoiding it for these uses? As always, your wisdom would be appreciated.

Update: Some examples of how I've used $SIG{__DIE__}:

local $SIG{__DIE__} = sub { die "[".gmtime." UTC] (PID $$) FATAL ".shi +ft }; # - OR - # for my $i (0..10) { local $SIG{__DIE__} = sub { my $e = shift; $e=~s/\.?\n?$//; die "$ +e (item $i)\n" }; } # - OR - # local $SIG{__DIE__} = sub { chomp(my $m = shift); syslog('err','Error: + %s',$m) };

What say you, have I sinned?

P.S. I should say that I am aware of the issues of how $SIG{__DIE__} interacts with eval and that specifically hasn't been a problem for me so far. I'm asking mostly about the other, more general, warning in the documentation I quoted above.

Thanks,
-- Hauke D

Replies are listed 'Best First'.
Re: How bad is $SIG{__DIE__} really?
by Corion (Patriarch) on Oct 11, 2016 at 10:34 UTC

    Having looked at SIG magic, it's even more horrible, but the real thing on why to avoid $SIG{__DIE__} is when you mix die and eval. If you can live with your $SIG{__DIE__} handler getting called even when the program doesn't actually die, then I think using it to copy the message to some logging/notification is OK.

    $SIG{__DIE__} = sub { die "[".gmtime." UTC] (PID $$) FATAL ".shift }; if( !eval { die "Whoops"; 1; }) { print "Error reading config file, using defaults\n"; ... };

    Update: Upon reading your node to completion, you already mentioned the case I'm pointing out, sorry.

    Outside of that weird/potentially confusing interaction, I simply wouldn't want to put complex logic in a SIG handler because something already went wrong, but again, copying the message to syslog or whatever doesn't seem too bad.

      Hi Corion,

      Update: Upon reading your node to completion, you already mentioned the case I'm pointing out, sorry.

      I didn't add that "P.S." until I added the "Update", so if there was an overlap in the posting times and you didn't see it, then it's me who should be apologizing! :-/

      Regards,
      -- Hauke D

Re: How bad is $SIG{__DIE__} really?
by ateague (Monk) on Oct 11, 2016 at 13:59 UTC

    A combination of $SIG{__DIE__} and $^S is what is recommended by Log::Log4Perl

    All the usages I have seen invert the conditions that brian d foy was talking about in his article; the $SIG{__DIE__} handler is skipped in eval{}

    i.e.:

    $SIG{__DIE__} = sub { return if $^S; # ignore die in an eval block # Get the actual caller for the "die" and not the wrapper local $Log::Log4perl::caller_depth; $Log::Log4perl::caller_depth++; LOGDIE($_[0]); };
Re: How bad is $SIG{__DIE__} really?
by Discipulus (Canon) on Oct 11, 2016 at 10:51 UTC
    If i can add something I remember that die handler has a lot of magics and among them it concatenates it's arguments:
    perl -e "$SIG{__DIE__} = sub { print qq($0 - $_\n)for @_ }; die qw(a l +ot of words)" -e - alotofwords at -e line 1. alotofwords at -e line 1.

    See Perl's Warn and Die Signals and Any last words?

    L*

    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: How bad is $SIG{__DIE__} really?
by stevieb (Canon) on Oct 11, 2016 at 13:47 UTC

    I'm not going to speak too much to the bad and/or the good of trapping warnings/die/interrupt with $SIG handlers, because I've used them all.

    One frustrating thing though is when you are troubleshooting code when you're expecting something to happen, but then you find someone's trapped __WARN__, __DIE__ and/or INT. You've spent hours trying to figure out why something did or didn't happen to realize you were correct in the first place, but something was doing something not documented.

    My advice is when you trap anything that breaks normal flow (all of these handlers affect the entire stack, even code far away), document it within your POD.

    From my RPi::WiringPi distribution:

    "We also trap $SIG{__DIE__} and $SIG{INT}, so that in the event of a crash, we can reset the Pi back to default settings, so components are not left in an inconsistent state."

    This was needed here, as I'm dealing directly with hardware, where if the program crashes, the user needs to be assured that the hardware is reset to its original state (on the Raspberry Pi, the GPIO pins, registers and other items will stay in the state you last left them, crash or not).

      If you clean up in destructors, then you don't have to try to trap global events. Having a non-global thing (such as your module) try to trap global events is usually a pretty bad idea, as the methods for trapping such things don't have built-in support for multiple handlers.

      - tye        

        You're absolutely right tye. I suppose in my case I'd only have to watch for $SIG{INT} (as DESTROY() isn't called on the interrupt signal), and not $SIG{__DIE__}.

Re: How bad is $SIG{__DIE__} really?
by haukex (Archbishop) on Oct 26, 2016 at 08:31 UTC

    Hi everyone,

    Thanks very much for your replies, and sorry for my late reply, I've been very busy with other things.

    I think what threw me off is how dire the warning I quoted sounds, but on re-reading the section of the documentation, it does sound more like the warning is referring to errors that happen during parsing (compilation). Unfortunately, I haven't yet found any background on the commit 19799a2 where the wording was introduced, the P5P archives seem to end a few months prior to the commit, and I haven't yet found anything in RT.

    Anyway, taking all your replies together, it does seem like using $SIG{__DIE__} - at least as shown in the OP - is not such a bad thing, and since my handlers are generally installed during runtime and not compilation, and I'm not doing anything all too wild in the handlers, I think that for now I'll continue using code like what I showed. Thanks again!

    Regards,
    -- Hauke D

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1173708]
Front-paged by Arunbear
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others chilling in the Monastery: (8)
As of 2024-04-18 08:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found