From: Doug MacEachern Date: Thu, 2 Aug 2001 20:24:55 +0000 (-0700) Subject: [patch] plug PL_regex_padav leaks X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5f8cb0464db8019389b7bf1816b817fa4d44ca34;p=p5sagit%2Fp5-mst-13.2.git [patch] plug PL_regex_padav leaks Message-ID: p4raw-id: //depot/perl@11560 --- diff --git a/op.c b/op.c index 7fad9a4..daefb14 100644 --- a/op.c +++ b/op.c @@ -852,8 +852,14 @@ clear_pmop: #endif } cPMOPo->op_pmreplroot = Nullop; - ReREFCNT_dec(PM_GETRE(cPMOPo)); - PM_SETRE(cPMOPo, (REGEXP*)NULL); + /* we use the "SAFE" version of the PM_ macros here + * since sv_clean_all might release some PMOPs + * after PL_regex_padav has been cleared + * and the clearing of PL_regex_padav needs to + * happen before sv_clean_all + */ + ReREFCNT_dec(PM_GETRE_SAFE(cPMOPo)); + PM_SETRE_SAFE(cPMOPo, (REGEXP*)NULL); break; } diff --git a/op.h b/op.h index af0e983..e92b1d8 100644 --- a/op.h +++ b/op.h @@ -252,9 +252,13 @@ struct pmop { #ifdef USE_ITHREADS #define PM_GETRE(o) ((REGEXP*)SvIVX(PL_regex_pad[(o)->op_pmoffset])) #define PM_SETRE(o,r) (sv_setiv(PL_regex_pad[(o)->op_pmoffset], (IV)r)) +#define PM_GETRE_SAFE(o) (PL_regex_pad ? PM_GETRE(o) : (REGEXP*)0) +#define PM_SETRE_SAFE(o,r) if (PL_regex_pad) PM_SETRE(o,r) #else #define PM_GETRE(o) ((o)->op_pmregexp) #define PM_SETRE(o,r) ((o)->op_pmregexp = (r)) +#define PM_GETRE_SAFE PM_GETRE +#define PM_SETRE_SAFE PM_SETRE #endif #define PMdf_USED 0x01 /* pm has been used once already */ diff --git a/perl.c b/perl.c index e6d6f5f..7362316 100644 --- a/perl.c +++ b/perl.c @@ -466,6 +466,28 @@ perl_destruct(pTHXx) } #endif +#ifdef USE_ITHREADS + /* the syntax tree is shared between clones + * so op_free(PL_main_root) only ReREFCNT_dec's + * REGEXPs in the parent interpreter + * we need to manually ReREFCNT_dec for the clones + */ + { + I32 i = AvFILLp(PL_regex_padav) + 1; + SV **ary = AvARRAY(PL_regex_padav); + + while (i) { + REGEXP *re = (REGEXP *)SvIVX(ary[--i]); + if (re && (re->refcnt > 0)) { + ReREFCNT_dec(re); + } + } + } + SvREFCNT_dec(PL_regex_padav); + PL_regex_padav = Nullav; + PL_regex_pad = NULL; +#endif + /* loosen bonds of global variables */ if(PL_rsfp) {