summaryrefslogtreecommitdiff
path: root/pp_sys.c
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2015-10-19 16:12:33 +0100
committerDavid Mitchell <davem@iabyn.com>2016-02-03 09:18:30 +0000
commit656457d0493edca22133d31ca3c6ddbaa987e06c (patch)
treeb9c8d2bce03bc692e62dfd40ec17e56180cfea08 /pp_sys.c
parentf284fecd86b66528552854be16564b432fd1480c (diff)
downloadperl-656457d0493edca22133d31ca3c6ddbaa987e06c.tar.gz
make POPSUB and POPFORMAT re-entrant safe
In code like sub DESTROY { exit } sub f { push @_, bless [] } f() While leaving f, POPSUB will attempt to clear @_. This triggers the destructor, which calls exit, which unwinds the context stack, calling POPSUB again on thr same context stack entry. Thus we need to to be careful that POPSUB can be called multiple times on the same CX stack entry. The general way of doing this is to NULL or update pointers *before* calling SvREFCNT_dec() on the old value. This commit also removes the old CxPOPSUB_DONE mechanism which was a poor bandaid added at the last minute to 5.22 to try and achieve the basics of what this commit does comprehensively (hopefully). Also, CxPOPSUB_DONE was mainly a protection against re-entrantly calling LEAVE_SCOPE(). Since that's now done before POPSUB rather than in the middle of it, it has become reentrant-safe by default.
Diffstat (limited to 'pp_sys.c')
-rw-r--r--pp_sys.c5
1 files changed, 4 insertions, 1 deletions
diff --git a/pp_sys.c b/pp_sys.c
index 0792727ed6..99f718e522 100644
--- a/pp_sys.c
+++ b/pp_sys.c
@@ -1292,10 +1292,13 @@ of the typeglob that C<PL_defoutgv> points to is decreased by one.
void
Perl_setdefout(pTHX_ GV *gv)
{
+ GV *oldgv = PL_defoutgv;
+
PERL_ARGS_ASSERT_SETDEFOUT;
+
SvREFCNT_inc_simple_void_NN(gv);
- SvREFCNT_dec(PL_defoutgv);
PL_defoutgv = gv;
+ SvREFCNT_dec(oldgv);
}
PP(pp_select)