This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
[perl #70614] Seg. fault with eval/use/UNITCHECK/DESTROY/eval combination
authorFather Chrysostomos <sprout@cpan.org>
Thu, 23 Sep 2010 06:47:11 +0000 (23:47 -0700)
committerFather Chrysostomos <sprout@cpan.org>
Thu, 23 Sep 2010 06:47:11 +0000 (23:47 -0700)
This case can be reduced to:
eval "UNITCHECK{ eval 0 }"

(eval 0 triggers the bug more reliably than eval ''.)

The inner eval clobbers PL_eval_start, so when the UNITCHECK finishes,
the outer eval tries to call the inner eval’s code, which has been
freed already.

This commit saves PL_eval_start and restores it after UNITCHECK.

pp_ctl.c
t/op/blocks.t

index 0a9dcfe..601a25c 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -3255,8 +3255,11 @@ S_doeval(pTHX_ int gimme, OP** startop, CV* outside, U32 seq)
        }
     }
 
-    if (PL_unitcheckav)
+    if (PL_unitcheckav) {
+       OP *es = PL_eval_start;
        call_list(PL_scopestack_ix, PL_unitcheckav);
+       PL_eval_start = es;
+    }
 
     /* compiled okay, so do it */
 
index 476d9ea..717be4c 100644 (file)
@@ -6,7 +6,7 @@ BEGIN {
     require './test.pl';
 }
 
-plan tests => 3;
+plan tests => 4;
 
 my @expect = qw(
 b1
@@ -105,3 +105,7 @@ sub CHECK {print ":check"}
 sub INIT {print ":init"}
 sub END {print ":end"}
 SCRIPT3
+
+fresh_perl_is(<<'SCRIPT70614', "still here",{switches => [''], stdin => '', stderr => 1 },'eval-UNITCHECK-eval (bug 70614)');
+eval "UNITCHECK { eval 0 }"; print "still here";
+SCRIPT70614