From: David Mitchell Date: Fri, 16 Nov 2012 18:04:49 +0000 (+0000) Subject: clone() wasn't cloning the whole stack X-Git-Tag: v5.17.6~58 X-Git-Url: https://perl5.git.perl.org/perl5.git/commitdiff_plain/ba593adc2b8b59175ac3c28b7b41aef7a74908e2 clone() wasn't cloning the whole stack When cloning stacks (e.g. for fake fork), the stack is cloned by copying the stack AV pointed to by PL_curstackinfo; but the AvFILL on that AV may not be up to date, resulting in the top N items of the stack not being cloned. Fix by saving PL_stack_sp back into AvFILL(PL_curstack) before cloning --- diff --git a/ext/XS-APItest/t/clone-with-stack.t b/ext/XS-APItest/t/clone-with-stack.t index 943a123..7a0cd29 100644 --- a/ext/XS-APItest/t/clone-with-stack.t +++ b/ext/XS-APItest/t/clone-with-stack.t @@ -17,7 +17,7 @@ if (not $Config{'useithreads'}) { skip_all("clone_with_stack requires threads"); } -plan(3); +plan(4); fresh_perl_is( <<'----', <<'====', undef, "minimal clone_with_stack" ); use XS::APItest; @@ -51,3 +51,17 @@ ok ==== } + +{ + fresh_perl_is( <<'----', <<'====', undef, "clone stack" ); +use XS::APItest; +sub f { + clone_with_stack(); + 0..4; +} +print 'X-', 'Y-', join(':', f()), "-Z\n"; +---- +X-Y-0:1:2:3:4-Z +==== + +} diff --git a/sv.c b/sv.c index 682ac45..4d7219d 100644 --- a/sv.c +++ b/sv.c @@ -13493,6 +13493,11 @@ perl_clone_using(PerlInterpreter *proto_perl, UV flags, Newxz(PL_scopestack_name, PL_scopestack_max, const char *); Copy(proto_perl->Iscopestack_name, PL_scopestack_name, PL_scopestack_ix, const char *); #endif + /* reset stack AV to correct length before its duped via + * PL_curstackinfo */ + AvFILLp(proto_perl->Icurstack) = + proto_perl->Istack_sp - proto_perl->Istack_base; + /* NOTE: si_dup() looks at PL_markstack */ PL_curstackinfo = si_dup(proto_perl->Icurstackinfo, param);