From: David Mitchell Date: Mon, 11 Jan 2010 12:09:12 +0000 (+0000) Subject: fix for [perl #41138] $_ leaks under threads X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=e81cd4d2c506bfc28460d324d94b81010f5ee455;p=p5sagit%2Fp5-mst-13.2.git fix for [perl #41138] $_ leaks under threads It's possible for an interpreter to get cloned with an SV copied that ends up only linked from @_. For example, local $x causes a link to the original $x SV to be added to the save stack, but when cloning a thread the save stack isn't copied. If the old $x was also in someone's @_, then it gets copied, but because @_'s elements aren't normally reference counted, old $x ends up with a refcount of zero, and you get a "leaked" warning when the thread exits. The workaround is to reify any reify-able AVs in the cloned interpreter during cloning. Also fixes [perl #70602], [perl #70974] --- diff --git a/sv.c b/sv.c index 108a1b1..063dd19 100644 --- a/sv.c +++ b/sv.c @@ -11104,6 +11104,11 @@ Perl_sv_dup(pTHX_ const SV *const sstr, CLONE_PARAMS *const param) else { while (items-- > 0) *dst_ary++ = sv_dup(*src_ary++, param); + if (!(param->flags & CLONEf_COPY_STACKS) + && AvREIFY(sstr)) + { + av_reify(MUTABLE_AV(dstr)); /* #41138 */ + } } items = AvMAX((const AV *)sstr) - AvFILLp((const AV *)sstr); while (items-- > 0) { diff --git a/t/op/threads.t b/t/op/threads.t index c834d07..588b969 100644 --- a/t/op/threads.t +++ b/t/op/threads.t @@ -129,6 +129,8 @@ foreach my $BLOCK (qw(CHECK INIT)) { EOI } +} # TODO + # Scalars leaked: 1 fresh_perl_is(<<'EOI', 'ok', { }, 'Bug #41138'); use threads; @@ -141,7 +143,6 @@ fresh_perl_is(<<'EOI', 'ok', { }, 'Bug #41138'); print 'ok'; EOI -} # TODO # [perl #45053] Memory corruption with heavy module loading in threads #