This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
free PL_regex_padav later
authorDavid Mitchell <davem@iabyn.com>
Thu, 29 Mar 2012 10:20:32 +0000 (11:20 +0100)
committerDavid Mitchell <davem@iabyn.com>
Wed, 13 Jun 2012 12:32:49 +0000 (13:32 +0100)
At the point where formerly it was freed, instead just free the individual
regexes and put &PL_sv_undef placeholders in the vacated PL_regex_padav
slots. Then free the actual array a lot later.

This is because at the point where PL_regex_padav used to be freed,
regexes can still hold pointers to CVs that have PMOPs that index into
PL_regex_padav; and while the array is being freed, it's state is
inconsistent (jn particular, sv_clear temporarily stores old indexes in
the top slot.)

This is a band-aid really; the proper solution is to get rid of
PL_regex_padav altogether and store the regexps in the pad.

perl.c

diff --git a/perl.c b/perl.c
index 79d15e2..d287872 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -840,12 +840,19 @@ perl_destruct(pTHXx)
      * REGEXPs in the parent interpreter
      * we need to manually ReREFCNT_dec for the clones
      */
-    SvREFCNT_dec(PL_regex_padav);
-    PL_regex_padav = NULL;
-    PL_regex_pad = NULL;
+    {
+       I32 i = AvFILLp(PL_regex_padav);
+       SV **ary = AvARRAY(PL_regex_padav);
+
+       for (; i; i--) {
+           SvREFCNT_dec(ary[i]);
+           ary[i] = &PL_sv_undef;
+       }
+    }
     Safefree(PL_stashpad);
 #endif
 
+
     SvREFCNT_dec(MUTABLE_SV(PL_stashcache));
     PL_stashcache = NULL;
 
@@ -1060,6 +1067,12 @@ perl_destruct(pTHXx)
                             (long)cxstack_ix + 1);
     }
 
+#ifdef USE_ITHREADS
+    SvREFCNT_dec(PL_regex_padav);
+    PL_regex_padav = NULL;
+    PL_regex_pad = NULL;
+#endif
+
 #ifdef PERL_IMPLICIT_CONTEXT
     /* the entries in this list are allocated via SV PVX's, so get freed
      * in sv_clean_all */