Getting stack traces in Perl?
Solution 1
There are many useful, core and CPAN based tools to generate a stack trace (as other answers illustrate.) However, if you want to roll your own, check out the caller
builtin. You can use this to walk down the stack and see exactly what's happening.
Solution 2
For debugging needs, I like Carp::Always.
perl -MCarp::Always my_script.pl
Solution 3
Carp::confess
(from use Carp;
) will give you a full stack trace as part of the error. If you just need it as part of something failing, confess
is all you really need.
Per comments, here's output of various Carp
functions:
use strict;
use warnings;
use Carp qw/longmess cluck confess/;
sub foo {
&bar;
}
sub bar {
&baz;
}
sub baz {
shift->();
}
my %tests = (
'longmess' => sub { print longmess 'longmess' },
'cluck' => sub { cluck 'using cluck' },
'confess' => sub { confess 'using confess' },
);
while (my ($name, $sub) = each %tests) {
print "$name - before eval:\n";
eval {
foo($sub);
};
print "$name - before if:\n";
if ($@) {
print "caught: $@";
}
print "$name - done\n\n";
}
Running this script, you get:
longmess - before eval: longmess at - line 14 main::baz called at - line 10 main::bar called at - line 6 main::foo('CODE(0x183a4d0)') called at - line 26 eval {...} called at - line 25 longmess - before if: longmess - done confess - before eval: confess - before if: caught: using confess at - line 20 main::__ANON__() called at - line 14 main::baz called at - line 10 main::bar called at - line 6 main::foo('CODE(0x183a3e0)') called at - line 26 eval {...} called at - line 25 confess - done cluck - before eval: using cluck at - line 19 main::__ANON__() called at - line 14 main::baz called at - line 10 main::bar called at - line 6 main::foo('CODE(0x183a434)') called at - line 26 eval {...} called at - line 25 cluck - before if: cluck - done
Running this script but redirecting STDOUT (thus showing what gets printed on STDERR), you get:
using cluck at - line 19 main::__ANON__() called at - line 14 main::baz called at - line 10 main::bar called at - line 6 main::foo('CODE(0x183a434)') called at - line 26 eval {...} called at - line 25
Solution 4
Easy way using caller
.
This code does not use any additional module. Just include it where needed.
my $i = 1;
print "Stack Trace:\n";
while ( (my @call_details = (caller($i++))) ){
print $call_details[1].":".$call_details[2]." in function ".$call_details[3]."\n";
}
Related videos on Youtube
Comments
-
Timmy almost 2 years
How do I get stack traces in Perl?
-
nurp almost 6 years
perl -d script.pl
DB<1> t 50
Trace = on (to level 51)
DB<2> T
-
-
ysth about 14 yearsThat sends the stack trace and error to STDERR; if you need to capture it, directly use the underlying Carp::longmess(). And Carp::cluck is like confess but dies afterwards.
-
mob about 14 yearsI think that's backwards --
cluck
is a warn with a stack trace andconfess
is a die. -
jrockway about 14 yearsUh, or use
Devel::StackTrace
. -
Robert P about 14 yearsThat's a fine, other option. But it requires an external module, which a may or may not find appealing. Why not just post that as an answer, instead of downvoting?
-
brianegge almost 11 yearsI seem to need to do -MCarp=verbose
-
x-yuri almost 5 yearsYou can find an example of using
caller
in this answer.