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 {