如何在Perl中获取堆栈跟踪?
答案 0 :(得分:33)
Carp::confess
(来自use Carp;
)将为您提供完整的堆栈跟踪作为错误的一部分。如果你只需要它作为失败的一部分,confess
就是你真正需要的。
根据评论,这里是各种Carp
函数的输出:
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";
}
运行此脚本,您将获得:
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
运行此脚本但重定向STDOUT(从而显示在STDERR上打印的内容),您得到:
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
答案 1 :(得分:32)
对于调试需求,我喜欢Carp::Always。
perl -MCarp::Always my_script.pl
答案 2 :(得分:16)
有许多有用的,基于核心和基于CPAN的工具来生成堆栈跟踪(正如其他答案所示)。但是,如果你想自己推出,请查看caller
内置版。您可以使用它来向下走,看看究竟发生了什么。
答案 3 :(得分:9)
使用caller
的简便方法。
此代码不使用任何其他模块。只需将它包含在需要的地方。
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";
}