Skip to content

Commit

Permalink
make MULTICALL safe across cxstack reallocs
Browse files Browse the repository at this point in the history
[perl #115602]
MUTLICALL sets a local var, cx, to point to the current context stack
frame. When a function is called, the context stack might be realloc()ed,
in which case cx would point to freed memory.
  • Loading branch information
iabyn committed Nov 11, 2012
1 parent 285c5e4 commit 3d26b81
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 2 deletions.
3 changes: 2 additions & 1 deletion cop.h
Expand Up @@ -1217,7 +1217,8 @@ See L<perlcall/LIGHTWEIGHT CALLBACKS>.

#define POP_MULTICALL \
STMT_START { \
if (! ((CvDEPTH(multicall_cv) = cx->blk_sub.olddepth)) ) { \
cx = &cxstack[cxstack_ix]; \
if (! ((CvDEPTH(multicall_cv) = cx->blk_sub.olddepth)) ) { \
LEAVESUB(multicall_cv); \
} \
POPBLOCK(cx,PL_curpm); \
Expand Down
15 changes: 14 additions & 1 deletion ext/XS-APItest/t/multicall.t
Expand Up @@ -7,7 +7,7 @@
use warnings;
use strict;

use Test::More tests => 6;
use Test::More tests => 7;
use XS::APItest;


Expand Down Expand Up @@ -48,3 +48,16 @@ use XS::APItest;
is($destroyed, 1, "f now destroyed");

}

# [perl #115602]
# deep recursion realloced the CX stack, but the dMULTICALL local var
# 'cx' still pointed to the old one.
# Thius doesn;t actually test the failure (I couldn't think of a way to
# get the failure to show at the perl level) but it allows valgribnd or
# similar to spot any errors.

{
sub rec { my $c = shift; rec($c-1) if $c > 0 };
my @r = XS::APItest::multicall_each { rec(90) } 1,2,3;
pass("recursion");
}

0 comments on commit 3d26b81

Please sign in to comment.