Subject: | Perl crash when using Future::AsyncAwait |
Hello again,
I'm finally trying out Future::AsyncAwait and I really like the primitives it supplies! However, I think I encountered a bug somewhere in Future::AsyncAwait, since Perl crashes for the attached program, while the (trivially modified) non-async/await version passes as expected.
I have tested the program on Windows+Perl 5.26 and the Debian stock Perl (5.24), with the latest IO::Async, Future and Future::AsyncAwait and get different but consistent indicators of memory corruption in both cases. I've also tested the program with AnyEvent::Future and IO::Async but have only attached the IO::Async version, since I assume that you are more familiar with that and I don't think that the different backends are relevant.
I suspect some problem in the parsing or stack/pad handling, since using a global variable instead of a lexical variable in global scope makes a difference in behaviour (but not final outcome, i.e. crash). But my debugging-fu is too weak to actually pinpoint where the problem would be.
If you need any assistance in debugging, or more/different test runs, please tell me!
Thanks for bringing the future to Perl,
-max
Subject: | await-lexical.t |
#!perl -w
use strict;
use Test::More tests => 2;
use Future;
use Future::AsyncAwait;
# We want to use/force the IO::Async backend for now
# The same crash happens with Future::AnyEvent
use IO::Async::Future;
use IO::Async::Loop;
use Data::Dumper;
# This one won't work with a lexical variable(?!)
# Most likely a bug in Future::AsyncAwait stack handling/pad handling?!
my $limiter = 1;
# This works/crashes differently:
#our $limiter = 1;
my $loop = IO::Async::Loop->new;
my @results;
async sub limit_test {
my( $j ) = @_;
warn "No more limiter for $j" unless $limiter;
push @results, [$j, $limiter];
my $future = $loop->new_future;
$loop->watch_time( after => 3, code => sub { $future->done( "Done" ) } );
await $future; # AnyEvent::Future->new_delay(after => 1);
Future->done( $j );
};
Future->wait_all(
limit_test( 1 ),
limit_test( 2 ),
)->get();
is 0+@results, 2, "We got two calls";
is_deeply \@results, [ [1,1], [2,1] ], 'The $limiter variable kept its value';