diff options
author | Gurusamy Sarathy <gsar@cpan.org> | 1999-10-09 00:41:02 +0000 |
---|---|---|
committer | Gurusamy Sarathy <gsar@cpan.org> | 1999-10-09 00:41:02 +0000 |
commit | b0d9ce3858aa1d5f16f24f50ca1172e6eb75fcd9 (patch) | |
tree | a7de3bee889a19e08ea369636a8e8b53b0bacb28 /pp_ctl.c | |
parent | a8bba7fac320f0a7f553e9a133cddd65ef2a66c7 (diff) | |
download | perl-b0d9ce3858aa1d5f16f24f50ca1172e6eb75fcd9.tar.gz |
POPSUB() gave up the refcount to the CV before LEAVE had a chance to
clear entries in the CV's pad, leading to coredumps when CV had no
other references to it; this is a slightly edited version of the
patch suggested by Russel O'Connor <roconnor@world.std.com>
p4raw-id: //depot/perl@4321
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 14 |
1 files changed, 11 insertions, 3 deletions
@@ -1187,6 +1187,7 @@ Perl_dounwind(pTHX_ I32 cxix) I32 optype; while (cxstack_ix > cxix) { + SV *sv; cx = &cxstack[cxstack_ix]; DEBUG_l(PerlIO_printf(Perl_debug_log, "Unwinding block %ld, type %s\n", (long) cxstack_ix, PL_block_type[CxTYPE(cx)])); @@ -1196,7 +1197,8 @@ Perl_dounwind(pTHX_ I32 cxix) POPSUBST(cx); continue; /* not break */ case CXt_SUB: - POPSUB(cx); + POPSUB(cx,sv); + LEAVESUB(sv); break; case CXt_EVAL: POPEVAL(cx); @@ -1700,6 +1702,7 @@ PP(pp_return) SV **newsp; PMOP *newpm; I32 optype = 0; + SV *sv; if (PL_curstackinfo->si_type == PERLSI_SORT) { if (cxstack_ix == PL_sortcxix || dopoptosub(cxstack_ix) <= PL_sortcxix) { @@ -1771,11 +1774,14 @@ PP(pp_return) /* Stack values are safe: */ if (popsub2) { - POPSUB(cx); /* release CV and @_ ... */ + POPSUB(cx,sv); /* release CV and @_ ... */ } + else + sv = Nullsv; PL_curpm = newpm; /* ... and pop $1 et al */ LEAVE; + LEAVESUB(sv); return pop_return(); } @@ -1791,6 +1797,7 @@ PP(pp_last) SV **newsp; PMOP *newpm; SV **mark; + SV *sv = Nullsv; if (PL_op->op_flags & OPf_SPECIAL) { cxix = dopoptoloop(cxstack_ix); @@ -1850,12 +1857,13 @@ PP(pp_last) LEAVE; break; case CXt_SUB: - POPSUB(cx); /* release CV and @_ ... */ + POPSUB(cx,sv); /* release CV and @_ ... */ break; } PL_curpm = newpm; /* ... and pop $1 et al */ LEAVE; + LEAVESUB(sv); return nextop; } |