2010-03-02 120 views

回答

14

有许多有用的,cor e和基于CPAN的工具来生成堆栈跟踪(如其他答案所示)。但是,如果您想自己推出,请查看caller内置。您可以使用它沿着堆栈走,看看到底发生了什么。

+4

呃,或者使用'Devel :: StackTrace'。 – jrockway 2010-03-04 09:59:32

+5

这是一个很好的选择。但它需要一个外部模块,它可能会或可能不会吸引人。为什么不把它作为答案发布,而不是downvoting? – 2010-03-04 19:03:13

31

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 ([email protected]) { 
     print "caught: [email protected]"; 
    } 
    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 
+3

将堆栈跟踪和错误发送到STDERR;如果你需要捕获它,直接使用底层的Carp :: longmess()。 和鲤鱼:: cluck就像是承认,但之后死亡。 – ysth 2010-03-03 01:13:44

+2

我认为这是倒退 - 'cluck'是一个堆栈跟踪警告和'confess'是一个死亡。 – mob 2010-03-03 02:32:04

+0

错,是的,那是倒退 – ysth 2010-03-04 06:01:22

31

对于调试需求,我喜欢Carp::Always

perl -MCarp::Always my_script.pl 
+1

我似乎需要做--MCarp =详细 – brianegge 2013-06-17 21:08:25

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"; 
}