Бесконечный цикл в модуле Perl Carp - PullRequest
4 голосов
/ 01 ноября 2011

У нас есть некоторый код, который перехватывает исключение, регистрирует сообщение и затем вызывает Carp::longmess, чтобы получить трассировку стека.

Итак, упрощенное представление о том, что мы делаем:

eval { <some SOAP::Lite stuff> };
if( my $err = $@ )
{
    logwrite( "Caught Error: $err" );
}

Функция logwrite по существу:

sub logwrite($)
{
    my $msg = $_[0];
    my($pkg,$fil,$lin)=caller;
    my $timestamp = POSIX::strftime(...);
    print STDERR "$timestamp $fil/$lin $msg\n";
    print STDERR "$timestamp $fil/$lin Stack trace:\n" . Carp::longmess . "\n";
}

Но в журнале я вижу:

20111030 Module.pm/42 Caught Error: at  line
Use of uninitialized value in caller at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 22.
Use of uninitialized value in string eq at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 91.
Use of uninitialized value in numeric lt (<) at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 200.
Use of uninitialized value in pattern match (m//) at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 55.
Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 55.
Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 142.
Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 142.
Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 142.
Use of uninitialized value in concatenation (.) or string at /usr/lib/perl5/5.8.8/Carp/Heavy.pm line 142.
...

И эта последовательность предупреждений от модуля Carp/Heavy.pm повторяется снова и снова, бесконечно, выдувая логику. Таким образом, мы в конечном итоге убить его. Эти предупреждения выглядят так, как будто они вызваны звонком на Carp::longmess. Другая интересная вещь здесь - это переменная $@, которая выглядит просто как at. Это как at, добавленное die, но без фактического сообщения об ошибке или номера строки.

Кто-нибудь видел это раньше или есть идеи, что происходит с пакетом Carp? Это редко, но случалось несколько раз за последний месяц или около того, и у нас есть сотни таких заданий каждый день.

Ответы [ 2 ]

1 голос
/ 01 ноября 2011

Ваш код работает для меня на Perl v5.10.1, с Carp.pm версия 1.11.

Однако обратите внимание, что то, что он делает, возможно, не то, что вы ожидаете: обратная трассировка, создаваемая longmess, покажет, откуда была вызвана функция logwrite, а не где произошла фактическая ошибка внутри eval.

0 голосов
/ 01 ноября 2011

Я понимаю, что это не отвечает на ваш актуальный вопрос, но. , , поскольку, очевидно, $msg eq 'at line ' в этом случае, может быть, вам следует просто обойти проблему, прикрепив unless $msg eq 'at line ' к концу оператора print ... Carp::longmess ...? (Я имею в виду, если кто-то не предложит реальное решение.)

...