-
Notifications
You must be signed in to change notification settings - Fork 560
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
SegFault in perl 5.010 -5.14.1 #11844
Comments
From 0body0@rambler.ruperl crushed with segfault Summary of my perl5 (revision 5 version 14 subversion 1) configuration: Platform: Characteristics of this binary (from libperl): |
From @cpansproutOn Tue Jan 03 00:21:56 2012, grian wrote:
Here is a simpler test case: { my %connections; Under a debugging build of blead, it gives: Assertion failed: (array), function Perl_hfree_next_entry, file hv.c, The hash is being freed while it is being cleared. The hash-clearing The same problem happens with arrays: { my %connections; Output: Attempt to free unreferenced scalar: SV 0x826e50, Perl interpreter: The most naïve way to fix this would be to increase the reference count Alternatively, since hv_clear and av_clear could check the reference What does Dave Mitchell think? -- Father Chrysostomos |
The RT System itself - Status changed from 'new' to 'open' |
From @cpansproutOn Tue Jan 03 09:56:54 2012, sprout wrote:
Argh!! RT suffers from the Unicode Bug. -- Father Chrysostomos |
From [Unknown Contact. See original ticket]On Tue Jan 03 09:56:54 2012, sprout wrote:
Argh!! RT suffers from the Unicode Bug. -- Father Chrysostomos |
From zefram@fysh.orgFather Chrysostomos via RT wrote:
That would be an unwarranted assumption that the address of the freed -zefram |
From @nwc10On Tue, Jan 03, 2012 at 09:56:55AM -0800, Father Chrysostomos via RT wrote:
I'm not Dave, nor do I play him on TV*, but neither of these approaches make The following suggestion might also make people uncomfortable, but it strikes Then, iterate over the guts of the HV or AV and free up the scalars it used Dangers of this I can see to avoid 1: The intermediate stage holds references to the (ex) body and the SVs within. 2: Dealing (in some way) with anything that attempts to insert new elements Nicholas Clark * and I'm replying to my e-mail backlog in a very non-deterministic order, |
From @nwc10On Tue, Jan 03, 2012 at 09:58:02AM -0800, Father Chrysostomos via RT wrote:
The version of RT that rt.perl.org runs definitely exhibits some bugs. It's a couple of versions behind the current, but I'm told that upgrading it So I don't know if it's like MySQL (fixed in the next release) Nicholas Clark |
From @cpansproutOn Tue Jan 03 10:48:40 2012, nicholas wrote:
Yes, this has been bothering me for some time now. The fact that
Well, if we make it appear atomic, then logically the freeing of the For arrays, the solution might be as simple as: ENTER; -- Father Chrysostomos |
From @cpansproutOn Tue Jan 03 12:39:54 2012, sprout wrote:
(and free AvARRAY of course) -- Father Chrysostomos |
From @iabynOn Tue, Jan 03, 2012 at 12:42:51PM -0800, Father Chrysostomos via RT wrote: Just for those playing along at home, the example can be reduced to sub A::DESTROY{ $ra = 0 } and it concerns the code that empties an array or hash (av_undef, The main options seem to be: 1 to temporarily increase the refcnt of the array/hash being emptied; I like (1). It's simple to implement, and its only cost is that (2) I don't like, in that we used to have something similar for HVs (3) I don't like, as it means to clear a large array we have to -- |
From @cpansproutOn Wed Jan 04 09:15:14 2012, davem wrote:
For hashes, yes. For undef @$ra, yes. For @$ra = (), it�s a little case SVt_PVAV: So, if av_clear has an ENTER/LEAVE pair, the array will be freed by the But what should @$ra = ('a'..'z') do in that case? What about %$ra = ('a'..'z'), which crashes even with my local fix for sub A::DESTROY { $::ra = 0 } How about making the stash refcounted? :-) If we did that, it would fix Is adding ENTER/LEAVE worthwhile, considering it is just a variation of This is the twenty-third bug report in this category. Attached is my unfinished patch, since this is a convenient place to put -- Father Chrysostomos |
From @cpansproutInline Patchdiff --git a/av.c b/av.c
index 733bbd4..88f796a 100644
--- a/av.c
+++ b/av.c
@@ -431,6 +431,7 @@ Perl_av_clear(pTHX_ register AV *av)
{
dVAR;
I32 extra;
+ bool real;
PERL_ARGS_ASSERT_AV_CLEAR;
assert(SvTYPE(av) == SVt_PVAV);
@@ -456,9 +457,11 @@ Perl_av_clear(pTHX_ register AV *av)
if (AvMAX(av) < 0)
return;
- if (AvREAL(av)) {
+ if ((real = !!AvREAL(av))) {
SV** const ary = AvARRAY(av);
I32 index = AvFILLp(av) + 1;
+ ENTER;
+ SAVEFREESV(SvREFCNT_inc_simple_NN(av));
while (index) {
SV * const sv = ary[--index];
/* undef the slot before freeing the value, because a
@@ -473,7 +476,7 @@ Perl_av_clear(pTHX_ register AV *av)
AvARRAY(av) = AvALLOC(av);
}
AvFILLp(av) = -1;
-
+ if (real) LEAVE;
}
/*
@@ -487,6 +490,8 @@ Undefines the array. Frees the memory used by the array itself.
void
Perl_av_undef(pTHX_ register AV *av)
{
+ bool real;
+
PERL_ARGS_ASSERT_AV_UNDEF;
assert(SvTYPE(av) == SVt_PVAV);
@@ -494,8 +499,10 @@ Perl_av_undef(pTHX_ register AV *av)
if (SvTIED_mg((const SV *)av, PERL_MAGIC_tied))
av_fill(av, -1);
- if (AvREAL(av)) {
+ if ((real = !!AvREAL(av))) {
register I32 key = AvFILLp(av) + 1;
+ ENTER;
+ SAVEFREESV(SvREFCNT_inc_simple_NN(av));
while (key)
SvREFCNT_dec(AvARRAY(av)[--key]);
}
@@ -506,6 +513,7 @@ Perl_av_undef(pTHX_ register AV *av)
AvMAX(av) = AvFILLp(av) = -1;
if(SvRMAGICAL(av)) mg_clear(MUTABLE_SV(av));
+ if(real) LEAVE;
}
/*
diff --git a/hv.c b/hv.c
index 9c5670b..011a23c 100644
--- a/hv.c
+++ b/hv.c
@@ -1681,12 +1681,20 @@ S_hfreeentries(pTHX_ HV *hv)
STRLEN index = 0;
XPVHV * const xhv = (XPVHV*)SvANY(hv);
SV *sv;
+ const bool save = !!SvREFCNT(hv);
PERL_ARGS_ASSERT_HFREEENTRIES;
+ if (save) {
+ ENTER;
+ SAVEFREESV(SvREFCNT_inc_simple_NN(hv));
+ }
+
while ((sv = Perl_hfree_next_entry(aTHX_ hv, &index))||xhv->xhv_keys) {
SvREFCNT_dec(sv);
}
+
+ if (save) LEAVE;
}
diff --git a/t/op/array.t b/t/op/array.t
index b53da80..1ae2b2a 100644
--- a/t/op/array.t
+++ b/t/op/array.t
@@ -3,11 +3,10 @@
BEGIN {
chdir 't' if -d 't';
@INC = ('.', '../lib');
+ require 'test.pl';
}
-require 'test.pl';
-
-plan (123);
+plan (125);
#
# @foo, @bar, and @ary are also used from tie-stdarray after tie-ing them
@@ -441,4 +440,13 @@ sub test_arylen {
*trit = *scile; $trit[0];
ok(1, 'aelem_fast on a nonexistent array does not crash');
+# [perl #107440]
+sub A::DESTROY { $::ra = 0 }
+$::ra = [ bless [], 'A' ];
+undef @$::ra;
+pass 'no crash when freeing array that is being undeffed';
+$::ra = [ bless [], 'A' ];
+@$::ra = ();
+pass 'no crash when freeing array that is being cleared';
+
"We're included by lib/Tie/Array/std.t so we need to return something true";
diff --git a/t/op/hash.t b/t/op/hash.t
index 1e8c6b2..3d4c5e7 100644
--- a/t/op/hash.t
+++ b/t/op/hash.t
@@ -8,7 +8,7 @@ BEGIN {
use strict;
-plan tests => 13;
+plan tests => 15;
my %h;
@@ -208,3 +208,12 @@ SKIP: {
}
is $ref, undef, 'weak refs to pad hashes go stale on scope exit';
}
+
+# [perl #107440]
+sub A::DESTROY { $::ra = 0 }
+$::ra = {a=>bless [], 'A'};
+undef %$::ra;
+pass 'no crash when freeing hash that is being undeffed';
+$::ra = {a=>bless [], 'A'};
+%$::ra = ();
+pass 'no crash when freeing hash that is being exonerated, ahem, cleared'; |
From 0body0@rambler.ruA little question about first solution: ENTER/SAVEFREESV/LEAVE, may be SAVEFREESV is enough? 04.01.2012 21:15, Dave Mitchell via RT пи�е�:
|
From 0body0@rambler.ruYou all are interesting people ... The problem was huge in my eyes. I think first case (1) is the best of all. It give Perl a little time to work with SV, before destroying it. Anatoliy. 04.01.2012 21:15, Dave Mitchell via RT пи�е�:
|
From 0body0@rambler.ru05.01.2012 10:30, Father Chrysostomos via RT пи�е�:
What if we simply delay freeing AV/HV until OP(nextstate) ? |
From @cpansproutOn Thu Jan 05 01:19:36 2012, grian wrote:
av_clear, etc., are not necessarily called directly from a perl That would be bad if it happens with %^H. I�m wondering now whether we need ENTER/SAVEFREESV/LEAVE inside -- Father Chrysostomos |
From @cpansproutOn Thu Jan 05 06:21:04 2012, sprout wrote:
Actually, the simplest solution seem to be to put the av or hv on the In those cases we are directly inside a runloop, so it will be freed soon. My concern with %^H had to do with arbitrary code elsewhere making %^H I�ve made this change with commit 9f71cfe. -- Father Chrysostomos |
@cpansprout - Status changed from 'open' to 'resolved' |
From johngrahamalvord@gmail.comOn Friday, January 6, 2012, Father Chrysostomos via RT <
|
From @iabynOn Fri, Jan 06, 2012 at 05:22:31PM -0800, Father Chrysostomos via RT wrote:
This makes me nervous. The tmps stack is typically cleared only on * user-visible delaying of freeing elements; Surely an ENTER/SAVEFREESV/LEAVE inside pp_aassign is just as efficient, Also, although pp_aassign and pp_undef are now fixed, the -- |
From @cpansproutOn Sun Jan 08 14:40:49 2012, davem wrote:
I�ve made the changes with commits 60edcf0 and 8b9a115. -- Father Chrysostomos |
Migrated from rt.perl.org#107440 (status was 'resolved')
Searchable as RT107440$
The text was updated successfully, but these errors were encountered: