Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

Re: Capturing stack trace in eval

by Joost (Canon)
on Oct 07, 2009 at 19:32 UTC ( #799793=note: print w/ replies, xml ) Need Help??


in reply to Capturing stack trace in eval

You can override CORE::GLOBAL::die to throw an exception object (see the die documentation) which captures the call stack at that moment, instead of just a string.

Which is the only reliable way I've found to do it.

edit: don't try to use the $SIG{__DIE__} for this. It won't work.


Comment on Re: Capturing stack trace in eval
Re^2: Capturing stack trace in eval
by moritz (Cardinal) on Oct 07, 2009 at 20:00 UTC
    edit: don't try to use the $SIG{__DIE__} for this. It won't work.

    Care to elaborate? Surely it won't work if somebody else fiddles with $SIG{__DIE__}, just like overriding CORE::GLOBAL::die won't work if somebody else fiddles with it at same time.

    Perl 6 - links to (nearly) everything that is Perl 6.
      Can't get into the details right now, the code I've worked on isn't here. One issue is that $SIG{__DIE__} won't work correctly with eval {} and eval "", even when testing $^S.

      perlvar sais:

      Due to an implementation glitch, the $SIG{__DIE__} hook is called even inside an eval(). Do not use this to rewrite a pending exception in $@, or as a bizarre substitute for overriding CORE::GLOBAL::die(). This strange action at a dis‐ tance may be fixed in a future release so that $SIG{__DIE__} is only called if your program is about to exit, as was the original intent. Any other use is deprecated.
      The only thing overriding CORE::GLOBAL::die won't catch is compile-time parser errors, but then you won't need a stack trace.

Re^2: Capturing stack trace in eval
by ikegami (Pope) on Oct 07, 2009 at 20:26 UTC

    You can override CORE::GLOBAL::die to throw an exception object

    Yes, but it wouldn't work for Perl errors such as the one the OP wants to capture, "Can't use an undefined value as a symbol reference".

    The only thing overriding CORE::GLOBAL::die won't catch is compile-time parser errors

    It won't catch run-time errors or XS errors either. Perl and XS don't call die, a Perl-space function. They call C function croak (not the one from Carp). Therefore, it only catches user-thrown errors.

      Actually, I might have been mistaken about my SIG{__DIE__} assertion - I mean that using __DIE__ instead of overriding CORE::GLOBAL::die might indeed be the best way of dealing with it.

      As I said I don't have the code with me at the moment - last time I looked at that specific bit of code was a couple of months ago and I switched implementations a few times.

      In any case, the end result turned out that throwing an exception object that encapsulates the stack trace from whatever means you use to intercept the error was the only reasonable way of dealing with the problem when you also have to deal with eval (both versions).

      Update: the way I implemented it, was that the exception object overloaded stringification so that the stack trace is printed if the exception isn't eventually caught.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://799793]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (15)
As of 2014-12-22 17:15 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (121 votes), past polls