1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335
|
#!./perl
# Tests for caller()
BEGIN {
chdir 't' if -d 't';
@INC = '../lib';
require './test.pl';
plan( tests => 95 );
}
my @c;
BEGIN { print "# Tests with caller(0)\n"; }
@c = caller(0);
ok( (!@c), "caller(0) in main program" );
eval { @c = caller(0) };
is( $c[3], "(eval)", "subroutine name in an eval {}" );
ok( !$c[4], "hasargs false in an eval {}" );
eval q{ @c = caller(0) };
is( $c[3], "(eval)", "subroutine name in an eval ''" );
ok( !$c[4], "hasargs false in an eval ''" );
sub { @c = caller(0) } -> ();
is( $c[3], "main::__ANON__", "anonymous subroutine name" );
ok( $c[4], "hasargs true with anon sub" );
# Bug 20020517.003, used to dump core
sub foo { @c = caller(0) }
my $fooref = delete $::{foo};
$fooref -> ();
is( $c[3], "main::__ANON__", "deleted subroutine name" );
ok( $c[4], "hasargs true with deleted sub" );
BEGIN {
require strict;
is +(caller 0)[1], __FILE__,
"[perl #68712] filenames after require in a BEGIN block"
}
print "# Tests with caller(1)\n";
sub f { @c = caller(1) }
sub callf { f(); }
callf();
is( $c[3], "main::callf", "subroutine name" );
ok( $c[4], "hasargs true with callf()" );
&callf;
ok( !$c[4], "hasargs false with &callf" );
eval { f() };
is( $c[3], "(eval)", "subroutine name in an eval {}" );
ok( !$c[4], "hasargs false in an eval {}" );
eval q{ f() };
is( $c[3], "(eval)", "subroutine name in an eval ''" );
ok( !$c[4], "hasargs false in an eval ''" );
sub { f() } -> ();
is( $c[3], "main::__ANON__", "anonymous subroutine name" );
ok( $c[4], "hasargs true with anon sub" );
sub foo2 { f() }
my $fooref2 = delete $::{foo2};
$fooref2 -> ();
is( $c[3], "main::__ANON__", "deleted subroutine name" );
ok( $c[4], "hasargs true with deleted sub" );
# See if caller() returns the correct warning mask
sub show_bits
{
my $in = shift;
my $out = '';
foreach (unpack('W*', $in)) {
$out .= sprintf('\x%02x', $_);
}
return $out;
}
sub check_bits
{
local $Level = $Level + 2;
my ($got, $exp, $desc) = @_;
if (! ok($got eq $exp, $desc)) {
diag(' got: ' . show_bits($got));
diag('expected: ' . show_bits($exp));
}
}
sub testwarn {
my $w = shift;
my $id = shift;
check_bits( (caller(0))[9], $w, "warnings match caller ($id)");
}
{
no warnings;
# Build the warnings mask dynamically
my ($default, $registered);
BEGIN {
for my $i (0..$warnings::LAST_BIT/2 - 1) {
vec($default, $i, 2) = 1;
}
$registered = $default;
vec($registered, $warnings::LAST_BIT/2, 2) = 1;
}
# The repetition number must be set to the value of $BYTES in
# lib/warnings.pm
BEGIN { check_bits( ${^WARNING_BITS}, "\0" x 15, 'all bits off via "no warnings"' ) }
testwarn("\0" x 15, 'no bits');
use warnings;
BEGIN { check_bits( ${^WARNING_BITS}, $default,
'default bits on via "use warnings"' ); }
BEGIN { testwarn($default, 'all'); }
# run-time :
# the warning mask has been extended by warnings::register
testwarn($registered, 'ahead of w::r');
use warnings::register;
BEGIN { check_bits( ${^WARNING_BITS}, $registered,
'warning bits on via "use warnings::register"' ) }
testwarn($registered, 'following w::r');
}
# The next two cases test for a bug where caller ignored evals if
# the DB::sub glob existed but &DB::sub did not (for example, if
# $^P had been set but no debugger has been loaded). The tests
# thus assume that there is no &DB::sub: if there is one, they
# should both pass no matter whether or not this bug has been
# fixed.
my $debugger_test = q<
my @stackinfo = caller(0);
return scalar @stackinfo;
>;
sub pb { return (caller(0))[3] }
my $i = eval $debugger_test;
is( $i, 11, "do not skip over eval (and caller returns 10 elements)" );
is( eval 'pb()', 'main::pb', "actually return the right function name" );
my $saved_perldb = $^P;
$^P = 16;
$^P = $saved_perldb;
$i = eval $debugger_test;
is( $i, 11, 'do not skip over eval even if $^P had been on at some point' );
is( eval 'pb()', 'main::pb', 'actually return the right function name even if $^P had been on at some point' );
print "# caller can now return the compile time state of %^H\n";
sub hint_exists {
my $key = shift;
my $level = shift;
my @results = caller($level||0);
exists $results[10]->{$key};
}
sub hint_fetch {
my $key = shift;
my $level = shift;
my @results = caller($level||0);
$results[10]->{$key};
}
{
my $tmpfile = tempfile();
open my $fh, '>', $tmpfile or die "open $tmpfile: $!";
print $fh <<'EOP';
#!perl -wl
use strict;
{
package KAZASH ;
sub DESTROY {
print "DESTROY";
}
}
@DB::args = bless [], 'KAZASH';
print $^P;
print scalar @DB::args;
{
local $^P = shift;
}
@DB::args = (); # At this point, the object should be freed.
print $^P;
print scalar @DB::args;
# It shouldn't leak.
EOP
close $fh;
foreach (0, 1) {
my $got = runperl(progfile => $tmpfile, args => [$_]);
$got =~ s/\s+/ /gs;
like($got, qr/\s*0 1 DESTROY 0 0\s*/,
"\@DB::args doesn't leak with \$^P = $_");
}
}
# This also used to leak [perl #97010]:
{
my $gone;
sub fwib::DESTROY { ++$gone }
package DB;
sub { () = caller(0) }->(); # initialise PL_dbargs
@args = bless[],'fwib';
sub { () = caller(0) }->(); # clobber @args without initialisation
::is $gone, 1, 'caller does not leak @DB::args elems when AvREAL';
}
# And this crashed [perl #93320]:
sub {
package DB;
()=caller(0);
undef *DB::args;
()=caller(0);
}->();
pass 'No crash when @DB::args is freed between caller calls';
# This also crashed:
package glelp;
sub TIEARRAY { bless [] }
sub EXTEND { }
sub CLEAR { }
sub FETCH { $_[0][$_[1]] }
sub STORE { $_[0][$_[1]] = $_[2] }
package DB;
tie @args, 'glelp';
eval { sub { () = caller 0; } ->(1..3) };
::like $@, qr "^Cannot set tied \@DB::args at ",
'caller dies with tie @DB::args';
::ok tied @args, '@DB::args is still tied';
untie @args;
package main;
# [perl #113486]
fresh_perl_is <<'END', "ok\n", {},
{ package foo; sub bar { main::bar() } }
sub bar {
delete $::{"foo::"};
my $x = \($1+2);
my $y = \($1+2); # this is the one that reuses the mem addr, but
my $z = \($1+2); # try the others just in case
s/2// for $$x, $$y, $$z; # now SvOOK
$x = caller;
print "ok\n";
};
foo::bar
END
"No crash when freed stash is reused for PV with offset hack";
is eval "(caller 0)[6]", "(caller 0)[6]",
'eval text returned by caller does not include \n;';
if (1) {
is (sub { (caller)[2] }->(), __LINE__,
'[perl #115768] caller gets line numbers from nulled cops');
}
# Test it at the end of the program, too.
fresh_perl_is(<<'115768', 2, {},
if (1) {
foo();
}
sub foo { print +(caller)[2] }
115768
'[perl #115768] caller gets line numbers from nulled cops (2)');
# PL_linestr should not be modifiable
eval '"${;BEGIN{ ${\(caller 2)[6]} = *foo }}"';
pass "no assertion failure after modifying eval text via caller";
is eval "<<END;\nfoo\nEND\n(caller 0)[6]",
"<<END;\nfoo\nEND\n(caller 0)[6]",
'here-docs do not gut eval text';
is eval "s//<<END/e;\nfoo\nEND\n(caller 0)[6]",
"s//<<END/e;\nfoo\nEND\n(caller 0)[6]",
'here-docs in quote-like ops do not gut eval text';
# The bitmask should be assignable to ${^WARNING_BITS} without resulting in
# different warnings settings.
{
my $ bits = sub { (caller 0)[9] }->();
my $w;
local $SIG{__WARN__} = sub { $w++ };
eval '
use warnings;
BEGIN { ${^WARNING_BITS} = $bits }
local $^W = 1;
() = 1 + undef;
$^W = 0;
() = 1 + undef;
';
is $w, 1, 'value from (caller 0)[9] (bitmask) works in ${^WARNING_BITS}';
}
# This was fixed with commit d4d03940c58a0177, which fixed bug #78742
fresh_perl_is <<'END', "__ANON__::doof\n", {},
package foo;
BEGIN {undef %foo::}
sub doof { caller(0) }
print +(doof())[3];
END
"caller should not SEGV when the current package is undefined";
# caller should not SEGV when the eval entry has been cleared #120998
fresh_perl_is <<'END', 'main', {},
$SIG{__DIE__} = \&dbdie;
eval '/x';
sub dbdie {
@x = caller(1);
print $x[0];
}
END
"caller should not SEGV for eval '' stack frames";
$::testing_caller = 1;
do './op/caller.pl' or die $@;
|