Steve, John:

I did a bisect today against perl git, using mod_perl 2.0.9 and apache
2.2.29 to find out where my two issues were caused.  It turns out that
both of my problems, which were:

- panic: attempt to copy freed scalar xxxx to yyyy

and also

- segmentation fault caused by a specific "return" statement

Are *BOTH* caused by the following commit made to perl between 5.19.6
and 5.19.7:

> commit 437e3a7dac994ebace1195549170c81f474d9c20
> Author: Matthew Horsfall <wolfs...@gmail.com>
> Date:   Wed Dec 11 18:28:21 2013 -0500
> 
>     Optimise out PUSHMARK/RETURN if return is the last statement in a sub.
>     
>     This makes:
>     
>       sub baz { return $cat; }
>     
>     Behave like:
>     
>       sub baz { $cat; }
>     
>     Which is notably faster.
...

I created a patch that reverses this (at least the change to op.c.. the
other parts of the patch are just new macros, and a test case), then
both of my problems are fixed.

John:  I'd be interested to know if your problem is related.  If
possible, can you build perl with the attached patch applied and see  if
that fixes your segfault also?

This seems to be mod_perl specific.  I have a very
straightforward/minimal test case that causes the "panic" error under
mod_perl, but the same code runs fine under the command line outside of
mod_perl.

Regards,
Michael Schout
diff --git a/op.c b/op.c
index 7038526..dc42b56 100644
--- a/op.c
+++ b/op.c
@@ -11354,45 +11354,6 @@ Perl_rpeep(pTHX_ OP *o)
        case OP_NEXTSTATE:
            PL_curcop = ((COP*)o);              /* for warnings */
 
-           /* Optimise a "return ..." at the end of a sub to just be "...".
-            * This saves 2 ops. Before:
-            * 1  <;> nextstate(main 1 -e:1) v ->2
-            * 4  <@> return K ->5
-            * 2    <0> pushmark s ->3
-            * -    <1> ex-rv2sv sK/1 ->4
-            * 3      <#> gvsv[*cat] s ->4
-            *
-            * After:
-            * -  <@> return K ->-
-            * -    <0> pushmark s ->2
-            * -    <1> ex-rv2sv sK/1 ->-
-            * 2      <$> gvsv(*cat) s ->3
-            */
-           {
-               OP *next = o->op_next;
-               OP *sibling = o->op_sibling;
-               if (   OP_TYPE_IS(next, OP_PUSHMARK)
-                   && OP_TYPE_IS(sibling, OP_RETURN)
-                   && OP_TYPE_IS(sibling->op_next, OP_LINESEQ)
-                   && OP_TYPE_IS(sibling->op_next->op_next, OP_LEAVESUB)
-                   && cUNOPx(sibling)->op_first == next
-                   && next->op_sibling && next->op_sibling->op_next
-                   && next->op_next
-               ) {
-                   /* Look through the PUSHMARK's siblings for one that
-                    * points to the RETURN */
-                   OP *top = next->op_sibling;
-                   while (top && top->op_next) {
-                       if (top->op_next == sibling) {
-                           top->op_next = sibling->op_next;
-                           o->op_next = next->op_next;
-                           break;
-                       }
-                       top = top->op_sibling;
-                   }
-               }
-           }
-
            /* Optimise 'my $x; my $y;' into 'my ($x, $y);'
              *
             * This latter form is then suitable for conversion into padrange

Reply via email to