New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Shared references (threads::shared) disappear on sub return #13140
Comments
From @snauryCreated by @snauryThis is a bug report for perl from snaury@gmail.com, ----------------------------------------------------------------- use strict; sub test_clone { die "not defined" unless defined(test_clone); This causes threaded perl programs on Debian 7.0 or Ubuntu 12.04 Perl Info
|
From @iabynOn Tue, Jul 30, 2013 at 10:58:36PM -0700, Alexey Borzenkov wrote:
This was fixed in perl 5.15.7 with commit You can work around the issue on older perls by assigning the value to my $ret = $ref->[0]; -- |
The RT System itself - Status changed from 'new' to 'open' |
@cpansprout - Status changed from 'open' to 'resolved' |
From @nwc10On Wed, Jul 31, 2013 at 01:10:33PM +0100, Dave Mitchell wrote:
This can be simplified to: #!./perl sub test_clone { die "not defined" unless defined test_clone;
Totally true. If assertions are enabled the test case triggers an assertion failure on So a git bisect (with assertions enabled) shows that commit 6f48390 commit 6f48390 [perl #95548] Returned magical temps are not copied So, what caused the assertions to start failing between v5.12 and v5.14? commit f2338a2 use cBOOL for bool casts which has nothing directly to do with threads shared, or (not?) copying Inline Patchdiff --git a/mg.c b/mg.c
index 3fb8ec4..4a8d767 100644
--- a/mg.c
+++ b/mg.c
@@ -193,7 +193,7 @@ Perl_mg_get(pTHX_ SV *sv)
{
dVAR;
const I32 mgs_ix = SSNEW(sizeof(MGS));
- const bool was_temp = (bool)SvTEMP(sv);
+ const bool was_temp = cBOOL(SvTEMP(sv));
bool have_new = 0;
MAGIC *newmg, *head, *cur, *mg;
/* guard against sv having being freed midway by holding a private
commit 35a4481 Adding const qualifiers (note that the commit message doesn't even note that some variables' types The variable in question is used to enable Perl_mg_get() to retain the So, all that conceals what actually going on. When that truncation bug was I set out to bisect between the two commits, patching *that* the bug to fix So I made a patch to fix the bug, and bisected with that: Porting/bisect.pl -Dusethreads --start f9c6fee --end db63319 --late-fixup ../119089-W -Dnoextensions=Encode ../perl/119089 That reveals that the true trigger of the behaviour regression was this commit fd69380 Fix assorted bugs related to magic (such as pos) not "sticking" to The key part is this: Inline Patchdiff --git a/pp_hot.c b/pp_hot.c
index 3371e88..8f8af53 100644
--- a/pp_hot.c
+++ b/pp_hot.c
@@ -658,7 +658,7 @@ PP(pp_aelemfast)
SV *sv = (svp ? *svp : &PL_sv_undef);
EXTEND(SP, 1);
if (!lval && SvGMAGICAL(sv)) /* see note in pp_helem() */
- sv = sv_mortalcopy(sv);
+ mg_get(sv);
PUSHs(sv);
RETURN;
}
The story is not over. So, I assumed that taking blead, and reverting the patch that fixes the test commit 4bac9ae Magic flags harmonization. because part of it removes the entire was_temp (micro?) optimisation logic: @@ -3302,12 +3285,8 @@ S_restore_magic(pTHX_ const void *p) meaning that values will always be copied. (Given the nature of the first commit identified as a bug fix, this seems So that explains the given test case. But the story is still not over. Whilst temporary values should be copied (by default), LVALUEs returned from #!./perl sub test_clone :lvalue { #Dump(test_clone); I believe that the problem is because threads::shared wrongly assumes that I believe that the fix is to change threads::shared to deal with cleanup Inline Patchdiff --git a/dist/threads-shared/shared.xs b/dist/threads-shared/shared.xs
index d3e859d..07379cc 100644
--- a/dist/threads-shared/shared.xs
+++ b/dist/threads-shared/shared.xs
@@ -1027,6 +1027,27 @@ sharedsv_elem_mg_DELETE(pTHX_ SV *sv, MAGIC *mg)
return (0);
}
+int
+sharedsv_elem_mg_free(pTHX_ SV *sv, MAGIC *mg)
+{
+ dTHXc;
+ PERL_UNUSED_ARG(sv);
+ ENTER_LOCK;
+ if (mg->mg_obj) {
+ if (!PL_dirty) {
+ assert(SvROK(mg->mg_obj));
+ }
+ if (SvREFCNT(mg->mg_obj) == 1) {
+ /* If the element has the last pointer to the shared aggregate, then
+ it has to free the shared aggregate. mg->mg_obj itself is freed
+ by Perl_mg_free() */
+ S_sharedsv_dec(aTHX_ SHAREDSV_FROM_OBJ(mg->mg_obj));
+ }
+ }
+ LEAVE_LOCK;
+ return (0);
+}
+
/* Called during cloning of PERL_MAGIC_tiedelem(p) magic in new
* thread */
@@ -1044,7 +1065,7 @@ MGVTBL sharedsv_elem_vtbl = {
sharedsv_elem_mg_STORE, /* set */
0, /* len */
sharedsv_elem_mg_DELETE, /* clear */
- 0, /* free */
+ sharedsv_elem_mg_free, /* free */
0, /* copy */
sharedsv_elem_mg_dup, /* dup */
#ifdef MGf_LOCAL
@@ -1114,7 +1135,21 @@ int
sharedsv_array_mg_free(pTHX_ SV *sv, MAGIC *mg)
{
PERL_UNUSED_ARG(sv);
- S_sharedsv_dec(aTHX_ (SV*)mg->mg_ptr);
+ if (!PL_dirty) {
+ assert(mg->mg_obj);
+ assert(SvROK(mg->mg_obj));
+ assert(SvUV(SvRV(mg->mg_obj)) == PTR2UV(mg->mg_ptr));
+ }
+ if (mg->mg_obj) {
+ if (SvREFCNT(mg->mg_obj) == 1) {
+ S_sharedsv_dec(aTHX_ (SV*)mg->mg_ptr);
+ } else {
+ /* An element of this aggregate still has PERL_MAGIC_tied(p)
+ pointing to this shared aggregate. It will take responsibility
+ for freeing the shared aggregate. Perl_mg_free() drops the
+ reference count on mg->mg_obj. */
+ }
+ }
return (0);
}
I think that it doesn't introduce any leaks, but I'd appreciate a second pair This fix to threads::shared has the side effect of also fixing the original Nicholas Clark * Global destruction. threads::shared does not clean up "shared space", even |
From @cpansproutOn Mon Aug 05 07:20:37 2013, nicholas wrote:
It looks correct to me, but: -- Father Chrysostomos |
From @iabynOn Mon, Aug 05, 2013 at 03:19:44PM +0100, Nicholas Clark wrote:
Your fix looks plausible to me. I had a quick play with trying to break blead in other ways; I though this use threads (); my $r; So I feel less confident that I understand the issue fully.
I think the ENTER_LOCK and LEAVE_LOCK are superfluous in this function;
IIUC, sharedsv_elem_mg_free() and sharedsv_array_mg_free() should be -- |
From @iabynre-opening this ticket as it has an unapplied patch |
@iabyn - Status changed from 'resolved' to 'open' |
From @jmdhOn Mon Aug 05 08:32:28 2013, sprout wrote:
I understand that there won't be another 5.14 release for this, but in Thanks, |
From @jmdhOn Sat, Sep 07, 2013 at 10:22:20AM -0700, Dominic Hargreaves via RT wrote:
FWIW, I tried applying it to the Debian 5.14 and got: dist/threads-shared/t/av_refs..................................../../t/perl: symbol lookup error: ../../lib/auto/threads/shared/shared.so: undefined symbol: SHAREDSV_FROM_OBJ dist/threads-shared/t/clone....................................../../t/perl: symbol lookup error: ../../lib/auto/threads/shared/shared.so: undefined symbol: SHAREDSV_FROM_OBJ dist/threads-shared/t/hv_refs..................................../../t/perl: symbol lookup error: ../../lib/auto/threads/shared/shared.so: undefined symbol: SHAREDSV_FROM_OBJ dist/threads-shared/t/shared_attr................................/../t/perl: symbol lookup error: ../../lib/auto/threads/shared/shared.so: undefined symbol: SHAREDSV_FROM_OBJ Dominic. |
From @nwc10On Sat, Sep 07, 2013 at 07:25:39PM +0100, Dominic Hargreaves wrote:
You applied the patch to Debian? Or you built the current threads-shared Because that macro was added to threads::shared in version 1.42, which in commit 28399f5 Upgrade to threads::shared 1.42 That commit has this: -STATIC SV * So you might be OK changing all SHAREDSV_FROM_OBJ(sv) to Nicholas Clark |
From @jmdhOn Fri, Sep 13, 2013 at 02:26:57PM +0100, Nicholas Clark wrote:
The former.
Aha. Thanks for the hint! I've updated the patch and the this now http://anonscm.debian.org/gitweb/?p=perl/perl.git;a=shortlog;h=refs/heads/bug-718438 And the original test case from the reporter on the Debian bug now Cheers, |
From @jdheddenOn Sat Sep 14 16:09:05 2013, dom wrote:
|
From @jkeenanOn Mon Sep 30 08:43:03 2013, jdhedden@gmail.com wrote:
Doing so now. Thanks for the feedback. |
@jkeenan - Status changed from 'open' to 'resolved' |
@nwc10 - Status changed from 'resolved' to 'open' |
From @nwc10On Mon, Sep 30, 2013 at 08:43:04AM -0700, Jerry D. Hedden via RT wrote:
Actually it can't yet, because the patch isn't yet in blead. No-one Nicholas Clark |
From @jmdhOn Tue Oct 01 06:30:56 2013, nicholas wrote:
Hmm, I can't see the subsequent question from Dave on this ticket. I'd Cheers, |
From @tonycozOn Fri Oct 04 06:10:26 2013, dom wrote:
I think he meant: https://rt-archive.perl.org/perl5/Ticket/Display.html?id=119089#txn-1243579 I'm not sure about the correctness of the patch, but I think Dave's "why doesn't use threads (); which does break. Tony |
From @iabynOn Thu, Nov 14, 2013 at 04:14:37PM -0800, Tony Cook via RT wrote:
There was a followup from Nicholas which doesn't seem to have made it into Message-ID: <20131007123705.GE66035@plum.flirble.org> -- |
Migrated from rt.perl.org#119089 (status was 'open')
Searchable as RT119089$
The text was updated successfully, but these errors were encountered: