1#!./perl -w 2 3# Check that lines from eval are correctly retained by the debugger 4 5# Uncomment this for testing, but don't leave it in for "production", as 6# we've not yet verified that use works. 7# use strict; 8 9print "1..109\n"; 10my $test = 0; 11 12sub failed { 13 my ($got, $expected, $name) = @_; 14 15 print "not ok $test - $name\n"; 16 my @caller = caller(1); 17 print "# Failed test at $caller[1] line $caller[2]\n"; 18 if (defined $got) { 19 print "# Got '$got'\n"; 20 } else { 21 print "# Got undef\n"; 22 } 23 print "# Expected $expected\n"; 24 return; 25} 26 27sub is($$$) { 28 my ($got, $expect, $name) = @_; 29 $test = $test + 1; 30 if (defined $expect) { 31 if (defined $got && $got eq $expect) { 32 print "ok $test - $name\n"; 33 return 1; 34 } 35 failed($got, "'$expect'", $name); 36 } else { 37 if (!defined $got) { 38 print "ok $test - $name\n"; 39 return 1; 40 } 41 failed($got, 'undef', $name); 42 } 43} 44 45$^P = 0xA; 46 47my @before = grep { /eval/ } keys %::; 48 49is ((scalar @before), 0, "No evals"); 50 51my %seen; 52 53sub check_retained_lines { 54 my ($prog, $name) = @_; 55 # Is there a more efficient way to write this? 56 my @expect_lines = (undef, map ({"$_\n"} split "\n", $prog), "\n", ';'); 57 58 # sort in decreasing number so that $keys[0] is the from the most 59 # recent eval. In theory we should only have one, but if something 60 # breaks we might have more than one, and keys will return them in a 61 # random order, so if we dont do this then failing tests will have 62 # inconsistent results from run to run. 63 my @keys = map { $_->[0] } 64 sort { $b->[1] <=> $a->[1] } 65 map { (!$seen{$_} and /eval (\d+)/) ? [ $_, $1 ] : () } 66 keys %::; 67 68 is ((scalar @keys), 1, "1 new eval"); 69 70 my @got_lines = @{$::{$keys[0]}}; 71 72 is ((scalar @got_lines), 73 (scalar @expect_lines), "Right number of lines for $name"); 74 75 for (0..$#expect_lines) { 76 is ($got_lines[$_], $expect_lines[$_], "Line $_ is correct"); 77 } 78 # if we are "leaking" evals we only want to fail the current test, 79 # so we need to mark them all seen (older code only marked $keys[0] 80 # seen and this caused tests to fail that actually worked properly.) 81 $seen{$_}++ for @keys; 82} 83 84my $name = 'foo'; 85 86for my $sep (' ', "\0") { 87 88 my $prog = "sub $name { 89 'Perl${sep}Rules' 90}; 911; 92"; 93 94 eval $prog or die; 95 check_retained_lines($prog, ord $sep); 96 $name++; 97} 98 99{ 100 # This contains a syntax error 101 my $prog = "sub $name { 102 'This is $name' 103 } 104# 10 errors to triger a croak during compilation. 1051 +; 1 +; 1 +; 1 +; 1 +; 1061 +; 1 +; 1 +; 1 +; 1 +; 1071 +; # and one more for good measure. 108"; 109 110 eval $prog and die; 111 112 is (eval "$name()", "This is $name", "Subroutine was compiled, despite error") 113 or print STDERR "# $@\n"; 114 115 check_retained_lines($prog, 116 'eval that defines subroutine but has syntax error'); 117 $name++; 118} 119 120foreach my $flags (0x0, 0x800, 0x1000, 0x1800) { 121 local $^P = $^P | $flags; 122 # This is easier if we accept that the guts eval will add a trailing \n 123 # for us 124 my $prog = "1 + 1 + 1\n"; 125 my $fail = "1 +;\n" x 11; # we need 10 errors to trigger a croak during 126 # compile, we add an extra one just for good 127 # measure. 128 129 is (eval $prog, 3, 'String eval works'); 130 if ($flags & 0x800) { 131 check_retained_lines($prog, sprintf "%#X", $^P); 132 } else { 133 my @after = grep { /eval/ } keys %::; 134 135 is (scalar @after, 0 + keys %seen, 136 "evals that don't define subroutines are correctly cleaned up"); 137 } 138 139 is (eval $fail, undef, 'Failed string eval fails'); 140 141 if ($flags & 0x1000) { 142 check_retained_lines($fail, sprintf "%#X", $^P); 143 } else { 144 my @after = grep { /eval/ } keys %::; 145 146 is (scalar @after, 0 + keys %seen, 147 "evals that fail are correctly cleaned up"); 148 } 149} 150 151# BEGIN blocks that die 152for (0xA, 0) { 153 local $^P = $_; 154 155 eval (my $prog = "BEGIN{die}\n"); 156 157 if ($_) { 158 check_retained_lines($prog, 'eval that defines BEGIN that dies'); 159 } 160 else { 161 my @after = grep { /eval/ } keys %::; 162 163 is (scalar @after, 0 + keys %seen, 164 "evals with BEGIN{die} are correctly cleaned up"); 165 } 166} 167 168for (0xA, 0) { 169 local $^P = $_; 170 171 eval (my $prog = "UNITCHECK{die}\n"); 172 is (!!$@, 1, "Is \$@ true?"); 173 is ($@=~/UNITCHECK failed--call queue aborted/, 1, 174 "Error is expected value?"); 175 176 if ($_) { 177 check_retained_lines($prog, 'eval that defines UNITCHECK that dies'); 178 } 179 else { 180 my @after = grep { /eval/ } keys %::; 181 182 is (scalar @after, 0 + keys %seen, 183 "evals with UNITCHECK{die} are correctly cleaned up"); 184 } 185} 186 187 188# [perl #79442] A #line "foo" directive in a string eval was not updating 189# *{"_<foo"} in threaded perls, and was not putting the right lines into 190# the right elements of @{"_<foo"} in non-threaded perls. 191{ 192 local $^P = 0x400|0x100|0x10; 193 eval qq{#line 42 "hash-line-eval"\n labadalabada()\n}; 194 is $::{"_<hash-line-eval"}[42], " labadalabada()\n", 195 '#line 42 "foo" in a string eval updates @{"_<foo"}'; 196 eval qq{#line 42 "figgle"\n#line 85 "doggo"\n labadalabada()\n}; 197 is $::{"_<doggo"}[85], " labadalabada()\n", 198 'subsequent #line 42 "foo" in a string eval updates @{"_<foo"}'; 199} 200 201# Modifying ${"_<foo"} should not stop lines from being retained. 202{ 203 local $^P = 0x400|0x100|0x10; 204 eval <<'end'; 205#line 42 "copfilesv-modification" 206 BEGIN{ ${"_<copfilesv-modification"} = \1 } 207#line 52 "copfilesv-modified" 208 abcdefg(); 209end 210 is $::{"_<copfilesv-modified"}[52], " abcdefg();\n", 211 '#line 42 "foo" in a str eval is not confused by ${"_<foo"} changing'; 212} 213