develooper Front page | perl.perl5.porters | Postings from October 2003

Fixed: [perl #24255] shared hash ref memory leak in 5.8.1

From:
Dave Mitchell
Date:
October 23, 2003 13:47
Subject:
Fixed: [perl #24255] shared hash ref memory leak in 5.8.1
Message ID:
20031023204721.GB397@fdgroup.com
On Wed, Oct 22, 2003 at 10:15:52PM +0200, Elizabeth Mattijsen wrote:
> Well, maybe someone can figure out what is going on here and maybe 
> we'll get a fix for 5.8.2?

Fixed in bleedperl by change #21527

The leak could be reduced to

    my @a : shared;	
    $a[0] = &share([]) while 1;

Whether this will be integrated in 5.8.2 is up to Nick.

The gory details:

While in shared interpeter context, the call to sv_setsv() that updates
the (shared interpreter) RV at $a[0] to refer to the new (shared
interpreter) [] also causes the old thing the RV was pointing to to be
freed.  But a cunning bit of code in sv_unref_flags() doesn't free the old
referent immediately; instead it is converted into a mortal, and so freed
later. This is apparently to handle stuff like $a = $a->[0]. However, this
means that the mortal was added to the tmps stack of the *shared
interpreter*, which never gets freed. Adding a SAVETMPS/FREETMPS within
the shared context block of code solved the problem. 

-- 
You never really learn to swear until you learn to drive.


Change 21527 by davem@davem-percy on 2003/10/23 19:13:20

	Fix two threads::shared leaks
	#24061 - AV in shared interpreter wasn't set to AvREAL
	#24255 - mortals were added to the shared interpreter's tmpstack
		and never freed.

Affected files ...

... //depot/perl/ext/threads/shared/shared.xs#38 edit

Differences ...

==== //depot/perl/ext/threads/shared/shared.xs#38 (text) ====

@@ -308,6 +308,8 @@
     if (sv && SvTYPE(ssv) < SvTYPE(sv)) {
 	SHARED_CONTEXT;
 	sv_upgrade(ssv, SvTYPE(*psv));
+	if (SvTYPE(ssv) == SVt_PVAV)	/* #24061 */
+	    AvREAL_on(ssv);
 	CALLER_CONTEXT;
     }
 
@@ -436,6 +438,12 @@
 	if (target) {
 	    SV *tmp;
 	    SHARED_CONTEXT;
+	    /* #24255: sv_setsv() (via sv_unref_flags()) may cause a
+	     * deferred free with sv_2mortal(). Ensure that the free_tmps
+	     * is done within this inpterpreter. DAPM.
+	     */
+	    ENTER;
+	    SAVETMPS;
 	    tmp = newRV(SHAREDSvPTR(target));
 	    sv_setsv_nomg(SHAREDSvPTR(shared), tmp);
 	    SvREFCNT_dec(tmp);
@@ -444,6 +452,8 @@
 	      SvOBJECT_on(SHAREDSvPTR(target));
 	      SvSTASH(SHAREDSvPTR(target)) = (HV*)fake_stash;
 	    }
+	    FREETMPS;
+	    LEAVE;
 	    CALLER_CONTEXT;
 	}
 	else {



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About