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
memory leak: if($foo++){} and = overloading #6090
Comments
From khkramer@allafrica.comFrom: kwindla@allafrica.com Hi, There appears to be a scoping problem that certain kinds of operator The constructions: while ( $foo++ ) {} lead to $foo's reference count being high by one, if $foo is an object This bug is easily reproduced -- I have attached a test case below. I Just to clarify, I've carefully read all the information I can find on my $copy = $foo; $foo++; This bug, while admittedly in a very obscure corner of Perl, turns out I apologize for not having a patch. I've gotten lost in the perl 5.8.0 With sincere thanks, package Toy_Iterator; use overload sub new { sub set { $_[0]->{_i} = $_[1] } package main; my $a = Toy_Iterator->new ( 2 ); ## ## print "\n"; Dump $a; print "\n"; print "---- script finished (should have already gc'ed) ---\n"; Flags: Site configuration information for perl v5.8.0: Configured by khkramer at Thu Nov 14 13:37:07 EST 2002. Summary of my perl5 (revision 5.0 version 8 subversion 0) configuration: Locally applied patches: @INC for perl v5.8.0: Environment for perl v5.8.0: |
From goldbb2@earthlink.netkhkramer@allafrica.com (via RT) wrote:
Your copy constructor (the '=' operator) doesn't appear to do anything. Could this be the source of your problems? (Try replacing that line with: -- |
From kwindla@allafrica.comBenjamin Goldberg (via RT) writes:
Well, returning oneself in the overloaded copy constructor works while ($foo++) {} and if ($foo++) In particular: while (++$foo) {} # doesn't trigger copy constructor, and my $bar = $foo; are fine. The problem -- as far as I can tell -- is not in the copy constructor And I'm specifically trying to show what happens in the case of a copy My understanding of copy constructor overloading is that an actual Kwin |
From @hvds"khkramer@allafrica.com (via RT)" <perlbug@perl.org> wrote: There is a bug here, but the while (or if) is a red herring; stripping use overload '++' => sub { $_[0] }, '=' => sub { $_[0] }; .. which shows that the object is destroyed late. If the 'my $b = $a++' It goes something like this: Now I'm not sure how we handle the refcounting of return values; Hugo |
From @hvdsTels <perl_dummy@bloodgate.com> wrote: I couldn't see anything in the docs to state or imply that returning the Hugo |
From kwindla@allafrica.comHugo van der Sanden (via RT) writes:
In addition, if we "force" the copy constructor to actually copy while ( $foo++ ) {} # and constructions on iterator-like $foos. Thanks to Hugo for further stripping down the test-case to demonstrate Kwin |
From goldbb2@earthlink.netKwindla Hultman Kramer wrote:
If your copy-constructor doesn't make a copy, but just returns $self, while ( ++$foo ) {} # and ?
Or else switch from using the post-increment operator to using the Hmm.. if we *do* make using a defective copy-constructor into a death, -- |
From kwindla@allafrica.comBenjamin Goldberg (via RT) writes:
[ snip ]
You're right that there's no operational difference between using pre- But, I stumbled on this bug after adding operator overloading to an The library documentation now explains what's going on -- $foo++ is Yours, |
From kwindla@allafrica.comTels writes:
But that's only one way of looking at what $x = $y; means. You're right, that often the '=' statement serves to put a Note that in Perl, refererences are just another kind of value, and I think that Perl's wonderfully-flexible reference-munging facilities To wind back around to $x and $y, in much of my code $y->set ( 42 ); Hope this makes my perspective little clearer, |
From @ysthOn Sat, 28 Dec 2002 02:45:52 +0100 (CET), perl_dummy@bloodgate.com wrote:
I don't think this can easily change, since internally perl only |
From @rgsTels <perl_dummy@bloodgate.com> wrote:
There is no free bit left in op_flags, but in theory, the optimizer could label |
From @hvdsRafael Garcia-Suarez <rgarciasuarez@free.fr> wrote: I think this would be a rather large change, and I'm not convinced this Hugo |
@chorny - Status changed from 'open' to 'stalled' |
@cpansprout - Status changed from 'stalled' to 'open' |
From @cpansproutI changed this from ‘stalled’ to ‘open’, because I think And someone may want to revisit this bug some day. |
From zefram@fysh.orgThis was fixed by commit 7dcb9b9 in -zefram |
@tonycoz - Status changed from 'open' to 'resolved' |
From @jkeenanOn Tue, 16 Jan 2018 21:32:58 GMT, zefram@fysh.org wrote:
But I can hear Father C saying, "What about a test?" Please review the attached. (I'm not very familiar with 'fresh_perl_is' so I suspect both the test and the commit message could be improved.) Thank you very much. -- |
From @jkeenan0001-Demonstrate-timely-destruction-of-object.patchFrom 9422dbd7fd7a3c2aaa1fcb230f0229d70c203eb2 Mon Sep 17 00:00:00 2001
From: James E Keenan <jkeenan@cpan.org>
Date: Tue, 16 Jan 2018 19:21:53 -0500
Subject: [PATCH] Demonstrate timely destruction of object.
For RT #18581
---
lib/overload.t | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
diff --git a/lib/overload.t b/lib/overload.t
index 2afa6cf..f4ce103 100644
--- a/lib/overload.t
+++ b/lib/overload.t
@@ -48,7 +48,7 @@ package main;
$| = 1;
BEGIN { require './test.pl'; require './charset_tools.pl' }
-plan tests => 5338;
+plan tests => 5339;
use Scalar::Util qw(tainted);
@@ -3047,3 +3047,25 @@ package RT132385 {
# ditto with a mutator
::is($o .= $r1, "obj-ref1", "RT #132385 o.=r1");
}
+
+{
+ no strict;
+ $msg = '---- script finished (should have already garbage-collected) ---';
+ fresh_perl_is(
+ <<'EOF',
+package RT18581;
+use overload
+ '++' => sub { $_[0] },
+ '=' => sub { $_[0] };
+sub DESTROY { print "Destroying $_[0]\n"; }
+{
+ my $a = bless {}, RT18581;
+ my $b = $a++;
+}
+print "---- script finished (should have already garbage-collected) ---\n";
+EOF
+ $msg,
+ {},
+ 'RT 18581: timely destruction',
+ );
+}
--
2.7.4
|
From zefram@fysh.orgJames E Keenan via RT wrote:
This time the fix was intentional, and the commit that I cited added -zefram |
Migrated from rt.perl.org#18581 (status was 'resolved')
Searchable as RT18581$
The text was updated successfully, but these errors were encountered: