The warnings pragma emits warnings for legal code, from a set of given categories. While the FATAL
changes them into fatal errors, it does not change how warn
works. Since it is not known how this is emitted there's a good chance that overriding the __WARN__
hook may help
local $SIG{__WARN__} = \&Carp::confess; # or just die
or you may as well drop local
just this one time.
Another thing to try is to override CORE::GLOBAL::warn
BEGIN { *CORE::GLOBAL::warn = sub { die } } # before use Module;
This affects modules as well, as will the __WARN__
signal if set in BEGIN
before modules.
Note that Carp::Always accomplishes this, and more. Also, it is normally activiated simply when running the program, with -MCarp::Always
. Thanks to ikegami for a clarification.
See warn and %SIG hash in perlvar, and this Effective Perler article.
Finally, just how many calls to each
do you have? Check them all.
It is explained in comments that prints come from XS, found via debugger, but it is still unknown what code triggers this. Then try tie
-ing the stream to a class, where a trace is triggered on relevant text. A minimal example
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;
Change to the commented out if
line so to scan prints for the text of your error message. The rest below is just a test of this. In your code you need the first two lines from main.pl
, to use
this class and tie
the stream (filehandle) to it and then all prints (to STDERR
) go by way of PRINT
above.
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 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;
Output
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
The tie
-ing class should be written far more nicely, firstly to take arguments (text to search for, stream or handle to print to). See perltie and Tie::Handle, discussions on perlmonks, posts on SO such as this one, and above all the chapter "Tying Filehandles" in Camel (3rd Ed).