summaryrefslogtreecommitdiff
path: root/t/op/caller.t
diff options
context:
space:
mode:
authorFather Chrysostomos <sprout@cpan.org>2011-08-25 12:38:15 -0700
committerFather Chrysostomos <sprout@cpan.org>2011-08-25 12:38:15 -0700
commite1a80902e5e9ce316c7cc56f6c15b52b0c0a9144 (patch)
treea4bb12053aef53ba7217fb900fa832fbcaadc08c /t/op/caller.t
parentc931b03652afbc6f3525df91e6f1b821bf7c9fe3 (diff)
downloadperl-e1a80902e5e9ce316c7cc56f6c15b52b0c0a9144.tar.gz
[perl #93320] localising @DB::args leads to coredump
This script, from the RT ticket, crashes: #!/usr/bin/perl sub cl{ package DB; @DB::args = (); return caller(shift); } sub f{ local @DB::args; my @z = cl($_) for (1..3); } f(1,2,3); f(1,2,3); __END__ PL_dbargs is not refcounted, and it’s not set until pp_caller first tries to write to it. If that happens when @DB::args is localised, then the array will be freed on scope exit, leaving PL_dbargs pointing to a freed SV. This crash can be reproduced more simply this way: sub { package DB; ()=caller(0); undef *DB::args; ()=caller(0); }->(); So, basically, pp_caller has to re-fetch PL_dbargs from the %DB:: stash each time it sets it. It cannot rely on the cached value. (So now I’m wondering whether we even need PL_dbargs.)
Diffstat (limited to 't/op/caller.t')
-rw-r--r--t/op/caller.t11
1 files changed, 10 insertions, 1 deletions
diff --git a/t/op/caller.t b/t/op/caller.t
index d77088e611..4fcc8513f7 100644
--- a/t/op/caller.t
+++ b/t/op/caller.t
@@ -5,7 +5,7 @@ BEGIN {
chdir 't' if -d 't';
@INC = '../lib';
require './test.pl';
- plan( tests => 82 );
+ plan( tests => 83 );
}
my @c;
@@ -225,6 +225,15 @@ EOP
::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';
+
$::testing_caller = 1;
do './op/caller.pl' or die $@;