This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Prevent destructors called from gp_free from seeing freed SVs
perl5.13.9 -e 'local *foo; $foo = bless[]; (); DESTROY { use Devel::Peek; Dump $foo; }'
This prints:
SV = UNKNOWN(0xff) (0x8044dc) at 0x8044e0
REFCNT = 0
FLAGS = ()
If I do anything with $foo inside the destructor, such as
‘local $foo’, it crashes, of course.
gp_free (called when *foo is being unlocalised on scope exit) does
SvREFCNT_dec(gp->gp_xv) on each of its slots.
SvREFCNT_dec(gp->gp_sv) lowers the refcount of $foo to zero, which
causes the object it references to be destroyed, too. The objects
destructor sees the same $foo still there in the typeglob.
This commit changes gp_free to use a loop, the way S_hfreeentries
(in hv.c) does, checking that everything has been freed before exit-
ing the loop.
(The one-liner above is a reduced version of
perl -MWWW::Scripter -e '$w = new WWW::Scripter; $w->use_plugin(JavaScript); $w->get(q|data:text/html,<a href onclick="throw new Error("XMLHttpRequest")">|); $w->document->links->[0]->click'
which involved *@ and a destructor localising $@.)