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

Blessed anonymous subroutines not reliably deterministically destroyed. #17111

Open
p5pRT opened this issue Jul 25, 2019 · 3 comments
Open

Blessed anonymous subroutines not reliably deterministically destroyed. #17111

p5pRT opened this issue Jul 25, 2019 · 3 comments

Comments

@p5pRT
Copy link

p5pRT commented Jul 25, 2019

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

Searchable as RT134313$

@p5pRT
Copy link
Author

p5pRT commented Jul 25, 2019

From @demerphq

The following two one liners should output the same thing, in
particular they should both output the same thing as the second piece
of code.

This potentially could screw up code that is trying to do "ScopeExit"
type behavior. I find it particularly confusing and wrong that the
first example does not print out two "destroying lines".

$ perl -le'sub DestroyNow​::DESTROY { print "destroying $_[0] in
${^GLOBAL_PHASE}" } sub foo { my $x= bless sub {}, "DestroyNow"; undef
$x; return undef;} foo(); foo(); print "All done\n" '
All done

destroying DestroyNow=CODE(0x8bc6f8) in DESTRUCT

$ perl -le'sub DestroyNow​::DESTROY { print "destroying $_[0] in
${^GLOBAL_PHASE}" } sub foo { my $y= shift; my $x= bless sub {$y},
"DestroyNow"; undef $x; return undef;} foo(); foo(); print "All
done\n" '
destroying DestroyNow=CODE(0xf83218) in RUN
destroying DestroyNow=CODE(0xf83218) in RUN
All done

I'm told this is an optimisation, but I dont think the optimisation is
safe given this. As soon as a coderef is blessed it needs to be
treated like a closure and be distinct from any copies.

The tested Perl was 5.18.4, but I have replicated this behavior on
perl 5.24 as well. (Haven't checked blead yet.)

This is perl 5, version 18, subversion 4 (v5.18.4) built for x86_64-linux
(with 1 registered patch, see perl -V for more detail)

Copyright 1987-2013, Larry Wall

Perl may be copied only under the terms of either the Artistic License or the
GNU General Public License, which may be found in the Perl 5 source kit.

Complete documentation for Perl, including FAQ lists, should be found on
this system using "man perl" or "perldoc perl". If you have access to the
Internet, point your browser at http​://www.perl.org/, the Perl Home Page.

--
perl -Mre=debug -e "/just|another|perl|hacker/"

@p5pRT
Copy link
Author

p5pRT commented Aug 28, 2019

From @tonycoz

On Thu, 25 Jul 2019 03​:38​:34 -0700, demerphq wrote​:

The following two one liners should output the same thing, in
particular they should both output the same thing as the second piece
of code.

This potentially could screw up code that is trying to do "ScopeExit"
type behavior. I find it particularly confusing and wrong that the
first example does not print out two "destroying lines".

$ perl -le'sub DestroyNow​::DESTROY { print "destroying $_[0] in
${^GLOBAL_PHASE}" } sub foo { my $x= bless sub {}, "DestroyNow"; undef
$x; return undef;} foo(); foo(); print "All done\n" '
All done

destroying DestroyNow=CODE(0x8bc6f8) in DESTRUCT

$ perl -le'sub DestroyNow​::DESTROY { print "destroying $_[0] in
${^GLOBAL_PHASE}" } sub foo { my $y= shift; my $x= bless sub {$y},
"DestroyNow"; undef $x; return undef;} foo(); foo(); print "All
done\n" '
destroying DestroyNow=CODE(0xf83218) in RUN
destroying DestroyNow=CODE(0xf83218) in RUN
All done

I'm told this is an optimisation, but I dont think the optimisation is
safe given this. As soon as a coderef is blessed it needs to be
treated like a closure and be distinct from any copies.

The tested Perl was 5.18.4, but I have replicated this behavior on
perl 5.24 as well. (Haven't checked blead yet.)

This behaviour has been around since at least 5.6, and I expect since 5.000, so I suspect fixing it might break some code.

Fixing it would be kind of messy, if pp_anoncode sees that the CV in the pad is blessed, it would need to clone the SV, replace that in the pad and turn the CvCLONE() flag on so that future referents are cloned.

cv_clone() would have to handle cloning a CV without a pad.

Tony

@p5pRT
Copy link
Author

p5pRT commented Aug 28, 2019

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

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