【问题标题】:Infinite loop in perl Carp moduleperl Carp 模块中的无限循环
【发布时间】:2011-12-19 04:11:04
【问题描述】:

我们有一些代码可以捕获异常,记录消息,然后调用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。它作为 die 添加的at,但没有实际的错误消息或行号。

有没有人见过这个或者知道Carp 包的内容?这种情况很少见,但在过去一个月左右发生了几次,我们每天都有数百个这样的作业在运行。

【问题讨论】:

  • 在不知道您的调用堆栈是什么样子的情况下,我不确定如何重现您的错误。鲤鱼肯定已经离开了堆栈的顶部。它可能是 Carp 中的一个错误,或者是一个损坏的堆栈。 Carp 可作为 CPAN 模块使用,尝试升级吗? metacpan.org/release/Carp 另一个选择是尝试 Perl 5.8.9。
  • POSIX 可以叫鲤鱼吗?您是否通过在 longmess 上设置断点然后单步执行来调试问题?
  • 其实$@不包含at。它包含一个空字符串,或者可能是 undef。这不是那么不寻常。 Carp 无法获取文件名或行号的情况要奇怪得多。
  • @Schwern。谢谢,这是有用的信息,更多搜索。不幸的是升级不是一个简单的选择,在一个非常紧张的船上工作,任何升级都涉及到一个 QA 周期等。但是它的 SOAP::Lite 带有回调和对 LWP 的底层调用,还有几个级别的 evals。所以我想堆栈中的某些东西可能会被搞砸。不幸的是,它并不一致,正如我所说的数百次运行中的一次。虽然对于这个数据集,它是 9 中的 2。
  • @Sodved 尝试在本地安装升级后的 Carp,看看它是否修复了错误(参见 local::lib)。该错误很可能存在于 Carp 或 Perl 中,您将不得不升级或修补某些内容。

标签: perl infinite-loop carp


【解决方案1】:

您的代码在 perl v5.10.1 上适用于我,Carp.pm 版本为 1.11。

但是,请注意,它所做的可能不是您所期望的:longmess 生成的回溯将显示调用 logwrite 函数的位置,而不是 eval 中实际发生错误的位置。

【讨论】:

    【解决方案2】:

    我意识到这并不能回答您的实际问题,但是 . . .因为在这种情况下显然$msg eq 'at line ',也许您应该通过在print ... Carp::longmess ... 语句的末尾添加unless $msg eq 'at line ' 来绕过这个问题? (我的意思是,除非有人提出真正的解决方案。)

    【讨论】:

      猜你喜欢
      • 2018-03-20
      • 2017-04-27
      • 1970-01-01
      • 1970-01-01
      • 2010-12-07
      • 2011-02-03
      • 2013-04-25
      • 2012-07-21
      • 1970-01-01
      相关资源
      最近更新 更多