Skip to content

Commit

Permalink
Undeffing a gv in DESTROY triggered by undeffing the same gv
Browse files Browse the repository at this point in the history
$ ./perl -Ilib -e 'sub foo{} bless \&foo; DESTROY { undef *foo } undef *foo'
Attempt to free unreferenced glob pointers, Perl interpreter: 0x7fd6a3803200 at -e line 1.

Lowering the reference count on the glob pointer only after freeing
the contents fixes this.
  • Loading branch information
Father Chrysostomos committed Nov 12, 2013
1 parent 5deb134 commit 4571f4a
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
4 changes: 3 additions & 1 deletion gv.c
Expand Up @@ -2351,9 +2351,10 @@ Perl_gp_free(pTHX_ GV *gv)
pTHX__FORMAT pTHX__VALUE);
return;
}
if (--gp->gp_refcnt > 0) {
if (gp->gp_refcnt > 1) {
if (gp->gp_egv == gv)
gp->gp_egv = 0;
gp->gp_refcnt--;
GvGP_set(gv, NULL);
return;
}
Expand Down Expand Up @@ -2411,6 +2412,7 @@ Perl_gp_free(pTHX_ GV *gv)
}
}

gp->gp_refcnt--;
Safefree(gp);
GvGP_set(gv, NULL);
}
Expand Down
17 changes: 16 additions & 1 deletion t/op/gv.t
Expand Up @@ -12,7 +12,7 @@ BEGIN {

use warnings;

plan( tests => 258 );
plan( tests => 259 );

# type coercion on assignment
$foo = 'foo';
Expand Down Expand Up @@ -947,6 +947,21 @@ ok eval {
'no error when gp_free calls a destructor that assigns to the gv';
}

# This is a similar test, for destructors seeing a GV without a reference
# count on its gp.
sub undefine_me_if_you_dare {}
bless \&undefine_me_if_you_dare, "Undefiner";
sub Undefiner::DESTROY {
undef *undefine_me_if_you_dare;
}
{
my $w;
local $SIG{__WARN__} = sub { $w .= shift };
undef *undefine_me_if_you_dare;
is $w, undef,
'undeffing a gv in DESTROY triggered by undeffing the same gv'
}

# *{undef}
eval { *{my $undef} = 3 };
like $@, qr/^Can't use an undefined value as a symbol reference at /,
Expand Down

0 comments on commit 4571f4a

Please sign in to comment.