3

私は最近、コードベース全体でエラーをキャッチするためにいくつかのコードに取り組んでいます(つまり、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()もスタックトレースに含まれていません。

ええ、あなたが終了barbletch、スタックトレースを取得する前に。

$SIG{__DIE__}ハンドラーを作成します。

于 2012-11-08T01:50:41.167 に答える