summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Mitchell <davem@fdisolutions.com>2004-01-17 16:12:32 +0000
committerDave Mitchell <davem@fdisolutions.com>2004-01-17 16:12:32 +0000
commitb3a3b3a1da8f5142edf3e194532b08316f895282 (patch)
treea7599adfe749d92c3c1e340401d2cf679de77a8c
parentd3dc607d97b8af5aa45522c8a75a78694d3c7733 (diff)
downloadperl-b3a3b3a1da8f5142edf3e194532b08316f895282.tar.gz
[perl #24914] freeing a CV reference that was currently being
executed caused coredumps p4raw-id: //depot/perl@22167
-rw-r--r--perl.c3
-rw-r--r--scope.c4
-rw-r--r--scope.h1
-rw-r--r--sv.c2
-rwxr-xr-xt/op/closure.t14
5 files changed, 21 insertions, 3 deletions
diff --git a/perl.c b/perl.c
index f32e346950..aa37e2f15b 100644
--- a/perl.c
+++ b/perl.c
@@ -699,6 +699,9 @@ perl_destruct(pTHXx)
SvFLAGS(PL_fdpid) |= SVTYPEMASK; /* don't clean out pid table now */
SvFLAGS(PL_strtab) |= SVTYPEMASK; /* don't clean out strtab now */
+ PL_comppad = Null(PAD*);
+ PL_curpad = Null(SV**);
+
/* the 2 is for PL_fdpid and PL_strtab */
while (PL_sv_count > 2 && sv_clean_all())
;
diff --git a/scope.c b/scope.c
index 2c2ce3698e..1da8ebe29b 100644
--- a/scope.c
+++ b/scope.c
@@ -1045,8 +1045,10 @@ Perl_leave_scope(pTHX_ I32 base)
break;
case SAVEt_COMPPAD:
PL_comppad = (PAD*)SSPOPPTR;
- if (PL_comppad)
+ if (PL_comppad) {
PL_curpad = AvARRAY(PL_comppad);
+ SvREFCNT_dec(PL_comppad);
+ }
else
PL_curpad = Null(SV**);
break;
diff --git a/scope.h b/scope.h
index 50b40faf7d..c0bd3448b8 100644
--- a/scope.h
+++ b/scope.h
@@ -167,6 +167,7 @@ Closing bracket on a callback. See C<ENTER> and L<perlcall>.
SSCHECK(2); \
SSPUSHPTR((SV*)PL_comppad); \
SSPUSHINT(SAVEt_COMPPAD); \
+ SvREFCNT_inc(PL_comppad); \
} STMT_END
#ifdef USE_ITHREADS
diff --git a/sv.c b/sv.c
index 6e64702b70..bc53cc4a23 100644
--- a/sv.c
+++ b/sv.c
@@ -10830,7 +10830,7 @@ Perl_ss_dup(pTHX_ PerlInterpreter *proto_perl, CLONE_PARAMS* param)
break;
case SAVEt_COMPPAD:
av = (AV*)POPPTR(ss,ix);
- TOPPTR(nss,ix) = av_dup(av, param);
+ TOPPTR(nss,ix) = av_dup_inc(av, param);
break;
case SAVEt_PADSV:
longval = (long)POPLONG(ss,ix);
diff --git a/t/op/closure.t b/t/op/closure.t
index 2425a59a61..f9da3114e7 100755
--- a/t/op/closure.t
+++ b/t/op/closure.t
@@ -13,7 +13,7 @@ BEGIN {
use Config;
-print "1..185\n";
+print "1..186\n";
my $test = 1;
sub test (&) {
@@ -668,4 +668,16 @@ __EOF__
END { 1 while unlink $progfile }
}
+{
+ # bugid #24914 = used to coredump restoring PL_comppad in the
+ # savestack, due to the early freeing of the anon closure
+
+ my $got = runperl(stderr => 1, prog =>
+'sub d {die} my $f; $f = sub {my $x=1; $f = 0; d}; eval{$f->()}; print qw(ok)'
+ );
+ test { $got eq 'ok' };
+}
+
+
+