perl Carp模块中的无限循环
我们有一些代码捕获异常,记录消息,然后调用 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
包是怎么回事?这种情况很少见,但在过去一个月左右的时间里发生过几次,而且我们每天都有数百个这样的作业在运行。
We have some code which catches an exception, logs the message and then calls Carp::longmess
to get the stacktrace.
So a simplified view of what we are doing is:
eval { <some SOAP::Lite stuff> };
if( my $err = $@ )
{
logwrite( "Caught Error: $err" );
}
The logwrite function is essentially:
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";
}
But in the log I am seeing:
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.
...
And that sequence of warnings from the Carp/Heavy.pm
module repeats over and over again indefiniately, blowing out the logifle. So we eventually kill it off. These warnings look like they're being triggered by the call to Carp::longmess
. The other intersting thing here is the $@
variable appears to just be at
. It as the at
added by die, but no actual error message or line number.
Has anyone seen this before or have any idea what's coing on with the Carp
package? This is rare, but has happenned a handful of times over the past month or so, and we have hundreds of these jobs running every day.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
你的代码适用于我的 perl v5.10.1,
Carp.pm
版本 1.11。但是,请注意,它所做的可能不是您所期望的:
longmess
生成的回溯将显示logwrite
函数的调用位置,而不是内部实际发生错误的位置评估
。Your code works for me on perl v5.10.1, with
Carp.pm
version 1.11.However, note that what it does is perhaps not what you expect: the backtrace produced by
longmess
will show where thelogwrite
function was called from, not where the actual error occurred inside theeval
.我意识到这并不能回答你的实际问题,但是。 。 。因为在这种情况下显然是
$msg eq 'at line '
,也许您应该通过将unless $msg eq 'at line '
附加到的末尾来绕过这个问题code>print ... Carp::longmess ...
语句? (我的意思是,除非有人提出真正的解决方案。)I realize this doesn't answer your actual question, but . . . since apparently
$msg eq 'at line '
in this case, maybe you should just bypass the issue by tackingunless $msg eq 'at line '
onto the end of theprint ... Carp::longmess ...
statement? (I mean, unless someone proposes a real solution.)