Skipping $SIG{__DIE__} in evals

jdavidb on 2006-12-04T20:24:13

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?


Surely there's more than one way to do it...

bart on 2006-12-04T20:47:44

First of all, there's the special variable $^S that is set in a special way inside eval. Check perlvar 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.

Re:Surely there's more than one way to do it...

jdavidb on 2006-12-04T21:38:56

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.

Re:Surely there's more than one way to do it...

Dom2 on 2006-12-05T07:18:38

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

Re:Surely there's more than one way to do it...

bart on 2006-12-05T18:50:54

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.