Подтвердить что ты не робот

Получение следов стека в Perl?

Как получить трассировки стека в Perl?

4b9b3361

Ответ 1

Существует множество полезных инструментов для ядра и CPAN для создания трассировки стека (как показывают другие ответы). Однако, если вы хотите перевернуть свой собственный, посмотрите caller. Вы можете использовать это, чтобы спуститься по стеку и посмотреть, что именно происходит.

Ответ 2

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

Запустив этот script, вы получите:

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

Запустив этот script, но перенаправляя 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

Для отладочных задач мне нравится Carp:: Always.

perl -MCarp::Always my_script.pl

Ответ 4

Простой способ использования 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";
}