Subject: | Can't return outside a subroutine at /usr/local/share/perl/5.10.1/DateTime/TimeZone/Local.pm |
I'm submitting this patch to workaround an apparent perl bug rather than
a bug in DateTime::TimeZone::Local.
On systems without an explicit subclass (e.g. linux), using the local
timezone in a sort block crashes perl saying "Can't return outside a
subroutine at /usr/local/share/perl/5.10.1/DateTime/TimeZone/Local.pm
line 66."
I can reproduce on Linux systems running perl v5.8.8 and v5.10.1 running
DateTime::TimeZone v0.99 and v1.23 respectively.
The trigger seems to be the eval's loading the subclass. If there isn't
a subclass, the eval fails as intended. This triggers a bug in
perl (http://www.gossamer-threads.com/lists/perl/porters/256807) where
the stack is corrupted so the return on line 66 fails. Checked it in the
perl debugger and the stack trace is indeed empty after the first eval.
Using "require" instead of "use" to load the subclass appears to fix it.
I can workaround it in my code by setting the OS to Unix before calling
sort (local $^O = "Unix";)
Test case and patch against v1.23 attached.
Subject: | local-eval-20101118.patch |
--- /usr/local/share/perl/5.10.1/DateTime/TimeZone/Local.pm 2010-10-25 16:29:48.000000000 +0100
+++ Local.pm 2010-11-18 09:51:08.000000000 +0000
@@ -49,12 +49,12 @@
local $@;
local $SIG{__DIE__};
- eval "use $subclass";
+ eval "require $subclass";
if ( my $e = $@ ) {
if ( $e =~ /locate.+$os_name/ ) {
$subclass = $class . '::' . 'Unix';
- eval "use $subclass";
+ eval "require $subclass";
my $e2 = $@;
die $e2 if $e2;
}
Subject: | time-zone.t |
#!/usr/bin/perl
use strict;
# on linux, perl v5.8.8 x86_64-linux-gnu-thread-multi
use DateTime::TimeZone::Local;
use Test::More tests => 1;
# set the OS to Linux
$^O = 'linux';
my @input = (1 .. 10 );
# DateTime::TimeZone::Local loads up OS-specific subclasses
# If there isn't an explicit subclass, it falls back to Unix
# It loads subclasses in an eval.
# There appears to be a bug in perl (http://www.gossamer-threads.com/lists/perl/porters/256807)
# where the stack is corrupted if the eval fails
# fails with:
# "Can't return outside a subroutine at /usr/local/share/perl/5.10.1/DateTime/TimeZone/Local.pm line 66."
my (@output) = sort {
DateTime::TimeZone::Local->TimeZone();
$a <=> $b
} @input;
is_deeply(\@output, \@input);