Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何确定perl警告的位置-插入后在哈希上使用each()_Perl - Fatal编程技术网

如何确定perl警告的位置-插入后在哈希上使用each()

如何确定perl警告的位置-插入后在哈希上使用each(),perl,Perl,我有一个相当大的perl程序,用PAR::Packer打包成一个可执行文件。它使用了相当多的模块 通常,当perl给我一个警告时,比如使用未定义的值,它会打印错误的位置,然后很容易深入并调试它 然而,我现在面临一个错误(我想是在5.22中引入的),当这种情况发生时,我得不到任何位置: 插入后对哈希使用each()而不重置哈希迭代器会导致未定义的行为,Perl解释器:0xa94010 我尝试设置use warnings FATAL=>'all',但没有任何变化,程序不会消亡 也许它来自一个模块?还

我有一个相当大的perl程序,用PAR::Packer打包成一个可执行文件。它使用了相当多的模块

通常,当perl给我一个警告时,比如使用未定义的值,它会打印错误的位置,然后很容易深入并调试它

然而,我现在面临一个错误(我想是在5.22中引入的),当这种情况发生时,我得不到任何位置:

插入后对哈希使用each()而不重置哈希迭代器会导致未定义的行为,Perl解释器:0xa94010

我尝试设置
use warnings FATAL=>'all',但没有任何变化,程序不会消亡


也许它来自一个模块?还有什么方法可以确定警告的位置呢?

我想您可以使用诊断或splain。我已经使用了诊断,如果我们无法跟踪产生警告的位置,它会有所帮助

您只需将行
置于使用诊断在您的代码中就是这样。您可以在PerlMaven站点找到对此的详细解释-

谢谢。

pragma从一组给定的类别中发出法律代码警告。虽然
FATAL
会将它们更改为致命错误,但它不会更改
warn
的工作方式。由于不知道这是如何发出的,因此重写
\uuuu WARN\uuuu
钩子可能会有所帮助

local $SIG{__WARN__} = \&Carp::confess;   # or just die
或者你也可以只在这一次删除
local

另一件要尝试的事情是覆盖

这也会影响模块,如果在模块之前的
开始
中设置了
警告
信号,也会影响模块

请注意,它可以实现这一点,甚至更多。此外,它通常在运行程序时被激活,使用
-MCarp::Always
。谢谢你的澄清

看和,还有这个

最后,您有多少次对
的调用?全部检查一下


注释中解释了打印来自通过调试器找到的XS,但仍然不知道是什么代码触发了这一点。然后尝试将流绑定到一个类,在该类中相关文本上触发跟踪。最简单的例子

TraceError.pm

package TraceError;
use warnings;
use strict;
use Carp qw(longmess confess);

sub TIEHANDLE { bless {} }

sub PRINT {
    my $self = shift;
    my $prn = join '', @_;

    # print "STDERR: $prn";   # TEST
    print @_;                 # or   print STDERR @_;

    # if ($prn =~ /\QUse of each() on hash after insertion/)  # in your code
    if ($prn =~ /TRACE/) {                                    # test
        print longmess(@_);
    }
}

1;
package Pack;
use warnings;
use strict;

use Exporter qw(import);
our @EXPORT_OK = qw(issue_warn);

sub new { bless {}, $_[0] }

sub issue_warn { 
    my $self = shift;
    warn "In ", __PACKAGE__, ", issue_warn(@_).";
}

1;
更改为注释掉的
if
行,以便扫描打印的错误消息文本。下面剩下的只是一个测试。在您的代码中,您需要从
main.pl
开始的前两行,以
使用该类并
将流(filehandle)绑定到它,然后所有打印(到
STDERR
)通过上面的
PRINT
进行

main.pl

use TraceError;
tie *STDERR,'TraceError';

use warnings;
use strict;
use Pack qw(issue_warn);

call_for_err(Pack->new);

sub call_for_err {
    my ($pck) = @_; 
    $pck->issue_warn("TRACE call_for_err()");  # should catch this print
    $pck->issue_warn("from call_for_err()");   # but not this
};
Pack.pm

package TraceError;
use warnings;
use strict;
use Carp qw(longmess confess);

sub TIEHANDLE { bless {} }

sub PRINT {
    my $self = shift;
    my $prn = join '', @_;

    # print "STDERR: $prn";   # TEST
    print @_;                 # or   print STDERR @_;

    # if ($prn =~ /\QUse of each() on hash after insertion/)  # in your code
    if ($prn =~ /TRACE/) {                                    # test
        print longmess(@_);
    }
}

1;
package Pack;
use warnings;
use strict;

use Exporter qw(import);
our @EXPORT_OK = qw(issue_warn);

sub new { bless {}, $_[0] }

sub issue_warn { 
    my $self = shift;
    warn "In ", __PACKAGE__, ", issue_warn(@_).";
}

1;
输出

In Pack, issue_warn(TRACE, call_for_err()). at Pack.pm line 12. at Pack.pm line 12. Pack::issue_warn('Pack=HASH(0x7016e8)', 'TRACE call_for_err()') called at main.pl line 12 main::call_for_err('Pack=HASH(0x7016e8)') called at main.pl line 8 在包中,发出\u警告(跟踪,调用\u以获取\u err()。下午12点12分。 下午12点12分。 Pack::在main.pl第12行调用发出警告('Pack=HASH(0x7016e8)','TRACE call_for_err()') main::在main.pl第8行调用\u err('Pack=HASH(0x7016e8)')时调用\u
tie
-ing类的编写应该更加精巧,首先是为了获取参数(要搜索的文本、要打印的流或句柄)。请参阅和,讨论,帖子等,尤其是骆驼(第三版)中的“捆绑文件句柄”一章

你应该有一个行号

>perl a.pl
a
Use of each() on hash after insertion without resetting hash iterator results in undefined behavior, Perl interpreter: 0xe688d8 at a.pl line 8.
b
c
Carp::总是将其扩展到堆栈跟踪中

>perl -MCarp::Always a.pl
a
Use of each() on hash after insertion without resetting hash iterator results in undefined behavior, Perl interpreter: 0x1e88d8 at a.pl line 8.
        main::g() called at a.pl line 15
        main::f() called at a.pl line 18
c
b

运行非打包版本?我刚刚测试了非打包版本,它也不会打印出行。所做的只是获取警告并在
perldoc perldiag
的源代码中查找它,然后显示该文本。这无助于在perl源代码和模块中找到警告的来源。
-MCarp::Always
基本上就是这样做的,还有更多:)@ikegami我知道了,谢谢!源代码非常漂亮,有几十行:)因此
-MCarp::Always
也没有帮助。仍然没有位置信息。至于
每次调用
我都会查看代码;没有
每个
在所有的
foreach
看起来都没有可疑之处。我倾向于一些模块/XS代码(特别是因为通常情况下,如果它发生在我的代码中,我会得到正确的位置)。@VitSpinka OK。您是否尝试过使用
CORE::GLOBAL::warn
?这会改变每个
warn
的工作方式,而
Carp::Always
会做一些不同的事情。以防万一--这是在
STDERR
还是
STDOUT
上出现的?(如果您将输出重定向到一个文件,它是否会在控制台上打印?)我将研究更多的方法。@VitSpinka源代码可能正在使用
CORE::warn
,这正是阻止这些游戏的方法,在这种情况下,这不会有帮助。或者,更有可能的是,在发出
warn
后,线路信息以其他方式被剥离。