2

Chances are I invoke method x on an object of the wrong type, but it's way down in my call stack, so it's not obvious.

So: is there a way of always printing a full stack trace when this error occurs?

Johannes Ernst
  • 3,072
  • 3
  • 42
  • 56
  • 6
    Simplest: add `use Carp::Always;` or run with `perl -MCarp::Always script` ... is that good? – zdim Aug 31 '17 at 23:05

2 Answers2

4

To always print a full stack trace add use Carp::Always; or run the program with

perl -MCarp::Always script

or, with bash

PERL5OPT=-MCarp::Always script

what sets up the PERL5OPT environment variable and runs the (executable) script. For one, this allows the shebang (#!) line in the script to decide which interpreter is used. If you export it (say in the shell configuration file), export PERL5OPT=-MCarp::Always, then it will be used by all Perl scripts in that shell. Thanks to ikegami for comments.

To fine-tune which particular exceptions get more attention add the $SIG{__DIE__} hook

use Carp;

BEGIN { 
    $SIG{__DIE__} = sub { 
        confess @_ if $_[0] =~ /Can't locate object method/;  #'
    };  
};

and after the hook returns "... the exception processing continues as it would have in the absence of the hook, unless ...", see %SIG in perlvar. The code above dies normally on other errors.

Thus here you can change what happens as the die is thrown, with code run right before it goes. For example, see this post for how to get all lexicals for each frame in the call stack.

Messing with this can get tricky so please read up on it. See links in this post, for instance.

zdim
  • 64,580
  • 5
  • 52
  • 81
  • Not quite. I recommended `PERL5OPT=-MCarp::Always script` There's no reason to make it apply to more than just that one script as the longer `export PERL5OPT=-MCarp::Always` + `script` might accidentally do. – ikegami Sep 01 '17 at 04:56
  • @ikegami Heh ... I use tcsh and didn't think that one can run a line just like that in bash (so I thought that you were referring to exporting it). Updated.Thank you, again (and again) – zdim Sep 01 '17 at 05:06
1

The Carp module which ships with Perl can be used to generate stack traces.

Carp provide replacements for warn and die which can be used either to simply bump the offending file and line number 1 level back up the call stack or to produce a stack trace.

In your case it sounds like you're not actually calling die - that's happening as a result of attempting to call a non-existent method. For this circumstance you can use Carp's 'verbose' mode to force a stack trace globally. There are a number of ways to enable verbose mode. It can be done via the environment, from the command line used to invoke Perl or from inside your script:

use Carp 'verbose';
Grant McLean
  • 6,898
  • 1
  • 21
  • 37