diff options
author | Dave Mitchell <davem@fdisolutions.com> | 2004-01-20 00:16:42 +0000 |
---|---|---|
committer | Dave Mitchell <davem@fdisolutions.com> | 2004-01-20 00:16:42 +0000 |
commit | b36bdecab13f885c556206f71bfc47083b33107e (patch) | |
tree | cf1e451df96791b01c3da200598c5312387dbbcc | |
parent | 1bf2966364b6356e9050b17d8920dd4a8ce27d97 (diff) | |
download | perl-b36bdecab13f885c556206f71bfc47083b33107e.tar.gz |
second attempt to fix [perl #24914] freeing a CV reference that was
currently being executed caused coredumps. The dounwind called by
die unwinds all the contexts on the context stack before unwinding
the save stack. To stop premature freeing of the CV, hold
references to it on both stacks.
p4raw-id: //depot/perl@22182
-rw-r--r-- | cop.h | 13 | ||||
-rw-r--r-- | pp_ctl.c | 1 | ||||
-rw-r--r-- | pp_hot.c | 4 | ||||
-rw-r--r-- | pp_sort.c | 2 | ||||
-rwxr-xr-x | t/op/closure.t | 14 |
5 files changed, 25 insertions, 9 deletions
@@ -121,11 +121,20 @@ struct block_sub { PAD *oldcomppad; }; -/* base for the next two macros. Don't use directly */ +/* base for the next two macros. Don't use directly. + * Note that the refcnt of the cv is incremented twice; The CX one is + * decremented by LEAVESUB, the other by LEAVE. */ + #define PUSHSUB_BASE(cx) \ cx->blk_sub.cv = cv; \ cx->blk_sub.olddepth = CvDEPTH(cv); \ - cx->blk_sub.hasargs = hasargs; + cx->blk_sub.hasargs = hasargs; \ + if (!CvDEPTH(cv)) { \ + (void)SvREFCNT_inc(cv); \ + (void)SvREFCNT_inc(cv); \ + SAVEFREESV(cv); \ + } + #define PUSHSUB(cx) \ PUSHSUB_BASE(cx) \ @@ -1701,7 +1701,6 @@ PP(pp_dbstate) PUSHBLOCK(cx, CXt_SUB, SP); PUSHSUB_DB(cx); CvDEPTH(cv)++; - (void)SvREFCNT_inc(cv); PAD_SET_CUR(CvPADLIST(cv),1); RETURNOP(CvSTART(cv)); } @@ -2663,9 +2663,7 @@ PP(pp_entersub) * Owing the speed considerations, we choose instead to search for * the cv using find_runcv() when calling doeval(). */ - if (CvDEPTH(cv) < 2) - (void)SvREFCNT_inc(cv); - else { + if (CvDEPTH(cv) >= 2) { PERL_STACK_OVERFLOW_CHECK(); pad_push(padlist, CvDEPTH(cv), 1); } @@ -1524,8 +1524,6 @@ PP(pp_sort) cx->cx_type = CXt_SUB; cx->blk_gimme = G_SCALAR; PUSHSUB(cx); - if (!CvDEPTH(cv)) - (void)SvREFCNT_inc(cv); /* in preparation for POPSUB */ } PL_sortcxix = cxstack_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' }; +} + + + |