在Perl中获取堆栈跟踪?

Tim*_*mmy 22 perl stack-trace

如何在Perl中获得堆栈跟踪?

Rob*_*t P 34

Carp::confess(from 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";
}
Run Code Online (Sandbox Code Playgroud)

运行此脚本,您将获得:

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

  • 这会将堆栈跟踪和错误发送到STDERR; 如果你需要捕获它,直接使用底层的Carp :: longmess().Carp :: cluck就像忏悔但后来死了. (3认同)
  • 我认为这是倒退 - "cluck"是一个带有堆栈跟踪的警告,而'confess`是一个死亡. (2认同)

dao*_*oad 32

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

perl -MCarp::Always my_script.pl
Run Code Online (Sandbox Code Playgroud)


Rob*_*t P 17

有许多有用的,基于核心和基于CPAN的工具来生成堆栈跟踪(正如其他答案所示).但是,如果您想自己滚动,请查看caller内置命令.您可以使用它来向下走,看看究竟发生了什么.

  • 这是一个很好的,另一种选择.但它需要一个外部模块,可能会或可能不会吸引人.为什么不把它作为答案发布,而不是低估? (7认同)
  • 呃,或者使用`Devel :: StackTrace`. (5认同)

Tha*_*ama 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";
}
Run Code Online (Sandbox Code Playgroud)