This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Fix assertion failure with undef &my_sub/&anon
authorFather Chrysostomos <sprout@cpan.org>
Mon, 15 Sep 2014 21:28:22 +0000 (14:28 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Mon, 15 Sep 2014 21:49:18 +0000 (14:49 -0700)
commit7fcb412668d2fa3df241491ee985370bed3a3018
tree04c296872e03115c1f4672f5109a6e44e3fb65a6
parenta6de8fc77bb1ac413d5a5868104c8b2c555ce6d8
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.
pp.c
t/op/anonsub.t
t/op/lexsub.t