fix for [perl #41138] $_ leaks under threads
authorDavid Mitchell <davem@iabyn.com>
Mon, 11 Jan 2010 12:09:12 +0000 (12:09 +0000)
committerDavid Mitchell <davem@iabyn.com>
Mon, 11 Jan 2010 12:49:08 +0000 (12:49 +0000)
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]

sv.c
t/op/threads.t

diff --git a/sv.c b/sv.c
index 108a1b1..063dd19 100644 (file)
--- 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) {
index c834d07..588b969 100644 (file)
@@ -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
 #