【问题标题】:Can't disable stack trace in Carp::croak() for some reason由于某种原因,无法在 Carp::croak() 中禁用堆栈跟踪
【发布时间】:2012-08-09 08:27:40
【问题描述】:

根据 Carp 模块文档,croak() 不应产生任何堆栈跟踪,除非 $Carp::Verbose 评估为真。但出于某种原因,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

【问题讨论】:

    标签: perl


    【解决方案1】:

    Carp 的其中一个规则是:将堆栈跟踪的哪一帧用于错误消息:

    1. 从包到自身的任何调用都是安全的。

    由于您的代码不使用除main 之外的任何包,并且由于另一个规则是Carp 包本身是安全的,所以Carp 无法决定将哪一行代码用于其错误消息,因此它会踢出并打印出整个堆栈跟踪。

    哦,它实际上在Carp perldoc 中:

    他们所做的是在调用堆栈中搜索一个函数调用堆栈,其中没有被告知不应该有错误。 如果每个调用都标记为安全,它们会放弃并提供完整的堆栈回溯。

    Carp::short_error_loc 函数中的这一行是你的确凿证据:

    return 0 unless defined($caller);    # What happened?
    

    【讨论】:

    • 我找到了关于Carp vs warn/die 问题的以下答案,事实上,Damian Conway 在他的 PBP 书中建议使用carp 而不是warn。所以我想知道在main 包中(即在脚本中)使用warn/die 并仅在模块中使用carp/croak 是一个好习惯吗?
    • @DimaChumak:是的,你应该在脚本中使用warn / die,在模块中使用carp/croak
    【解决方案2】:

    一半的答案:它与代码都在同一个包中有关。如果您从不同的包调用入口点,croak 将按预期工作。

    【讨论】:

      猜你喜欢
      • 2022-11-12
      • 1970-01-01
      • 1970-01-01
      • 2013-03-02
      • 2014-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多