From: Vincent Pit Date: Fri, 27 Mar 2015 18:47:42 +0000 (-0300) Subject: Preserve PL_scopestack[cx->blk_oldscopesp - 1] in su_pop() X-Git-Tag: v0.27~4 X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=97dc8ef80311dba0ff5058c2ee54caa8193b5c51;p=perl%2Fmodules%2FScope-Upper.git Preserve PL_scopestack[cx->blk_oldscopesp - 1] in su_pop() Starting from perl 5.19.4 commit 2537512, pp_leavesub does a second leave_scope(PL_scopestack[cx->blk_oldscopesp - 1]) just after the usual LEAVE call. However, this index in the scope stack may be overwritten by our own "flush" leave_scope() call in su_pop(). More precisely, this seems to happen in sv_clear() (called from sv_free2() called from sv_unref_flags() called from sv_force_normal_flags() called from leave_scope()) and only when the debugger is enabled. --- diff --git a/Upper.xs b/Upper.xs index 7cbbaa2..7024815 100644 --- a/Upper.xs +++ b/Upper.xs @@ -1001,9 +1001,26 @@ static void su_pop(pTHX_ void *ud) { ud, 24, ' ', mark, base)); if (base < mark) { +#if SU_HAS_PERL(5, 19, 4) + I32 save = -1; + PERL_CONTEXT *cx; +#endif + SU_D(PerlIO_printf(Perl_debug_log, "%p: clear leftovers\n", ud)); + +#if SU_HAS_PERL(5, 19, 4) + cx = cxstack + cxstack_ix; + if (CxTYPE(cx) == CXt_SUB) + save = PL_scopestack[cx->blk_oldscopesp - 1]; +#endif + PL_savestack_ix = mark; leave_scope(base); + +#if SU_HAS_PERL(5, 19, 4) + if (CxTYPE(cx) == CXt_SUB) + PL_scopestack[cx->blk_oldscopesp - 1] = save; +#endif } PL_savestack_ix = base;