我们有一些代码捕获异常,记录消息,然后调用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 $msgn";
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
模块的警告序列一遍又一遍地无限重复,吹灭了logifle。所以我们最终消灭了它。这些警告看起来是由调用Carp::longmess
触发的。另一件有趣的事情是,$@
变量似乎只是at
。它是由die添加的at
,但没有实际的错误消息或行号。
有没有人见过这个或者知道Carp
包发生了什么吗?这种情况很少见,但在过去一个月左右发生过几次,每天都有数百个这样的作业在运行。
您的代码适用于perl v5.10.1, Carp.pm
版本1.11。
但是,请注意,它所做的可能不是您所期望的:longmess
产生的回溯将显示logwrite
函数是从哪里被调用的,而不是eval
中实际错误发生的位置。
我知道这并没有回答你的实际问题,但是…既然在这种情况下显然是$msg eq 'at line '
,也许你应该通过将unless $msg eq 'at line '
添加到print ... Carp::longmess ...
语句的末尾来绕过这个问题?(我的意思是,除非有人提出一个真正的解决方案。)