"unofficial" patches for some of the more spectacular [memory leaks]
Larry Wall [Fri, 13 Jan 1995 18:28:56 +0000 (10:28 -0800)]
To: Simon Parsons <S.Parsons@fulcrum.co.uk>

: I am on a Sun sparc running Solaris 5.3 / 5.4
:
: Are there any patches available for perl5.000, or a list of know bugs?
: I am having problems with a script running out of memory, which may be
: causes by memory leaks. The process size grows steadily up to approx
: 8Meg (over a couple of minutes) an then grows to approx 22Meg (in 2 or
: 3 seconds) before running out of memory. purify indicates memory
: leaks, but I am not sure whether this is as a result of perl
: abandoning memory as it exits.

5.001 will contain fixes for a number of memory leaks.  Here are some
unofficial patches for some of the more spectacular ones.  The one
for sv.c is the likeliest one to be affecting you, unless you're doing
a lot of evals.

op.c
perl.c
pp.c
scope.c
sv.c

diff --git a/op.c b/op.c
index d345575..13e536f 100644 (file)
--- a/op.c
+++ b/op.c
@@ -3133,6 +3133,7 @@ register OP *op;
                                ? SVt_PVHV
                                : SVt_PVGV);
        }
+       SvREFCNT_dec(kid->op_sv);
        kid->op_sv = SvREFCNT_inc(gv);
     }
     return op;
diff --git a/perl.c b/perl.c
index f2ee633..67fbcb3 100644 (file)
--- a/perl.c
+++ b/perl.c
@@ -1045,8 +1045,9 @@ init_main_stash()
     GV *gv;
     curstash = defstash = newHV();
     curstname = newSVpv("main",4);
-    GvHV(gv = gv_fetchpv("main::",TRUE, SVt_PVHV)) =
-       (HV*)SvREFCNT_inc(defstash);
+    gv = gv_fetchpv("main::",TRUE, SVt_PVHV);
+    SvREFCNT_dec(GvHV(gv));
+    GvHV(gv) = (HV*)SvREFCNT_inc(defstash);
     SvREADONLY_on(gv);
     HvNAME(defstash) = savepv("main");
     incgv = gv_HVadd(gv_AVadd(gv_fetchpv("INC",TRUE, SVt_PVAV)));
@@ -1054,8 +1055,7 @@ init_main_stash()
     defgv = gv_fetchpv("_",TRUE, SVt_PVAV);
     curstash = defstash;
     compiling.cop_stash = defstash;
-    debstash = newHV();
-    GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV)) = debstash;
+    debstash = GvHV(gv_fetchpv("DB::", GV_ADDMULTI, SVt_PVHV));
 }
 
 #ifdef CAN_PROTOTYPE
@@ -1541,7 +1541,7 @@ init_predump_symbols()
     stdingv = gv_fetchpv("STDIN",TRUE, SVt_PVIO);
     SvMULTI_on(stdingv);
     IoIFP(GvIOp(stdingv)) = stdin;
-    tmpgv = gv_fetchpv("stdin",TRUE, SVt_PVIO);
+    tmpgv = gv_fetchpv("stdin",TRUE, SVt_PV);
     GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(stdingv));
     SvMULTI_on(tmpgv);
 
@@ -1549,14 +1549,14 @@ init_predump_symbols()
     SvMULTI_on(tmpgv);
     IoOFP(GvIOp(tmpgv)) = IoIFP(GvIOp(tmpgv)) = stdout;
     defoutgv = tmpgv;
-    tmpgv = gv_fetchpv("stdout",TRUE, SVt_PVIO);
+    tmpgv = gv_fetchpv("stdout",TRUE, SVt_PV);
     GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(defoutgv));
     SvMULTI_on(tmpgv);
 
     othergv = gv_fetchpv("STDERR",TRUE, SVt_PVIO);
     SvMULTI_on(othergv);
     IoOFP(GvIOp(othergv)) = IoIFP(GvIOp(othergv)) = stderr;
-    tmpgv = gv_fetchpv("stderr",TRUE, SVt_PVIO);
+    tmpgv = gv_fetchpv("stderr",TRUE, SVt_PV);
     GvIOp(tmpgv) = (IO*)SvREFCNT_inc(GvIOp(othergv));
     SvMULTI_on(tmpgv);
 
diff --git a/pp.c b/pp.c
index 38c9e97..23fd79c 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -416,7 +416,7 @@ PP(pp_trans)
        sv = GvSV(defgv);
        EXTEND(SP,1);
     }
-    TARG = NEWSV(27,0);
+    TARG = sv_newmortal();
     PUSHi(do_trans(sv, op));
     RETURN;
 }
diff --git a/scope.c b/scope.c
index 9bc49f9..ce53fd0 100644 (file)
--- a/scope.c
+++ b/scope.c
@@ -573,6 +573,7 @@ I32 base;
            hv = (HV*)ptr;
            ptr = SSPOPPTR;
            hv_delete(hv, (char*)ptr, (U32)SSPOPINT);
+           Safefree(ptr);
            break;
        case SAVEt_DESTRUCTOR:
            ptr = SSPOPPTR;
diff --git a/sv.c b/sv.c
index 7776aa6..ed8dc52 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -1581,7 +1581,7 @@ register SV *sstr;
         */
 
        if (SvTEMP(sstr)) {             /* slated for free anyway? */
-           if (SvPOK(dstr)) {
+           if (SvPVX(dstr)) {          /* we know that dtype >= SVt_PV */
                (void)SvOOK_off(dstr);
                Safefree(SvPVX(dstr));
            }