Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Carp croak() fails on anon sub and package deletion #16827

Open
p5pRT opened this issue Jan 26, 2019 · 7 comments
Open

Carp croak() fails on anon sub and package deletion #16827

p5pRT opened this issue Jan 26, 2019 · 7 comments

Comments

@p5pRT
Copy link

p5pRT commented Jan 26, 2019

Migrated from rt.perl.org#133800 (status was 'open')

Searchable as RT133800$

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

From wagnerc@plebeian.com

This perlbug is in support of RT#133776.

croak() fails with numerous unitialized warnings and incorrect error
location when called from an anonymous sub in another package and if the
package (stash) that the error is thrown from has been deleted. The
problem arises from short_error_loc() iterating through the call stack
and leaving $called undefined. The corresponding code in
long_error_loc() seems to work.

I rewrote stash_deletion.t and added a new test for croak() to make it
easier to track the errors. Each test block is made to have unique
values so that the origin of any message is identifiable. I would like
to submit this file as a permanent replacement for the existing test
file.

The problem is not with the test construction because merely changing
Carp​::croak("Croak_Msg") to Carp​::confess("Croak_Msg") lets the test
pass.

Output​:
$ t/stash_deletion_new.t 2>&1
1..18
Test file t/stash_deletion_new.t, Perl v5.22.4, Carp 1.50
/usr/lib/perl5/site_perl/5.22/Carp.pm
ok 1
ok 2
ok 3
ok 4 - Confess_sub compile
ok 5 - Confess_sub execute
ok 6 - Confess_sub execute after package delete
ok 7 - Croak_sub compile
not ok 8 - Croak_sub execute
# Failed test 'Croak_sub execute'
# at t/stash_deletion_new.t line 69.
# 'Croak_Msg at t/stash_deletion_new.t line 68.
# '
# doesn't match '(?^​:^Croak_Msg at Croak_File line 3)'
Use of uninitialized value $called in hash element at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 672.
Use of uninitialized value $pkg in hash element at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 499.
Use of uninitialized value $pkg in anonymous hash ({}) at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 499.
Use of uninitialized value $class in concatenation (.) or string at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 731.
Use of uninitialized value $pkg in hash element at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 500.
Use of uninitialized value $parent in exists at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 724.
not ok 9 - Croak_sub execute after package delete
# Failed test 'Croak_sub execute after package delete'
# at t/stash_deletion_new.t line 75.
# 'Croak_Msg at t/stash_deletion_new.t line 74.
# '
# doesn't match '(?^​:^Croak_Msg at Croak_File line 3)'
ok 10
ok 11
ok 12
ok 13
ok 14
ok 15
ok 16
ok 17
ok 18
# Looks like you failed 2 tests of 18.

I also created an instrumented version of Carp.pm that illustrates how
$called is left undefined. The unanswered question is why the reported
error location is wrong. I attached the debug version and the output.
short_error_loc() either goes 1 too far or caller_info() adds 1 extra.
It should clearly report at 1 level down from what is currently
returned. Scroll down to just after the "ok 7" message, line 174, which
is the start of the output for test 8.

This failure came to light in investigating warnings​::enabled() calling
short_error_loc() and throwing warnings.

Thanks.

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

From wagnerc@plebeian.com

#!/usr/bin/env perl
use strict;
use warnings;
use Test​::More tests => 18;

use Carp;

printf "Test file %s, Perl $^V, Carp $Carp​::VERSION $INC{'Carp.pm'}\n", __FILE__;

{
## base test of die()
my $Die_sub = eval <<'EVAL_EOF';
package Die_Package;
sub {
#line 1 Die_File
  die "Die_Msg";
}
EVAL_EOF

ok(!$@​); # 1
eval { $Die_sub->() };
like($@​, qr/^Die_Msg at Die_File line 1/); # 2
{
  no strict 'refs';
  delete ${'​::'}{'Die_Package​::'};
}
eval { $Die_sub->() };
like($@​, qr/^Die_Msg at Die_File line 1/); # 3
}

######################################

{
## test of confess()
my $Confess_sub = eval <<'EVAL_EOF';
package Confess_Package;
sub {
#line 2 Confess_File
Carp​::confess("Confess_Msg");
}
EVAL_EOF

ok(!$@​); # 4
eval { $Confess_sub->() };
like($@​, qr/^Confess_Msg at Confess_File line 2/); # 5
{
  no strict 'refs';
  delete ${'​::'}{'Confess_Package​::'};
}
eval { $Confess_sub->() };
like($@​, qr/^Confess_Msg at Confess_File line 2/); # 6
}

######################################

{
## test of croak()
my $Croak_sub = eval <<'EVAL_EOF';
package Croak_Package;
sub {
#line 3 Croak_File
Carp​::croak("Croak_Msg");
}
EVAL_EOF

ok(!$@​, "Croak_sub compile"); # 7
eval { $Croak_sub->() };
like($@​, qr/^Croak_Msg at Croak_File line 3/, "Croak_sub execute"); # 8
{
  no strict 'refs';
  delete ${'​::'}{'Croak_Package​::'};
}
eval { $Croak_sub->() };
like($@​, qr/^Croak_Msg at Croak_File line 3/, "Croak_sub execute after package delete"); # 9
}

######################################

{
## test of helper package with croak()
my $Croak2_sub = eval <<'EVAL_EOF';
package CroakHelper_Package;
sub helper {
  Carp​::croak("CroakHelper_Msg");
}
package Croak2_Package;
sub {
#line 4 Croak2_File
  CroakHelper_Package​::helper();
}
EVAL_EOF

ok(!$@​); # 10
eval { $Croak2_sub->() };
like($@​, qr/^CroakHelper_Msg at Croak2_File line 4/); # 11
{
  no strict 'refs';
  delete ${'​::'}{'Croak2_Package​::'};
}
eval { $Croak2_sub->() };
like($@​, qr/^CroakHelper_Msg at Croak2_File line 4/); # 12
{
  no strict 'refs';
  delete ${'​::'}{'CroakHelper_Package​::'};
}
eval { $Croak2_sub->() };
like($@​, qr/^CroakHelper_Msg at Croak2_File line 4/); # 13
}

######################################

{
## test of helper package with confess()
# the amount of information available and how it is displayed varies quite
# a bit depending on the version of perl (specifically, what caller returns
# in that version), so there is a bit of fiddling around required to handle
# that
my $unknown_pat = qr/__ANON__​::/;
$unknown_pat = qr/$unknown_pat|\(unknown\)/
  if $] < 5.014;

my $Sub_sub = eval <<'EVAL_EOF';
package SubHelper_Package;
sub helper {
  Carp​::confess("_Msg");
}
package Sub_Package;
sub {
#line 5 Sub_File
  SubHelper_Package​::helper();
}
EVAL_EOF

ok(!$@​); # 14
eval { $Sub_sub->() };
unlike($@​, qr/$unknown_pat/); # 15
{
  no strict 'refs';
  delete ${'​::'}{'Sub_Package​::'};
}
eval { $Sub_sub->() };
like($@​, qr/$unknown_pat|Sub_Package​::/); # 16
unlike($@​, qr/$unknown_pat.*$unknown_pat/s); # 17
{
  no strict 'refs';
  delete ${'​::'}{'SubHelper_Package​::'};
}
eval { $Sub_sub->() };
like($@​, qr/(?​:$unknown_pat|SubHelper_Package​::).*(?​:$unknown_pat|Sub_Package​::)/s); # 18
}

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

From wagnerc@plebeian.com

Carp_debug.pm

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

From wagnerc@plebeian.com

1..18
Test file Carp3/t/stash_deletion_new.t, Perl v5.22.4, Carp 1.51_debug Carp/blib/lib/Carp.pm
ok 1
ok 2
ok 3
ok 4 - Confess_sub compile
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Confess_Package",
  "Confess_File",
  2,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Confess_Package"
Carp.pm​:599​: Carp/Carp​::long_error_loc() redo if Interal pkg? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Confess_Package"
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 3 2
Carp.pm​:629​: Carp/Carp​::ret_backtrace() Starting ret_backtrace `2`, `"Confess_Msg"`
Carp.pm​:674​: Carp/Carp​::ret_backtrace() ending ret_backtrace
ok 5 - Confess_sub execute
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  undef,
  "Confess_File",
  2,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:570​: Carp/Carp​::long_error_loc() $pkg not defined undef
Carp.pm​:573​: Carp/Carp​::long_error_loc() %Internal is defined, shouldn't happen? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 }
Carp.pm​:575​: Carp/Carp​::long_error_loc() re-calling
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  610,
  "Carp​::long_error_loc",
  1,
  "",
  undef,
  undef,
  1762,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 3
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  undef,
  "Confess_File",
  2,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 4
Carp.pm​:570​: Carp/Carp​::long_error_loc() $pkg not defined undef
Carp.pm​:587​: Carp/Carp​::long_error_loc() caller[2] defined, stash deleted? caller [
  undef,
  "Confess_File",
  2,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
], lvl 0
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 4 3
Carp.pm​:577​: Carp/Carp​::long_error_loc() last
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 3 2
Carp.pm​:629​: Carp/Carp​::ret_backtrace() Starting ret_backtrace `2`, `"Confess_Msg"`
Carp.pm​:674​: Carp/Carp​::ret_backtrace() ending ret_backtrace
ok 6 - Confess_sub execute after package delete
ok 7 - Croak_sub compile
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 1
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 1 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  319,
  "Carp​::shortmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Carp" caller from i 2
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Carp"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 2
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Croak_Package" caller from i 3
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 3 [
  "Croak_Package",
  "Croak_File",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Croak_Package"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Croak_Package"
Carp.pm​:752​: Carp/Carp​::short_error_loc() redo if CarpInteral called? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Croak_Package" called at i 3
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 3 [
  "Croak_Package",
  "Croak_File",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "main" caller from i 4
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 4 [
  "main",
  "Carp3/t/stash_deletion_new.t",
  68,
  "Croak_Package​::__ANON__",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "main"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "main"
Carp.pm​:752​: Carp/Carp​::short_error_loc() redo if CarpInteral called? { Carp => 1, warnings => 1 } "Croak_Package"
Carp.pm​:754​: Carp/Carp​::short_error_loc() redo if trusts( Croak_Package, main, {} )? ""
Carp.pm​:756​: Carp/Carp​::short_error_loc() redo if trusts( main, Croak_Package, { Croak_Package => [{ Croak_Package => "Croak_Package" }, []] } )? ""
Carp.pm​:758​: Carp/Carp​::short_error_loc() redo unless 0 > --lvl? -1
Carp.pm​:761​: Carp/Carp​::short_error_loc() return i - 1​: 3
Carp.pm​:681​: Carp/Carp​::ret_summary() Starting ret_summary `3`, `["Croak_Msg"]`
Carp.pm​:700​: Carp/Carp​::ret_summary() caller_info from level 4 {
  evaltext => undef,
  file => "Carp3/t/stash_deletion_new.t",
  has_args => 1,
  is_require => undef,
  line => 68,
  pack => "main",
  sub => "Croak_Package​::__ANON__",
  sub_name => "Croak_Package​::__ANON__()",
  wantarray => undef,
}
Carp.pm​:701​: Carp/Carp​::ret_summary() ending ret_summary()
not ok 8 - Croak_sub execute
# Failed test 'Croak_sub execute'
# at Carp3/t/stash_deletion_new.t line 69.
# 'Croak_Msg at Carp3/t/stash_deletion_new.t line 68.
# '
# doesn't match '(?^​:^Croak_Msg at Croak_File line 3)'
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 1
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 1 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  319,
  "Carp​::shortmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Carp" caller from i 2
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Carp"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 2
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() undef caller from i 3
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 3 [
  undef,
  "Croak_File",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:731​: Carp/Carp​::short_error_loc() $caller is not defined
Carp.pm​:733​: Carp/Carp​::short_error_loc() full caller [
  undef,
  "Croak_File",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:738​: Carp/Carp​::short_error_loc() have full caller, Carp Internal { Carp => 1, warnings => 1 }, $called "Carp", $lvl 0
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() undef called at i 3
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 3 [
  undef,
  "Croak_File",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "main" caller from i 4
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 4 [
  "main",
  "Carp3/t/stash_deletion_new.t",
  74,
  "__ANON__​::__ANON__",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "main"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "main"
Carp.pm​:752​: Carp/Carp​::short_error_loc() redo if CarpInteral called? { Carp => 1, warnings => 1 } undef
Use of uninitialized value $called in hash element at Carp/blib/lib/Carp.pm line 753.
Use of uninitialized value $called in concatenation (.) or string at Carp/blib/lib/Carp.pm line 754.
Use of uninitialized value $pkg in hash element at Carp/blib/lib/Carp.pm line 530.
Use of uninitialized value $pkg in anonymous hash ({}) at Carp/blib/lib/Carp.pm line 530.
Use of uninitialized value $class in concatenation (.) or string at Carp/blib/lib/Carp.pm line 816.
Use of uninitialized value $pkg in hash element at Carp/blib/lib/Carp.pm line 531.
Carp.pm​:754​: Carp/Carp​::short_error_loc() redo if trusts( , main, {} )? ""
Use of uninitialized value $pkg in hash element at Carp/blib/lib/Carp.pm line 530.
Use of uninitialized value $pkg in hash element at Carp/blib/lib/Carp.pm line 531.
Use of uninitialized value $called in concatenation (.) or string at Carp/blib/lib/Carp.pm line 756.
Use of uninitialized value $parent in exists at Carp/blib/lib/Carp.pm line 809.
Carp.pm​:756​: Carp/Carp​::short_error_loc() redo if trusts( main, , { "" => [{ "" => undef }, []] } )? ""
Use of uninitialized value $parent in exists at Carp/blib/lib/Carp.pm line 809.
Carp.pm​:758​: Carp/Carp​::short_error_loc() redo unless 0 > --lvl? -1
Carp.pm​:761​: Carp/Carp​::short_error_loc() return i - 1​: 3
Carp.pm​:681​: Carp/Carp​::ret_summary() Starting ret_summary `3`, `["Croak_Msg"]`
Carp.pm​:700​: Carp/Carp​::ret_summary() caller_info from level 4 {
  evaltext => undef,
  file => "Carp3/t/stash_deletion_new.t",
  has_args => 1,
  is_require => undef,
  line => 74,
  pack => "main",
  sub => "__ANON__​::__ANON__",
  sub_name => "__ANON__​::__ANON__()",
  wantarray => undef,
}
Carp.pm​:701​: Carp/Carp​::ret_summary() ending ret_summary()
not ok 9 - Croak_sub execute after package delete
# Failed test 'Croak_sub execute after package delete'
# at Carp3/t/stash_deletion_new.t line 75.
# 'Croak_Msg at Carp3/t/stash_deletion_new.t line 74.
# '
# doesn't match '(?^​:^Croak_Msg at Croak_File line 3)'
ok 10
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 1
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 1 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  319,
  "Carp​::shortmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Carp" caller from i 2
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Carp"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 2
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "CroakHelper_Package" caller from i 3
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 3 [
  "CroakHelper_Package",
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "CroakHelper_Package"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "CroakHelper_Package"
Carp.pm​:752​: Carp/Carp​::short_error_loc() redo if CarpInteral called? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "CroakHelper_Package" called at i 3
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 3 [
  "CroakHelper_Package",
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Croak2_Package" caller from i 4
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 4 [
  "Croak2_Package",
  "Croak2_File",
  4,
  "CroakHelper_Package​::helper",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Croak2_Package"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Croak2_Package"
Carp.pm​:752​: Carp/Carp​::short_error_loc() redo if CarpInteral called? { Carp => 1, warnings => 1 } "CroakHelper_Package"
Carp.pm​:754​: Carp/Carp​::short_error_loc() redo if trusts( CroakHelper_Package, Croak2_Package, {} )? ""
Carp.pm​:756​: Carp/Carp​::short_error_loc() redo if trusts( Croak2_Package, CroakHelper_Package, {
  CroakHelper_Package => [{ CroakHelper_Package => "CroakHelper_Package" }, []],
} )? ""
Carp.pm​:758​: Carp/Carp​::short_error_loc() redo unless 0 > --lvl? -1
Carp.pm​:761​: Carp/Carp​::short_error_loc() return i - 1​: 3
Carp.pm​:681​: Carp/Carp​::ret_summary() Starting ret_summary `3`, `["CroakHelper_Msg"]`
Carp.pm​:700​: Carp/Carp​::ret_summary() caller_info from level 4 {
  evaltext => undef,
  file => "Croak2_File",
  has_args => 1,
  is_require => undef,
  line => 4,
  pack => "Croak2_Package",
  sub => "CroakHelper_Package​::helper",
  sub_name => "CroakHelper_Package​::helper()",
  wantarray => undef,
}
Carp.pm​:701​: Carp/Carp​::ret_summary() ending ret_summary()
ok 11
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 1
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 1 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  319,
  "Carp​::shortmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Carp" caller from i 2
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Carp"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 2
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "CroakHelper_Package" caller from i 3
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 3 [
  "CroakHelper_Package",
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "CroakHelper_Package"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "CroakHelper_Package"
Carp.pm​:752​: Carp/Carp​::short_error_loc() redo if CarpInteral called? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "CroakHelper_Package" called at i 3
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 3 [
  "CroakHelper_Package",
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() undef caller from i 4
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 4 [
  undef,
  "Croak2_File",
  4,
  "CroakHelper_Package​::helper",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:731​: Carp/Carp​::short_error_loc() $caller is not defined
Carp.pm​:733​: Carp/Carp​::short_error_loc() full caller [
  undef,
  "Croak2_File",
  4,
  "CroakHelper_Package​::helper",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 4
Carp.pm​:738​: Carp/Carp​::short_error_loc() have full caller, Carp Internal { Carp => 1, warnings => 1 }, $called "CroakHelper_Package", $lvl 0
Carp.pm​:761​: Carp/Carp​::short_error_loc() return i - 1​: 3
Carp.pm​:681​: Carp/Carp​::ret_summary() Starting ret_summary `3`, `["CroakHelper_Msg"]`
Carp.pm​:700​: Carp/Carp​::ret_summary() caller_info from level 4 {
  evaltext => undef,
  file => "Croak2_File",
  has_args => 1,
  is_require => undef,
  line => 4,
  pack => undef,
  sub => "CroakHelper_Package​::helper",
  sub_name => "CroakHelper_Package​::helper()",
  wantarray => undef,
}
Carp.pm​:701​: Carp/Carp​::ret_summary() ending ret_summary()
ok 12
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 1
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 1 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  319,
  "Carp​::shortmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() "Carp" caller from i 2
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:748​: Carp/Carp​::short_error_loc() redo if Interal caller? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "Carp"
Carp.pm​:750​: Carp/Carp​::short_error_loc() redo if CarpInteral caller? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() "Carp" called at i 2
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 2 [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  322,
  "Carp​::shortmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() undef caller from i 3
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 3 [
  undef,
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:731​: Carp/Carp​::short_error_loc() $caller is not defined
Carp.pm​:733​: Carp/Carp​::short_error_loc() full caller [
  undef,
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:738​: Carp/Carp​::short_error_loc() have full caller, Carp Internal { Carp => 1, warnings => 1 }, $called "Carp", $lvl 0
Carp.pm​:713​: Carp/Carp​::short_error_loc() start iteration
Carp.pm​:717​: Carp/Carp​::short_error_loc() undef called at i 3
Carp.pm​:720​: Carp/Carp​::short_error_loc() full called at i 3 [
  undef,
  "(eval 20)",
  3,
  "Carp​::croak",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:724​: Carp/Carp​::short_error_loc() undef caller from i 4
Carp.pm​:727​: Carp/Carp​::short_error_loc() full caller at i 4 [
  undef,
  "Croak2_File",
  4,
  "__ANON__​::helper",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
]
Carp.pm​:731​: Carp/Carp​::short_error_loc() $caller is not defined
Carp.pm​:733​: Carp/Carp​::short_error_loc() full caller [
  undef,
  "Croak2_File",
  4,
  "__ANON__​::helper",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 4
Carp.pm​:738​: Carp/Carp​::short_error_loc() have full caller, Carp Internal { Carp => 1, warnings => 1 }, $called undef, $lvl 0
Carp.pm​:761​: Carp/Carp​::short_error_loc() return i - 1​: 3
Carp.pm​:681​: Carp/Carp​::ret_summary() Starting ret_summary `3`, `["CroakHelper_Msg"]`
Carp.pm​:700​: Carp/Carp​::ret_summary() caller_info from level 4 {
  evaltext => undef,
  file => "Croak2_File",
  has_args => 1,
  is_require => undef,
  line => 4,
  pack => undef,
  sub => "__ANON__​::helper",
  sub_name => "__ANON__​::helper()",
  wantarray => undef,
}
Carp.pm​:701​: Carp/Carp​::ret_summary() ending ret_summary()
ok 13
ok 14
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "SubHelper_Package",
  "(eval 24)",
  3,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "SubHelper_Package"
Carp.pm​:599​: Carp/Carp​::long_error_loc() redo if Interal pkg? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "SubHelper_Package"
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 3 2
Carp.pm​:629​: Carp/Carp​::ret_backtrace() Starting ret_backtrace `2`, `"_Msg"`
Carp.pm​:674​: Carp/Carp​::ret_backtrace() ending ret_backtrace
ok 15
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "SubHelper_Package",
  "(eval 24)",
  3,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "SubHelper_Package"
Carp.pm​:599​: Carp/Carp​::long_error_loc() redo if Interal pkg? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 } "SubHelper_Package"
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 3 2
Carp.pm​:629​: Carp/Carp​::ret_backtrace() Starting ret_backtrace `2`, `"_Msg"`
Carp.pm​:674​: Carp/Carp​::ret_backtrace() ending ret_backtrace
ok 16
ok 17
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  undef,
  "(eval 24)",
  3,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 3
Carp.pm​:570​: Carp/Carp​::long_error_loc() $pkg not defined undef
Carp.pm​:573​: Carp/Carp​::long_error_loc() %Internal is defined, shouldn't happen? { "Exporter" => 1, "Exporter​::Heavy" => 1, "Test2​::Util​::HashBase" => 1 }
Carp.pm​:575​: Carp/Carp​::long_error_loc() re-calling
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  610,
  "Carp​::long_error_loc",
  1,
  "",
  undef,
  undef,
  1762,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 1
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  303,
  "Carp​::longmess_heavy",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 2
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  "Carp",
  "Carp/blib/lib/Carp.pm",
  323,
  "Carp​::longmess",
  1,
  1,
  undef,
  undef,
  2018,
  "TUUUUUUUUUUT\@​UUUU\25",
  undef,
] at i 3
Carp.pm​:596​: Carp/Carp​::long_error_loc() redo if CarpInteral pkg? { Carp => 1, warnings => 1 } "Carp"
Carp.pm​:567​: Carp/Carp​::long_error_loc() full caller [
  undef,
  "(eval 24)",
  3,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
] at i 4
Carp.pm​:570​: Carp/Carp​::long_error_loc() $pkg not defined undef
Carp.pm​:587​: Carp/Carp​::long_error_loc() caller[2] defined, stash deleted? caller [
  undef,
  "(eval 24)",
  3,
  "Carp​::confess",
  1,
  undef,
  undef,
  undef,
  1762,
  "UUUUUUUUUUUUUUUUUU",
  undef,
], lvl 0
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 4 3
Carp.pm​:577​: Carp/Carp​::long_error_loc() last
Carp.pm​:602​: Carp/Carp​::long_error_loc() returning i - 1​: 3 2
Carp.pm​:629​: Carp/Carp​::ret_backtrace() Starting ret_backtrace `2`, `"_Msg"`
Carp.pm​:674​: Carp/Carp​::ret_backtrace() ending ret_backtrace
ok 18
# Looks like you failed 2 tests of 18.

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

From @jkeenan

On Sat, 26 Jan 2019 01​:00​:42 GMT, wagnerc@​plebeian.com wrote​:

This perlbug is in support of RT#133776.

croak() fails with numerous unitialized warnings and incorrect error
location when called from an anonymous sub in another package and if the
package (stash) that the error is thrown from has been deleted. The
problem arises from short_error_loc() iterating through the call stack
and leaving $called undefined. The corresponding code in
long_error_loc() seems to work.

I rewrote stash_deletion.t and added a new test for croak() to make it
easier to track the errors. Each test block is made to have unique
values so that the origin of any message is identifiable. I would like
to submit this file as a permanent replacement for the existing test
file.

The problem is not with the test construction because merely changing
Carp​::croak("Croak_Msg") to Carp​::confess("Croak_Msg") lets the test
pass.

Output​:
$ t/stash_deletion_new.t 2>&1
1..18
Test file t/stash_deletion_new.t, Perl v5.22.4, Carp 1.50
/usr/lib/perl5/site_perl/5.22/Carp.pm
ok 1
ok 2
ok 3
ok 4 - Confess_sub compile
ok 5 - Confess_sub execute
ok 6 - Confess_sub execute after package delete
ok 7 - Croak_sub compile
not ok 8 - Croak_sub execute
# Failed test 'Croak_sub execute'
# at t/stash_deletion_new.t line 69.
# 'Croak_Msg at t/stash_deletion_new.t line 68.
# '
# doesn't match '(?^​:^Croak_Msg at Croak_File line 3)'
Use of uninitialized value $called in hash element at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 672.
Use of uninitialized value $pkg in hash element at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 499.
Use of uninitialized value $pkg in anonymous hash ({}) at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 499.
Use of uninitialized value $class in concatenation (.) or string at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 731.
Use of uninitialized value $pkg in hash element at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 500.
Use of uninitialized value $parent in exists at
/usr/lib/perl5/site_perl/5.22/Carp.pm line 724.
not ok 9 - Croak_sub execute after package delete
# Failed test 'Croak_sub execute after package delete'
# at t/stash_deletion_new.t line 75.
# 'Croak_Msg at t/stash_deletion_new.t line 74.
# '
# doesn't match '(?^​:^Croak_Msg at Croak_File line 3)'
ok 10
ok 11
ok 12
ok 13
ok 14
ok 15
ok 16
ok 17
ok 18
# Looks like you failed 2 tests of 18.

I also created an instrumented version of Carp.pm that illustrates how
$called is left undefined. The unanswered question is why the reported
error location is wrong. I attached the debug version and the output.
short_error_loc() either goes 1 too far or caller_info() adds 1 extra.
It should clearly report at 1 level down from what is currently
returned. Scroll down to just after the "ok 7" message, line 174, which
is the start of the output for test 8.

This failure came to light in investigating warnings​::enabled() calling
short_error_loc() and throwing warnings.

Thanks.

So that people can play around with this, I created this branch in the repository​:

133800-carp

... in which I placed *only* the additional tests Chris Wagner provided. (The instrumented module uses a non-core library, so I can't put that in the branch yet.)

Thank you very much.

--
James E Keenan (jkeenan@​cpan.org)

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jan 26, 2019

From wagnerc@plebeian.com

Thanks for doing that James.

If if has to only use core modules, adding this code will replace Data​::Dump.

sub pp {
  require Data​::Dumper;
  no warnings "once";
  local $Data​::Dumper​::Terse = 1;
  my $x = Data​::Dumper​::Dumper(@​_);
  chomp $x;
  return $x;
}

Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants