Closed p5pRT closed 14 years ago
The program foo.pl below prints
SCALAR(0x874b2c0)
where I hoped it would print undef\, ie. the lexical scalar $str would be garbage collected on going out of scope. undef is what I get without the lvalue substr() assignment\, or with a 4-arg substr call.
Some digging around suggests the scratchpad array in foo() holds a reference to the $str scalar if an lvalue substr is used this way. I don't know if that's a bug\, a feature\, or an unavoidable side-effect of the implementation.
If a feature or unavoidable then take this report as a wish for something in the docs on the subject\, as even perlguts seems very thin on anything about lvalue scalars.
For what it's worth I struck this in DBI.pm where it does a substr modify like this and the resulting scalar looks like a memory leak to Test::Weaken. I think it really is a leak\, but only a temporary one since the next call to foo() or whatever function seems to clear it out. Of course if a string is very big it'd be bad to have it hanging around in core beyond what you normally expect to be its scope.
Flags: category=core severity=medium
Site configuration information for perl 5.10.0:
Configured by Debian Project at Thu Jul 9 09:30:18 UTC 2009.
Summary of my perl5 (revision 5 version 10 subversion 0) configuration: Platform: osname=linux\, osvers=2.6.30.1-dsa-ia32\, archname=i486-linux-gnu-thread-multi uname='linux murphy 2.6.30.1-dsa-ia32 #1 smp fri jul 3 12:55:10 cest 2009 i686 gnulinux ' config_args='-Dusethreads -Duselargefiles -Dccflags=-DDEBIAN -Dcccdlflags=-fPIC -Darchname=i486-linux-gnu -Dprefix=/usr -Dprivlib=/usr/share/perl/5.10 -Darchlib=/usr/lib/perl/5.10 -Dvendorprefix=/usr -Dvendorlib=/usr/share/perl5 -Dvendorarch=/usr/lib/perl5 -Dsiteprefix=/usr/local -Dsitelib=/usr/local/share/perl/5.10.0 -Dsitearch=/usr/local/lib/perl/5.10.0 -Dman1dir=/usr/share/man/man1 -Dman3dir=/usr/share/man/man3 -Dsiteman1dir=/usr/local/man/man1 -Dsiteman3dir=/usr/local/man/man3 -Dman1ext=1 -Dman3ext=3perl -Dpager=/usr/bin/sensible-pager -Uafs -Ud_csh -Ud_ualarm -Uusesfio -Uusenm -DDEBUGGING=-g -Doptimize=-O2 -Duseshrplib -Dlibperl=libperl.so.5.10.0 -Dd_dosuid -des' hint=recommended\, useposix=true\, d_sigaction=define useithreads=define\, usemultiplicity=define useperlio=define\, d_sfio=undef\, uselargefiles=define\, usesocks=undef use64bitint=undef\, use64bitall=undef\, uselongdouble=undef usemymalloc=n\, bincompat5005=undef Compiler: cc='cc'\, ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64'\, optimize='-O2 -g'\, cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBIAN -fno-strict-aliasing -pipe -I/usr/local/include' ccversion=''\, gccversion='4.3.3'\, gccosandvers='' intsize=4\, longsize=4\, ptrsize=4\, doublesize=8\, byteorder=1234 d_longlong=define\, longlongsize=8\, d_longdbl=define\, longdblsize=12 ivtype='long'\, ivsize=4\, nvtype='double'\, nvsize=8\, Off_t='off_t'\, lseeksize=8 alignbytes=4\, prototype=define Linker and Libraries: ld='cc'\, ldflags =' -L/usr/local/lib' libpth=/usr/local/lib /lib /usr/lib /usr/lib64 libs=-lgdbm -lgdbm_compat -ldb -ldl -lm -lpthread -lc -lcrypt perllibs=-ldl -lm -lpthread -lc -lcrypt libc=/lib/libc-2.9.so\, so=so\, useshrplib=true\, libperl=libperl.so.5.10.0 gnulibc_version='2.9' Dynamic Linking: dlsrc=dl_dlopen.xs\, dlext=so\, d_dlsymun=undef\, ccdlflags='-Wl\,-E' cccdlflags='-fPIC'\, lddlflags='-shared -O2 -g -L/usr/local/lib'
On Thu Jul 23 17:19:15 2009\, kryde wrote:
The program foo.pl below prints
SCALAR\(0x874b2c0\)
where I hoped it would print undef\, ie. the lexical scalar $str would be garbage collected on going out of scope. undef is what I get without the lvalue substr() assignment\, or with a 4-arg substr call.
Some digging around suggests the scratchpad array in foo() holds a reference to the $str scalar if an lvalue substr is used this way. I don't know if that's a bug\, a feature\, or an unavoidable side-effect of the implementation.
If a feature or unavoidable then take this report as a wish for something in the docs on the subject\, as even perlguts seems very thin on anything about lvalue scalars.
lvalue substr seems to leak...
Test case:
#!/usr/bin/perl -l
use strict; use warnings;
my $str = 'Hello World'; print "before: " . Internals::SvREFCNT($str);
substr($str\,0\,1) = 'x'; print "after (1): " . Internals::SvREFCNT($str);
substr($str\,0\,1) = 'x'; print "after (2): " . Internals::SvREFCNT($str);
for (3\, 4) { print "before ($_) (loop): " . Internals::SvREFCNT($str); substr($str\,0\,1) = 'x'; print "after ($_) (loop): " . Internals::SvREFCNT($str); }
__END__ Output (with blead):
before: 1 after (1): 2 after (2): 3 before (3) (loop): 3 after (3) (loop): 4 before (4) (loop): 4 after (4) (loop): 4
(perl-5.6.0 (tested with Devel::Peek)\, perl-5.8.0 and everything in between behaves the same as blead)
I'm guessing this is due to:
LvTYPE(TARG) = 'x'; if (LvTARG(TARG) != sv) { if (LvTARG(TARG)) SvREFCNT_dec(LvTARG(TARG)); LvTARG(TARG) = SvREFCNT_inc_simple(sv); }
in pp_substr.
Looking at the blame log this seems to be added in: http://perl5.git.perl.org/perl.git/blobdiff/ 15e73149a8419f18d739227762eab108524cec56..ae389c8a29b487f4434c465442dfb611507a4a38:/ pp.c [core language changes]
Title: "5.004_04m5t1: Fix dangling references in LVs"\, "Fix dangling references in LVs" Msg-ID: \199804010541\.AAA32615@​Orb\.Nashua\.NH\.US\, \19980422164037\.D29222@​perl\.org Files: embed.h keywords.h opcode.h perl.h proto.h doop.c global.sym mg.c pp.c sv.c
Title: "Fix SvGMAGIC typo in change 904" Files: doop.c
p4raw-id: //depot/maint-5.004/perl@906
Unfortunally no tests are added in that change :(
This change also indicates that the same happens for vec() and pos():
#!/usr/bin/perl -l
use strict; use warnings;
my $str = 'Hello World'; print "before: " . Internals::SvREFCNT($str);
vec($str\,0\,1) = 0; print "after (1): " . Internals::SvREFCNT($str);
vec($str\,0\,1) = 0; print "after (2): " . Internals::SvREFCNT($str);
for (3\, 4) { print "before ($_) (loop): " . Internals::SvREFCNT($str); vec($str\,0\,1) = 0; print "after ($_) (loop): " . Internals::SvREFCNT($str); } __END__
before: 1 after (1): 2 after (2): 3 before (3) (loop): 3 after (3) (loop): 4 before (4) (loop): 4 after (4) (loop): 4
#!/usr/bin/perl -l
use strict; use warnings;
my $str = 'Hello World'; print "before: " . Internals::SvREFCNT($str);
pos($str) = 0;
print "after (1): " . Internals::SvREFCNT($str);
pos($str) = 0;
print "after (2): " . Internals::SvREFCNT($str);
for (3\, 4) {
print "before ($_) (loop): " . Internals::SvREFCNT($str);
pos($str) = 0;
print "after ($_) (loop): " . Internals::SvREFCNT($str);
}
__END__
before: 1
after (1): 2
after (2): 3
before (3) (loop): 3
after (3) (loop): 4
before (4) (loop): 4
after (4) (loop): 4
Anyone remembers the reason why this is/was nessesary? (I haven't tested yet what happens when the refcount isn't increased)
Best regards\,
Bram
The RT System itself - Status changed from 'new' to 'open'
vec increases the refcount of its target:
perl -MDevel::Peek -le"my $x=''; Dump $x; vec($x\,0\,1)=0; Dump $x;" SV = PV(0x236044) at 0x238264 REFCNT = 1 FLAGS = (PADMY\,POK\,pPOK) PV = 0x23fd84 ""\0 CUR = 0 LEN = 4 SV = PV(0x236044) at 0x238264 REFCNT = 2 FLAGS = (PADMY\,POK\,pPOK) PV = 0x23fd84 "\0"\0 CUR = 1 LEN = 4
The memory leaking effects can be seen using these snippets:
perl -le"{ my $x=''; $x = bless {}; } print 'G'; DESTROY { print 'D' }" D G
perl -le"{ my $x=''; vec($x\,0\,1)=0; $x = bless {}; } print 'G'; DESTROY { print 'D' }" G D
This has been occurring at least as far back as 5.6.0
- Eric
It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe keys().
I'll have a look at this.
Vincent.
The RT System itself - Status changed from 'new' to 'open'
It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe keys().
I'll have a look at this.
Vincent.
Actually\, this has already been reported in http://rt.perl.org/rt3/Ticket/Display.html?id=67838\, and I came to the same conclusions as Bram. Let's continue there.
bitcard@profvince.com - Status changed from 'open' to 'rejected'
On Fri Jul 24 03:10:16 2009\, animator wrote:
I'm guessing this is due to:
LvTYPE\(TARG\) = 'x'; if \(LvTARG\(TARG\) \!= sv\) \{ if \(LvTARG\(TARG\)\) SvREFCNT\_dec\(LvTARG\(TARG\)\); LvTARG\(TARG\) = SvREFCNT\_inc\_simple\(sv\); \}
Yes
---BEGIN CODE--- my $str = 'Hello World';
for ($str\, "a") { print Internals::SvREFCNT($str)\, "\n";
pos = 0; print Internals::SvREFCNT($str)\, "\n";
pos = 0; print Internals::SvREFCNT($str)\, "\n";
print "\n"; } ---END CODE---
---BEGIN ANNOTATED OUTPUT--- 2 3 1st pos's targ refers to $str 4 2nd pos's targ refers to $str
3 2 1st pos's targ no longer refers to $str 1 2nd pos's targ no longer refers to $str ---END ANNOTATED OUTPUT---
What if we avoided using TARG when a lvalue is needed? I'll produce a patch this weekend.
On Thu Nov 05 12:56:29 2009\, perl@profvince.com wrote:
It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe keys().
Confirmed for all four. A patch to add tests is attached.
A patch to fix the problem will follow shortly.
On Fri Nov 06 16:25:33 2009\, ikegami@adaelis.com wrote:
On Thu Nov 05 12:56:29 2009\, perl@profvince.com wrote:
It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe keys().
Confirmed for all four. A patch to add tests is attached.
A patch to fix the problem will follow shortly.
Two patches are attached.
The first adds tests. It's an updated version of my earlier patch. It should be used instead of the earlier patch.
The second plugs the leaks by not using TARG when a lvalue is required.
2009/11/7 Eric Brine via RT \perlbug\-followup@​perl\.org:
On Fri Nov 06 16:25:33 2009\, ikegami@adaelis.com wrote:
On Thu Nov 05 12:56:29 2009\, perl@profvince.com wrote:
It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe keys().
Confirmed for all four. A patch to add tests is attached.
A patch to fix the problem will follow shortly.
Two patches are attached.
The first adds tests. It's an updated version of my earlier patch. It should be used instead of the earlier patch.
The second plugs the leaks by not using TARG when a lvalue is required.
Just out of curiosity why does that code decontaminate differently in the two cases? One time it "decontaminates" taint and utf8\, and one time it just does taint. Is that a bug?
Yves
-- perl -Mre=debug -e "/just|another|perl|hacker/"
On Sat\, Nov 7\, 2009 at 6:13 PM\, yves orton via RT \<perlbug-followup@perl.org
wrote:
Just out of curiosity why does that code decontaminate differently in the two cases? One time it "decontaminates" taint and utf8\, and one time it just does taint. Is that a bug?
Some opcodes always return the result in the same SV to avoid having to create a new SV everytime the opcode is encountered. This SV is known as TARG.
The problem with these ops is 1) that they reference their last return value since they use TARG\, and 2) that their return value references one of the opcode's arguments when they are used as lvalues.
{ my $x = "abc"; # REFCOUNT($x) = 1 (pad) substr($x\, 1\, 1) = "d"; # REFCOUNT($x) = 2 (pad\,substr) print($x); # REFCOUNT($x) = 2 (pad\,substr) } # LEAK! # REFCOUNT($x) = 1 (substr)
The mem will relacaimed the next time that substr instance is called.
The patch has the ops use a fresh SV instead of TARG when they're used as lvalues\, making it so the arg never contains a reference to a variable.
Now to answer your question.
Before TARG is reused by the op\, it's untainted. There's no use untaintaing a freshly created variable\, and there's no use untainting TARG when TARG isn't used\, so I moved the untainting into the branch where TARG is used.
ELB
[ Oops\, my previous message didn't answer your question. I had misread it. Let's try again ]
On Sat\, Nov 7\, 2009 at 6:12 PM\, demerphq \demerphq@​gmail\.com wrote:
Just out of curiosity why does that code decontaminate differently in the two cases? One time it "decontaminates" taint and utf8\, and one time it just does taint. Is that a bug?
Only one of the four ops plays with the UTF8 flag because three of the ops return numbers.
- ELB
2009/11/7 Eric Brine via RT \perlbug\-followup@​perl\.org:
On Fri Nov 06 16:25:33 2009\, ikegami@adaelis.com wrote:
On Thu Nov 05 12:56:29 2009\, perl@profvince.com wrote:
It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe keys().
Confirmed for all four. A patch to add tests is attached.
A patch to fix the problem will follow shortly.
Two patches are attached.
The first adds tests. It's an updated version of my earlier patch. It should be used instead of the earlier patch.
The second plugs the leaks by not using TARG when a lvalue is required.
WIth this patch\, the following tests fail : re/substr.t (Wstat: 65280 Tests: 328 Failed: 0) Non-zero exit status: 255 Parse errors: Bad plan. You planned 334 tests but ran 328. op/sub_lval.t (Wstat: 65280 Tests: 56 Failed: 0) Non-zero exit status: 255 Parse errors: Bad plan. You planned 69 tests but ran 56. ../lib/warnings.t (Wstat: 0 Tests: 633 Failed: 1) Failed test: 251
with the error "Can't return a temporary from lvalue subroutine". That happens in cases like that one : sub sstr : lvalue { substr($str\, 1\, 4) } It seems that we have a trade-off to make here. My opinion would be to apply your patch\, at the expense of forbidding that kind of leaky constructs. I'd like to hear comments here.
Also\, the warnings.t failure apparently is a bug fix rather than a true failure.
It seems that we have a trade-off to make here. My opinion would be to apply your patch\, at the expense of forbidding that kind of leaky constructs. I'd like to hear comments here.
I'm not too sure about this. I'd rather : - understand why ae389c8a29b487f4434c465442dfb611507a4a38 started incrementing the refcount of the LvTARG member ; - if it is decided to stop lvalues from propagating too far\, I'd rather keep those ops using the TARG and decrement its refcount in the magical callback.
Vincent.
On Sun\, Nov 8\, 2009 at 8:49 AM\, Vincent Pit \perl@​profvince\.com wrote:
It seems that we have a trade-off to make here. My opinion would be to
apply your patch\, at the expense of forbidding that kind of leaky constructs. I'd like to hear comments here.
I'm not too sure about this. I'd rather : - understand why ae389c8a29b487f4434c465442dfb611507a4a38 started incrementing the refcount of the LvTARG member ; - if it is decided to stop lvalues from propagating too far\, I'd rather keep those ops using the TARG and decrement its refcount in the magical callback.
Can't:
$x = \substr(...); print $$x; print $$x;
$x = \substr(...); $$x = uc($$x);
What about a weak reference. Is that possible? I haven't looked at how those work.
Rafael Garcia-Suarez \rgs@​consttype\.org wrote: :2009/11/7 Eric Brine via RT \perlbug\-followup@​perl\.org: :> On Fri Nov 06 16:25:33 2009\, ikegami@adaelis.com wrote: :>> On Thu Nov 05 12:56:29 2009\, perl@profvince.com wrote: :>> > It's not only lvalue vec()\, it's also lvalue pos()\, substr() and maybe :>> > keys(). :>> :>> Confirmed for all four. A patch to add tests is attached. :>> :>> A patch to fix the problem will follow shortly. :> :> Two patches are attached. :> :> The first adds tests. It's an updated version of my earlier patch. It :> should be used instead of the earlier patch. :> :> The second plugs the leaks by not using TARG when a lvalue is required. : :WIth this patch\, the following tests fail : [...] :with the error "Can't return a temporary from lvalue subroutine". :That happens in cases like that one : :sub sstr : lvalue { substr($str\, 1\, 4) } :It seems that we have a trade-off to make here. My opinion would be to :apply your patch\, at the expense of forbidding that kind of leaky :constructs. I'd like to hear comments here.
Is it possible to restrict the leak only to the lvalue-sub case? (In fact\, is it even a leak in that case?)
I feel it should be possible to have the best of both worlds.
Hugo
On Sun\, Nov 8\, 2009 at 12:21 PM\, Hugo van der Sanden via RT \< perlbug-followup@perl.org> wrote:
Is it possible to restrict the leak only to the lvalue-sub case? (In fact\, is it even a leak in that case?)
I feel it should be possible to have the best of both worlds.
As I understand it\, yes. That's the "LVRET" in "PL_op->op_flags & OPf_MOD || LVRET".
Considering the leak will probably never matter\, another option would be to simply not fix it.
On Thu\, Jul 23\, 2009 at 7:19 PM\, Kevin Ryde \perlbug\-followup@​perl\.orgwrote:
# New Ticket Created by Kevin Ryde # Please include the string: [perl #67838] # in the subject line of all future correspondence about this issue. # \<URL: http://rt.perl.org/rt3/Ticket/Display.html?id=67838 >
What's the impact of the bug?
substr\, pos and vec operate on strings. Delaying the freeing of strings has next to no impact. Problems can occur if the scalar containing the string is then repurposed (e.g. to hold an object with a destructor)\, but the odds of this occurring is probably next to nil.
keys operate on hashes. Delaying the freeing of a hash could have a significant impact. On the other hand\, lvalue keys is probably almost never used.
What's the impact of the fix?
Small slowdown due to the creation of a new SV for every lvalue call to these ops
Our options at this time:
- Apply the provided patch\, even though it will cause returning substr/pos/vec/keys from an lvalue sub croaks. - Apply an adjusted patch that doesn't fix the leak when substr/pos/vec/keys are returned from an lvalue sub. - Don't fix until a better solution is found. - WONTFIX
"Eric Brine via RT" \perlbug\-followup@​perl\.org writes:
What's the impact of the bug?
Is that a question for me? As I said I didn't know if it was a bug\, a feature\, or a side-effect. It was just it looked a bit leak-like.
Delaying the freeing of strings has next to no impact.
If it's a big string it would use up memory for a lot longer than you'd expect. Ie. you thought you were careful to chuck that big string\, but it gets held onto.
If the scalar is tied or has other magic it could be bad to delay its destructor\, eg. a write-back of held data or something which otherwise end-of-scope normally handled. Sample programs below with tie and a File::Map mmap() magic. (The mmap only holds up address space and system resources of course\, writes go through immediately.)
- Don't fix until a better solution is found.
I wouldn't mind knowing a way to identify scalars held alive like this\, so as to excuse them from Test::Weaken or similar leak checking.
On Mon\, Nov 16\, 2009 at 4:03 PM\, Kevin Ryde \user42@​zip\.com\.au wrote:
"Eric Brine via RT" \perlbug\-followup@​perl\.org writes:
What's the impact of the bug?
Is that a question for me?
It was rhetorical. The answer followed.
Delaying the freeing of strings has next to no impact.
If it's a big string it would use up memory for a lot longer than you'd expect.
Yes\, but Perl already does that all over the place intentionally. For example\, lexicals aren't freed when they go out of scope. They stay allocated (along with their string buffer) for reuse the next time that scope is entered. If that's the extent of the problem\, it's not a bug.
If the scalar is tied or has other magic it could be bad to delay its
destructor\,
I must have been tired\, but I forgot magic had destructors. I may have underestimated the impact. I definitely understated it.
- Don't fix until a better solution is found.
I wouldn't mind knowing a way to identify scalars held alive like this\, so as to excuse them from Test::Weaken or similar leak checking.
Since TARG variables are stored in the pad\, you could go through the pad looking for PVLVs that have associated variables. It may not be the perfect answer (any maybe you can refine it by looking at the flags)\, but it should be a very good heuristic.
On Tue\, Nov 17\, 2009 at 12:45 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
If the scalar is tied or has other magic it could be bad to delay its
destructor\,
I must have been tired\, but I forgot magic had destructors. I may have underestimated the impact. I definitely understated it.
- Don't fix until a better solution is found.
I wouldn't mind knowing a way to identify scalars held alive like this\, so as to excuse them from Test::Weaken or similar leak checking.
Since TARG variables are stored in the pad\, you could go through the pad looking for PVLVs that have associated variables. It may not be the perfect answer (any maybe you can refine it by looking at the flags)\, but it should be a very good heuristic.
1: are there situations where a RAIL object will be the subject of one of these functions? (resource acquisition is locking is the big design pattern that relies on timely destruction)
2: can TARG be a weak reference using current weak reference technology? That was mentioned earlier in this thread\, and seems from a high and distant level to be the way to go. What's wrong with that suggestion? When does TARG hold the last reference to something\, and if never\, can TARG manipulation stuff simply leave reference counts alone?
-- "In the case of an infinite collection\, the question of the existence of a choice function is problematic"
On Tue\, Nov 17\, 2009 at 2:27 PM\, David Nicol \davidnicol@​gmail\.com wrote:
1: are there situations where a RAIL object will be the subject of one of these functions? (resource acquisition is locking is the big design pattern that relies on timely destruction)
Yes.
I previously gave the following example which demonstrates resources being help until global destruction (marked by "G") rather than being released timely:
# Timely release
perl -le"{ my $x=''; $x = bless {}; } print 'G'; DESTROY { print 'D' }" D G
# Resource held until global destruction
perl -le"{ my $x=''; vec($x\,0\,1)=0; $x = bless {}; } print 'G'; DESTROY { print 'D' }" G D
Here's an example that uses lvalue keys(%h) in the most straightforward manner:
perl -le' sub init { my %h; keys(%h) = @_; %h = map { $_ => bless {} } @_; return \%h; } DESTROY { print "D" } { my $h = init(qw(a b c)); } print "G"; ' GDDD
2: can TARG be a weak reference using current weak reference technology?
That was mentioned earlier in this thread\, and seems from a high and distant level to be the way to go.
Yes\, I believe so.
What's wrong with that suggestion?
The only downside is overhead. It makes yet another variable magical (the var passed as an arg). I can write up a patch tonight if you wish.
Should I only use weaken when necessary (lvalue subs)?
When does TARG hold the last reference to something\,
See the reply to your first question.
can TARG manipulation stuff simply leave reference counts alone?
If these ops couldn't be used as the return value for lvalue subs\, I believe we could do forgo ref counting. I don't think that's a condition we can meet.
Eric
On Tue\, Nov 17\, 2009 at 6:22 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
On Tue\, Nov 17\, 2009 at 2:27 PM\, David Nicol \davidnicol@​gmail\.com wrote:
2: can TARG be a weak reference using current weak reference technology?
That was mentioned earlier in this thread\, and seems from a high and distant level to be the way to go.
Yes\, I believe so.
No\, I was wrong. Conditions that must be met:
- A magical var (e.g. PVLV) must be returned. - The magical var cannot be a TEMP - The magical var must reference the arg var - The magical var must have a counted reference to the arg var.
If the TARG is a PLVL that targets an RV that weekly references the arg var\, it violates the fourth point causing the following to fail:
my $r; { my $s = ""; $r = \substr($s\, 0\, 1); } $$r = 'a'; print $$r;
If the TARG is an RV that weekly references a PVLV that references the arg var\, the PVLV would be a TEMP. That violates the second causing the following to fail:
sub :lvalue { my $s = ""; substr($s\, 0\, 1) }->();
On Wed\, Nov 18\, 2009 at 1:01 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
My next step will be figuring out whether lvalue subs can't return TEMPs because it can't be done or because it hasn't been implemented.
It simply appears to be the case that the original coder forgot that TEMPs could be magical. No problem or memory leaks occur if they are returned.
In fact\, the sub was previously patched to allow a TEMP to be returned from an lvalue sub when it's a tied element. Without it\, the following would not work:
use Tie::Array; tie my @a\, Tie::StdArray:: @a = qw( a b c ); sub f :lvalue { $a[0] } f() = 'd';
Therefore\, the solution is to extend the aforementioned exception to SVs with any type of Set magic (instead of just those with tiedelem magic).
Attached is the test patch (unchanged) and an updated fix patch the addresses all problems and passes all tests.
- Eric
"Eric Brine via RT" \perlbug\-followup@​perl\.org writes:
lexicals aren't freed when they go out of scope. They stay allocated (along with their string buffer) for reuse the next time that scope is entered.
Ah\, I didn't know that. Makes it hard to work carefully with big strings. You'd be tempted to free big things\, above some threshold\, on the relative badness of time taken to malloc a new block.
On Fri\, 27 Nov 2009 11:41:19 +1100\, Kevin Ryde \user42@​zip\.com\.au wrote:
"Eric Brine via RT" \perlbug\-followup@​perl\.org writes:
lexicals aren't freed when they go out of scope. They stay allocated (along with their string buffer) for reuse the next time that scope is entered.
Ah\, I didn't know that. Makes it hard to work carefully with big strings. You'd be tempted to free big things\, above some threshold\, on the relative badness of time taken to malloc a new block.
$s = undef;
especially safe when $s is an object (e.g. a DBI statement handle) that may contain big structures.
-- H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/ using & porting perl 5.6.2\, 5.8.x\, 5.10.x\, 5.11.x on HP-UX 10.20\, 11.00\, 11.11\, 11.23\, and 11.31\, OpenSuSE 10.3\, 11.0\, and 11.1\, AIX 5.2 and 5.3. http://mirrors.develooper.com/hpux/ http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/
"H.Merijn Brand" \h\.m\.brand@​xs4all\.nl writes:
On Fri\, 27 Nov 2009 11:41:19 +1100\, Kevin Ryde \user42@​zip\.com\.au wrote:
"Eric Brine via RT" \perlbug\-followup@​perl\.org writes:
lexicals aren't freed when they go out of scope. They stay allocated (along with their string buffer) for reuse the next time that scope is entered.
Ah\, I didn't know that. Makes it hard to work carefully with big strings. You'd be tempted to free big things\, above some threshold\, on the relative badness of time taken to malloc a new block.
$s = undef;
Did you mean undef($s)\, or did something change while I was not looking? ;-)
Eirik\, who doesn't use that feature often either -- The price of success in philosophy is triviality. -- C. Glymour.
On Fri\, 27 Nov 2009 15:38:03 +0100\, Eirik Berg Hanssen \Eirik\-Berg\.Hanssen@​allverden\.no wrote:
"H.Merijn Brand" \h\.m\.brand@​xs4all\.nl writes:
On Fri\, 27 Nov 2009 11:41:19 +1100\, Kevin Ryde \user42@​zip\.com\.au wrote:
"Eric Brine via RT" \perlbug\-followup@​perl\.org writes:
lexicals aren't freed when they go out of scope. They stay allocated (along with their string buffer) for reuse the next time that scope is entered.
Ah\, I didn't know that. Makes it hard to work carefully with big strings. You'd be tempted to free big things\, above some threshold\, on the relative badness of time taken to malloc a new block.
$s = undef;
Did you mean undef($s)\, or did something change while I was not looking? ;-)
Both is allowed\, but indeed only 'undef ($x)' frees the variable. I was not aware of the difference until I just checked. Look at the flags:
$ perl -MDP -wle'$_="x"x10;DDump$_;$_=undef;DDump$_' SV = PV(0x743158) at 0x782198 REFCNT = 1 FLAGS = (POK\,pPOK) PV = 0x753660 "xxxxxxxxxx"\0 CUR = 10 LEN = 16
SV = PV(0x743158) at 0x782198 REFCNT = 1 FLAGS = () PV = 0x753660 "xxxxxxxxxx"\0 CUR = 10 LEN = 16
$ perl -MDP -wle'$_="x"x10;DDump$_;undef$_;DDump$_' SV = PV(0x743158) at 0x782198 REFCNT = 1 FLAGS = (POK\,pPOK) PV = 0x753660 "xxxxxxxxxx"\0 CUR = 10 LEN = 16
SV = PV(0x743158) at 0x782198 REFCNT = 1 FLAGS = () PV = 0
$
Eirik\, who doesn't use that feature often either
-- H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/ using & porting perl 5.6.2\, 5.8.x\, 5.10.x\, 5.11.x on HP-UX 10.20\, 11.00\, 11.11\, 11.23\, and 11.31\, OpenSuSE 10.3\, 11.0\, and 11.1\, AIX 5.2 and 5.3. http://mirrors.develooper.com/hpux/ http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/
On Sun\, 29 Nov 2009 00:51:49 +0100\, Eirik Berg Hanssen \Eirik\-Berg\.Hanssen@​allverden\.no wrote:
On Fri\, Nov 27\, 2009 at 8:52 AM\, H.Merijn Brand \h\.m\.brand@​xs4all\.nl wrote:
On Fri\, 27 Nov 2009 15:38:03 +0100\, Eirik Berg Hanssen
Did you mean undef($s)\, or did something change while I was not looking? ;-)
Both is allowed\, but indeed only 'undef ($x)' frees the variable.
If '$s = undef' is clearly not doing what might be expected\, is there any chance in breaking code when making '$s = undef' to do the same as 'undef $s' ?
How easy would it be to `optimize' that in perl itself?
Aside: If anything were to change\, my suggestion would be the addition of a warning for an assignment\, the right hand side of which is a simple literal undef (without arguments\, parens or such). It is often a mistake and never the clearest way to write something:
$x = undef; # unclear – did you really mean this? $x = (); # same thing\, clearer – yes\, I mean it undef $x; # not the same thing: this frees the memory
@x = undef; # unclear – did you really mean this? @x = (undef); # same thing\, clearer – yes\, I mean it @x = (); # not the same thing: empty array undef @x; # not the same thing: this frees the memory
%x = undef; # unclear – did you really mean this? %x = ('' => undef); # same thing\, clearer – and no warning %x = (); # not the same thing: empty hash undef %x; # not the same thing: this frees the memory
($x\, @y) = undef; # unclear – did you really mean this? ($x\, @y) = (undef); # same thing\, clearer ($x\, @y) = (); # also the same thing\, perhaps even clearer undef $x; undef @y; # not the same thing: this frees the memory
lsub($x) = undef; # ... okay\, I suppose that one is reasonably clear lsub($x) = (undef); # same thing\, even clearer ;-) undef lsub($x); # not the same thing ... but yes\, it works ;-)
... and at least the scalar case is a mistake that\, apparently\, even an experienced Perl hacker could make. ;-)
Eirik
-- H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/ using & porting perl 5.6.2\, 5.8.x\, 5.10.x\, 5.11.x on HP-UX 10.20\, 11.00\, 11.11\, 11.23\, and 11.31\, OpenSuSE 10.3\, 11.0\, and 11.1\, AIX 5.2 and 5.3. http://mirrors.develooper.com/hpux/ http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/
"H.Merijn Brand" \h\.m\.brand@​xs4all\.nl writes:
$s = undef;
Umm\, sounds a bit like hard work if you have to catch all variables that hold or might hold big things ... :-)
On Sun\, Nov 29\, 2009 at 5:11 AM\, H.Merijn Brand \h\.m\.brand@​xs4all\.nl wrote:
If '$s = undef' is clearly not doing what might be expected\, is there any chance in breaking code when making '$s = undef' to do the same as 'undef $s' ?
No\, I don't see how it could.
How easy would it be to `optimize' that in perl itself?
You mean remove the optimisation to prevent unnecessary calls to malloc.
The answer might depend on exactly what you want. Do you wish to free the scalar's buffer
1) When the result of a call to undef is assigned to it? 2) When &PL_sv_undef is assigned to it? 3) When an undefined value is assigned to it? 4) When an undefined value is assigned to it and when it is cleared (e.g. when it goes out of scope).
I'm not sure it's wise to remove this optimisation for the rare occurrence of accidentally using undef($var) instead of $var = undef in the rare occurrence that undef($var) is needed.
ELB
On Mon\, Nov 30\, 2009 at 2:34 PM\, Eric Brine \ikegami@​adaelis\.com wrote:
You mean remove the optimisation to prevent unnecessary calls to malloc. [... When?]
how about "when there's memory pressure?"
On Mon\, 30 Nov 2009 15:34:08 -0500\, Eric Brine \ikegami@​adaelis\.com wrote:
On Sun\, Nov 29\, 2009 at 5:11 AM\, H.Merijn Brand \h\.m\.brand@​xs4all\.nl wrote:
If '$s = undef' is clearly not doing what might be expected\, is there any chance in breaking code when making '$s = undef' to do the same as 'undef $s' ?
No\, I don't see how it could.
How easy would it be to `optimize' that in perl itself?
You mean remove the optimisation to prevent unnecessary calls to malloc.
I'm not pushing anymore\, but /I/ don't see *any* use here. If I want to preserve the allocated memory\, I use ""\, not undef.
The answer might depend on exactly what you want. Do you wish to free the scalar's buffer
1) When the result of a call to undef is assigned to it? 2) When &PL_sv_undef is assigned to it? 3) When an undefined value is assigned to it? 4) When an undefined value is assigned to it and when it is cleared (e.g. when it goes out of scope).
Yes to all four points\, but I'll change my habits.
I'm not sure it's wise to remove this optimisation for the rare occurrence of accidentally using undef ($var) instead of $var = undef in the rare occurrence that undef ($var) is needed.
I was looking from the other side. I used $s = undef *expecting* it to act as undef $s. I learned\, I'll change.
And jdb\, I'm not propagating people to undef all their values themselves. Out-of-scope is way nicer\, but I have seen places where using undef $sth would force a DESTROY that otherwise would have been too late.
-- H.Merijn Brand http://tux.nl Perl Monger http://amsterdam.pm.org/ using & porting perl 5.6.2\, 5.8.x\, 5.10.x\, 5.11.x on HP-UX 10.20\, 11.00\, 11.11\, 11.23\, and 11.31\, OpenSuSE 10.3\, 11.0\, and 11.1\, AIX 5.2 and 5.3. http://mirrors.develooper.com/hpux/ http://www.test-smoke.org/ http://qa.perl.org http://www.goldmark.org/jeff/stupid-disclaimers/
On Mon\, Nov 30\, 2009 at 3:58 PM\, H.Merijn Brand \h\.m\.brand@​xs4all\.nl wrote:
I'm not pushing anymore\, but /I/ don't see *any* use here. If I want to preserve the allocated memory\, I use ""\, not undef.
The empty string is not the same thing as undef. You can't assign the empty string to variable you want to undefine.
And jdb\, I'm not propagating people to undef all their values themselves. Out-of-scope is way nicer
Variables going out of scope are not freed (if there are no external reference to them)\, and neither are their buffers.
$ perl -MDevel::Peek -e'sub f { my $x; Dump $x; $x=$_[0]; Dump $x; } f "abcdef"; f "xyz";' SV = NULL(0x0) at 0x966c900 REFCNT = 1 FLAGS = (PADMY) SV = PV(0x96506d0) at 0x966c900 REFCNT = 1 FLAGS = (PADMY\,POK\,pPOK) PV = 0x9667ed0 "abcdef"\0 CUR = 6 LEN = 8 SV = PV(0x96506d0) at 0x966c900 REFCNT = 1 FLAGS = (PADMY) PV = 0x9667ed0 "abcdef"\0 CUR = 6 LEN = 8 SV = PV(0x96506d0) at 0x966c900 REFCNT = 1 FLAGS = (PADMY\,POK\,pPOK) PV = 0x9667ed0 "xyz"\0 CUR = 3 LEN = 8
but I have seen places where using undef $sth would force
a DESTROY that otherwise would have been too late.
$sth=undef; and even $sth=123; would have worked just as well. Aside from the fact that the reference in $sth probably has no string buffer to free in the first place\, if wouldn't affect anything's refcount if it did.
- ELB
perldoc -f undef could use a sentence discussing freeing large string buffers. maybe an example ten:
10. $buf = undef; # defined($buf) is now false\, but $buf's memory space is intact for reuse!
Eric notes that he has pending work on this ticket
Hi\,
Attached are updated versions of patches submitted during the 5.12 prerelease freeze. They are rebased\, have more tests and remove a bit more dead code.
- Eric Brine
Migrated from rt.perl.org#67838 (status was 'resolved')
Searchable as RT67838$