根据Carp模块文档,croak()不应产生任何堆栈跟踪,除非$Carp :: Verbose的计算结果为true.但是对于某些原因,croak()在我的环境中总是表现得像confess(),即总是打印堆栈跟踪,即使它不应该…
这是一个测试脚本:
#!/usr/bin/perl use Modern::Perl; use Carp; sub func { say "Carp::Verbose = $Carp::Verbose"; croak "There should be no stack trace after this message!"; } sub main { func(); } main;
这是它在我的系统上产生的结果:
$./croak Carp::Verbose = 0 There should be no stack trace after this message! at ./croak line 8 main::func() called at ./croak line 13 main::main() called at ./croak line 16
也许有人遇到过这个问题或有任何关于根本原因的线索?
以下是有关我的环境的一些信息:
Ubuntu 12.04 LTS Linux 3.2.0-27-generic x86_64 perl 5,version 14,subversion 2 (v5.14.2) built for x86_64-linux-gnu-thread-multi
我在SL6系统上也遇到了同样错误的行为:
Scientific Linux SL release 6.3 (Carbon) kernel-2.6.32-279.1.1.el6.x86_64 perl,v5.10.1 (*) built for x86_64-linux-thread-multi
解决方法
用于错误消息的堆栈跟踪帧的Carp规则之一是:
- Any call from a package to itself is safe.
由于你的代码不使用除main之外的任何软件包,并且由于另一个规则是Carp软件包本身是安全的,因此Carp无法确定用于其错误消息的代码行,因此它会打包并打印出整个堆栈跟踪.
哦,它实际上存在于Carp perldoc中:
What they do is search the call-stack for a function call stack where thay have not been told that there shouldn’t be an error. If every call is marked safe,they give up and give a full stack backtrace instead.
Carp :: short_error_loc函数中的这一行是你的吸烟枪:
return 0 unless defined($caller); # What happened?