Получение следов стека в Perl?
Как получить трассировки стека в Perl?
Ответы
Ответ 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";
}