Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jdavidb (1361)

jdavidb
  (email not shown publicly)
http://voiceofjohn.blogspot.com/

J. David Blackstone has a Bachelor of Science in Computer Science and Engineering and nine years of experience at a wireless telecommunications company, where he learned Perl and never looked back. J. David has an advantage in that he works really hard, he has a passion for writing good software, and he knows many of the world's best Perl programmers.

Journal of jdavidb (1361)

Monday December 04, 2006
03:24 PM

Skipping $SIG{__DIE__} in evals

[ #31803 ]

So I've wrapped up warn and die in order to log whatever they say using Log::Log4perl. However, in my code at one point, I perform an eval, planning to check $@ and ignore it in the most common case, but re-die again if it is something unexpected. Unfortunately, this breaks logging by my definition: I'm still ignoring the case of $@ I specified, but that caught exception is getting logged. I don't want that.

I can mess around with local and removing the %SIG handler, but that still doesn't fix all my problems: I'm calling a module where the author also does an eval that runs some code that occasionally traps an exception I definitely don't want to see (and don't even understand).

I want my @SIG{'__WARN__','__DIE__'} to not fire within an eval. Anyone know how to do that?

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
 Full
 Abbreviated
 Hidden
More | Login | Reply
Loading... please wait.
  • First of all, there's the special variable $^S that is set in a special way inside eval. Check perlvar [perl.org] for the details. So, you check its value in the $SIG{__DIE__} handler, and respond appropriately to its current value.

    Second, I think I saw a module recently that did a

    local $SIG{__DIE__};

    before invoking the eval or even inside it, before doing anything dangerous.

    Some modules even do

    local $SIG{__DIE__} = 'DEFAULT';

    though I don't know about any benefit. I guess there is none.

    • That special var looks like what I want! Thank you!. Although by now I've adopted a totally different approach to get around it. :) But I still wanted to know the answer, because this is going to bite me again.

      I tried local and the DEFAULT thing, but it still became a problem because I'm using modules by other people that do eval's.

      --
      J. David works really hard, has a passion for writing good software, and knows many of the world's best Perl programmers
      • Unfortunately, it's just a problem you have to live with. I've got local $SIG{__DIE__}; scattered all over my code, not because I've written a DIE handler, but because Mason has one. I can see why they do it, but it's a nuisance. I'd really like a way for the handler to only apply in certain circumstances...

        -Dom

        • The consensus (that I only partially agree with) appears to be that every $SIG{__DIE__} handler is supposed to check $^S. So it really should be considered a bug in Mason.

          Personally I would have preferred it if $SIG{__DIE__} handlers would just not be called in eval. Life would have been a lot simpler, then.