This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #109718] Clone PL_comppad properly
authorFather Chrysostomos <sprout@cpan.org>
Tue, 10 Apr 2012 03:11:47 +0000 (20:11 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Tue, 10 Apr 2012 21:52:59 +0000 (14:52 -0700)
fork emulation on Windows, which clones a new thread via
perl_clone_using, expects to be able to access the current pad imme-
diately after the cloning, and crashes if there is no current pad.

PL_comppad was not being cloned explicitly, but simply looked up in
the pointer table, it being assumed that it had already been cloned.

For string evals, before commit 676a678, PL_compcv happened to point
to the eval’s CV.  PL_compcv is cloned just before PL_comppad is set,
so that worked.

As of commit 676a678, PL_compcv does not point to the eval’s CV
at the eval’s run time, so the pad has not been cloned yet when
PL_comppad is set.

In the case of string evals, the CV does get cloned, but later on,
after PL_comppad is set, when the stacks are cloned.

Changing the setting of PL_comppad to do an actual cloning works, as,
when the eval’s CV is cloned later (during stack cloning), it will
simply pick up the pad that has already been cloned and is waiting for
it in the pointer table.

This stops eval 'fork' from crashing on Windows.

pad.h

diff --git a/pad.h b/pad.h
index ddde4d7..aa6521f 100644 (file)
--- a/pad.h
+++ b/pad.h
@@ -338,7 +338,7 @@ Clone the state variables associated with running and compiling pads.
  * sub's CV or padlist. */
 
 #define PAD_CLONE_VARS(proto_perl, param)                              \
-    PL_comppad = MUTABLE_AV(ptr_table_fetch(PL_ptr_table, proto_perl->Icomppad)); \
+    PL_comppad                 = av_dup(proto_perl->Icomppad, param);  \
     PL_curpad = PL_comppad ?  AvARRAY(PL_comppad) : NULL;              \
     PL_comppad_name            = av_dup(proto_perl->Icomppad_name, param); \
     PL_comppad_name_fill       = proto_perl->Icomppad_name_fill;       \