From: Vincent Pit Date: Sun, 19 Dec 2010 23:54:15 +0000 (+0100) Subject: Fix stack corruption when using unwind() under Devel::NYTProf X-Git-Tag: rt61904 X-Git-Url: http://git.vpit.fr/?a=commitdiff_plain;h=0a5344226fbb976549bdc6bd777bd6ee3563ea7c;p=perl%2Fmodules%2FScope-Upper.git Fix stack corruption when using unwind() under Devel::NYTProf This fixes RT #61904. Thanks Sergey Aleynikov for contributing the fix. --- diff --git a/Upper.xs b/Upper.xs index 24e3f0a..47dab2b 100644 --- a/Upper.xs +++ b/Upper.xs @@ -120,11 +120,12 @@ #define MY_CXT_KEY __PACKAGE__ "::_guts" XS_VERSION typedef struct { - char *stack_placeholder; - I32 cxix; - I32 items; - SV **savesp; - OP fakeop; + char *stack_placeholder; + I32 cxix; + I32 items; + SV **savesp; + LISTOP return_op; + OP proxy_op; } my_cxt_t; START_MY_CXT @@ -757,11 +758,13 @@ STATIC void su_unwind(pTHX_ void *ud_) { items, PL_stack_sp - PL_stack_base, *PL_markstack_ptr, mark); }); - PL_op = PL_ppaddr[OP_RETURN](aTHX); + PL_op = (OP *) &(MY_CXT.return_op); + PL_op = PL_op->op_ppaddr(aTHX); + *PL_markstack_ptr = mark; - MY_CXT.fakeop.op_next = PL_op; - PL_op = &(MY_CXT.fakeop); + MY_CXT.proxy_op.op_next = PL_op; + PL_op = &(MY_CXT.proxy_op); } /* --- XS ------------------------------------------------------------------ */ @@ -878,8 +881,18 @@ BOOT: HV *stash; MY_CXT_INIT; + MY_CXT.stack_placeholder = NULL; + /* NewOp() calls calloc() which just zeroes the memory with memset(). */ + Zero(&(MY_CXT.return_op), 1, sizeof(MY_CXT.return_op)); + MY_CXT.return_op.op_type = OP_RETURN; + MY_CXT.return_op.op_ppaddr = PL_ppaddr[OP_RETURN]; + + Zero(&(MY_CXT.proxy_op), 1, sizeof(MY_CXT.proxy_op)); + MY_CXT.proxy_op.op_type = OP_STUB; + MY_CXT.proxy_op.op_ppaddr = NULL; + stash = gv_stashpv(__PACKAGE__, 1); newCONSTSUB(stash, "TOP", newSViv(0)); newCONSTSUB(stash, "SU_THREADSAFE", newSVuv(SU_THREADSAFE));