3

我最近一直在编写一些代码来捕获整个代码库中的错误(IE 在我们的 Perl 代码的最顶层执行 try/catch)。令我苦恼的是,我发现 Perl 堆栈跟踪省略了堆栈帧!呸!我正在寻找这些堆栈帧消失的原因。caller() 的文档说堆栈帧可以“优化掉”。但实际上,让他们离开真是太烦人了。有没有办法诱使 Perl 包含它们?这样做会有性能损失吗?下面是一个简单的例子。如您所见,堆栈跟踪中既不包含 bar() 也不包含 bletch()。一个可悲的遗漏导致我不得不手动跟踪代码。

感激地收到任何见解。

伦纳德

这是 foo.pl

use strict;
use warnings;

use Devel::StackTrace;
use Try::Tiny;

foo();

sub foo {
    print "In foo\n";
    try {
        bar();
    }
    catch {
        my $trace = Devel::StackTrace->new();
        print $trace->as_string;
    };
}

sub bar {
    print "In bar\n";
    bletch();
    my $more_stuff = 123;
    return $more_stuff;
}

sub bletch {
    print "In bletch\n";
    my $not_so_defined;
    $not_so_defined->barf();
    print "Unlikely to be printed\n";

}

这是运行 foo.pl 时打印的内容:

In foo
In bar
In bletch
Trace begun at foo.pl line 17
main::__ANON__('Can\'t call method "barf" on an undefined value at ./foo.pl line 32.^J') called at /vcm/home/apps/perl-5.12.1/lib/site_perl/5.12.1/Try/Tiny.pm line 100
Try::Tiny::try('CODE(0xf503a0)', 'Try::Tiny::Catch=REF(0x1035ca0)') called at foo.pl line 19
main::foo at foo.pl line 9
4

2 回答 2

4

在我看来,好像没有。至少,不会缺少在调用堆栈中创建更深的堆栈帧,例如在错误点,或者使用不那么笨拙的 try/catch 实现。

Try::Tiny 只是一个非常薄的eval. 这意味着,它基本上评估try子然后运行catch子如果$@是真的。当catch子程序运行时,try“块”已经返回并且堆栈帧已经消失。没有优化掉——只是消失了。的eval返回已经杀死了它正在评估的堆栈帧。您真正剩下的只是$@.

于 2012-11-08T00:54:30.550 回答
3

下面是一个简单的例子。如您所见,堆栈跟踪中既不包含 bar() 也不包含 bletch()。

是的,因为您已经退出bar并且bletch在获取堆栈跟踪之前。

创建一个$SIG{__DIE__}处理程序。

于 2012-11-08T01:50:41.167 回答