Since Scope::Upper always uses PL_curstackinfo (most often via cxstack_ix) to get information
about the current stack depth, it does not work when the call stack has been swapped for
another one, for example from within a signal handler (where si_type = PERLSI_SIGNAL).
When it inspects callers it should test for si_type == PERLSI_MAIN, and if not,
continue through si_prev.
Here's a program that can demonstrate the problem:
as is, it runs correctly, but by commenting out the "comment me" line
and uncommenting the alarm one, we fool uplevel in not executing the
die() enough levels up.
use 5.14.2;
use Scope::Upper ':all';
my $die_from_here;
sub alrm_handler {
say "in the alrm handler";
if (!defined $die_from_here) { say 'Nowhere to die from' ; return }
uplevel { die "alarm!!" } $die_from_here;
};
sub main1 {
say 'main1';
eval { main2() } or print "main2 died: $@";
}
sub main2 {
say 'main2';
$die_from_here = HERE; # so main1 should catch it
eval { main3() } or print "main3 died: $@";
}
sub main3 {
say 'main3';
eval { main4() } or print "main4 died: $@";
}
sub main4 {
say 'main4';
alrm_handler; # comment me!
#local $SIG{ALRM} = \&alrm_handler; alarm 1; sleep 2;
}
main1();
say "finished peacefully";