diff options
author | Father Chrysostomos <sprout@cpan.org> | 2014-09-15 14:28:22 -0700 |
---|---|---|
committer | Father Chrysostomos <sprout@cpan.org> | 2014-09-15 14:49:18 -0700 |
commit | 7fcb412668d2fa3df241491ee985370bed3a3018 (patch) | |
tree | 04c296872e03115c1f4672f5109a6e44e3fb65a6 /t/op/lexsub.t | |
parent | a6de8fc77bb1ac413d5a5868104c8b2c555ce6d8 (diff) | |
download | perl-7fcb412668d2fa3df241491ee985370bed3a3018.tar.gz |
Fix assertion failure with undef &my_sub/&anon
$ ./perl -Ilib -le 'use experimental lexical_subs; my sub x; undef &x;'
Assertion failed: (isGV_with_GP(_gvname_hek)), function Perl_leave_scope, file scope.c, line 1035.
Abort trap: 6
pp_undef undefines a subroutine via cv_undef, which wipes out the
name, and then restores the name again afterwards.
For subs with GVs, it would call CvGV_set afterwards with the same gv.
But cv_undef could have freed the GV, if the CV held the only refer-
ence count.
I caused this for lexical subs a few commits ago in ae77754ae (because
CvGV will always return non-null; in fact the CvNAME_HEK code in
pp_undef is no longer exercised, but I will address that soon).
For anonymous subs it is older:
$ perl5.14.4 -e '$_ = sub{}; delete $::{__ANON__}; undef &$_; use Devel::Peek; Dump $_'
SV = IV(0x7fed9982f9c0) at 0x7fed9982f9d0
REFCNT = 1
FLAGS = (ROK)
RV = 0x7fed9982f9e8
SV = PVCV(0x7fed9982e290) at 0x7fed9982f9e8
REFCNT = 2
FLAGS = (PADMY,WEAKOUTSIDE,CVGV_RC)
COMP_STASH = 0x7fed99806b68 "main"
ROOT = 0x0
GVGV::GV = 0x7fed9982fa48Assertion failed: (isGV_with_GP(_gvname_hek)), function Perl_do_gvgv_dump, file dump.c, line 1477.
Abort trap: 6
(Probably commit 803f2748.)
Presumably that could be made to crash in other ways than introspec-
tion, but it is much harder.
This commit fixes the problem by fiddling with reference counts. But
this is only a temporary fix. I think I plan to stop cv_undef from
removing the name (gv/hek) when called from pp_undef.
Diffstat (limited to 't/op/lexsub.t')
-rw-r--r-- | t/op/lexsub.t | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/t/op/lexsub.t b/t/op/lexsub.t index 1efcf1c336..d2edb79bab 100644 --- a/t/op/lexsub.t +++ b/t/op/lexsub.t @@ -7,7 +7,7 @@ BEGIN { *bar::is = *is; *bar::like = *like; } -plan 133; +plan 135; # -------------------- Errors with feature disabled -------------------- # @@ -376,6 +376,10 @@ like runperl( 'state subs and DB::sub under -d' ); } +# This used to fail an assertion, but only as a standalone script +is runperl(switches => ['-lXMfeature=:all'], + prog => 'state sub x {}; undef &x; print defined &x', + stderr => 1), "\n", 'undefining state sub'; # -------------------- my -------------------- # @@ -719,6 +723,10 @@ pass "pad taking ownership once more of packagified my-sub"; 'my subs and DB::sub under -d' ); } +# This used to fail an assertion, but only as a standalone script +is runperl(switches => ['-lXMfeature=:all'], + prog => 'my sub x {}; undef &x; print defined &x', + stderr => 1), "\n", 'undefining my sub'; # -------------------- Interactions (and misc tests) -------------------- # |